Статьи

Почему Nexus, а не Artifactory? Соответствие стандартам, безопасности и качеству

Мы (Sonatype) недавно получили несколько запросов на поддержку от компании, которая переключается с Artifactory на Nexus. На этапе оценки и проектирования системы они настраивали Nexus для прокси-сервера своего внутреннего экземпляра Artifactory и где возникали некоторые проблемы с интеграцией. Наш вспомогательный персонал немного покопался, и результаты оказались неожиданными. 

Прежде чем углубляться в детали, я просто хочу сказать, что я не испытываю особого удовлетворения, указывая на проблемы в Artifactory, и не буду утверждать, что Nexus также совершенен, но мы уделяем очень подробное внимание таким ключевым областям, как стабильность, производительность и, самое главное, совместимость. Честно говоря, это не то, на что я хотел бы тратить свое время, но я прочитал так много гипербол от JFrog о том, как настройка mirrorOr «ленива и грязна», и так много глупых разговоров о том, что Sonatype просто «все» говорить «, что я думаю, что пришло время начать отвечать на критику.

Переписывание POM и соответствие лицензии

Заказчик настраивал свою систему для использования поддержки Procurement в Nexus, и он задыхался при проверке подписи множества артефактов, исходящих из его устаревшей системы Artifactory. В результате расследования мы обнаружили, что Artifactory полностью переписывает файлы POM, предположительно, как часть новой функции для удаления записей из репозитория. Чтобы убедиться в этом, сравните результаты этих двух URL:

http://repo1.maven.org/maven2/org/apache/maven/apache-maven/2.0.10/apache-maven-2.0.10.pom

и

http : //repo.jfrog.org/artifactory/libs-releases/org/apache/maven/apache-maven/2.0.10/apache-maven-2.0.10.pom

Прежде всего обратите внимание, что в этом pom нет элемента репозитория, поэтому нет необходимости изменять файл вообще. Более детальная оценка покажет, что этот pom «прокси» Artifactory полностью переписан, удалив все комментарии и переупорядоченные элементы. Лично я не думаю, что это хорошая идея, чтобы копаться с файлами, передаваемыми через прокси, но это, вероятно, хорошо, если все синтаксический анализ выполнен правильно. Это действительно вводит еще одно место для вещей, которые идут не так, как надо. Я имею в виду, что комментарии не так важны, не так ли? Что ж, если вы заботитесь о лицензировании с открытым исходным кодом, они есть. Посмотрите на это POM из Центральной:

 <!--

Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>maven</artifactId>
<groupId>org.apache.maven</groupId>
<version>2.0.10</version>
</parent>

Теперь взгляните на первые несколько строк из того же POM из открытого репозитория JFrog:

<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
...

Лицензионный заголовок файла был полностью удален. Я был уверен, что это может быть нарушением самой лицензии, поэтому я проверил лицензию Apache по адресу http://www.apache.org/licenses/LICENSE-2.0 .


4.2 Вы должны заставить любые измененные файлы иметь заметные уведомления о том, что Вы изменили файлы;
и

4.3 Вы должны сохранить в форме «Источник» любых распространяемых вами Производных работ все уведомления об авторских правах, патентах, товарных знаках и атрибуции из формы «Произведения», за исключением уведомлений, которые не относятся к какой-либо части Производных произведений.

Я не юрист, но я понимаю, что это означает, что если у вас включена эта опция и вы распространяете эти POM среди всех остальных, вы можете нарушать лицензию на использование прокси-артефактов. Этот пример относится к лицензии ASL, довольно либеральной лицензии, но, как активный участник ASF, я могу вам сказать, что организация очень серьезно относится к вопросам лицензирования. Дело в том, что заголовки с любого pom будут сброшены, и большинство лицензий там, вероятно, осуждают это. Некоторые из вас собираются игнорировать это как незначительную проблему, может быть, это так, но это такая незначительная проблема, которая заставит отдел соблюдения правовых норм прийти в бешенство. Но удаление лицензий с POM на самом деле не было главной проблемой, я просто наткнулся на то, чтобы найти решение проблемы с подписями PGP.

Перезапись POM и подписи PGP

Оставив в стороне проблему с лицензией, давайте вернемся к проблеме закупок, о которой сообщалось. Теперь попробуйте получить файл подписи для этого артефакта, чтобы вы могли проверить, что он не был подделан. В файле asc должна быть подпись GPG, созданная с помощью общедоступного ключа. Нажмите на следующий URL в центре, чтобы увидеть пример.

http://repo1.maven.org/maven2/org/apache/maven/apache-maven/2.0.9/apache-maven-2.0.9.pom.asc

Хорошо, пока? (Это моя подпись) Вот суть проблемы. Нажмите на тот же артефакт в прокси-сервере Atifactory, расположенном ниже:

http://repo.jfrog.org/artifactory/libs-releases/org/apache/maven/apache-maven/2.0.9/apache-maven-2.0.9 .pom.asc

На момент написания я получаю:

HTTP Status 500 -


type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.IllegalArgumentException: Checksum type not found for path org/apache/maven/apache-maven/2.0.9/apache-maven-2.0.9.pom.asc org.artifactory.engine.DownloadServiceImpl.respondForChecksumRequest(DownloadServiceImpl.java:214) org.artifactory.engine.DownloadServiceImpl.respond(DownloadServiceImpl.java:176) org.artifactory.engine.DownloadServiceImpl.process(DownloadServiceImpl.java:122) sun.reflect.GeneratedMethodAccessor93.invoke(Unknown Source) )

Моя действительная подпись, которая существует в Central, больше не может быть получена через прокси. Я не сомневаюсь, что они исправят аварию. Однако: проблема все еще остается, как вы можете иметь сеть доверия, которая ссылается на первоначального разработчика, когда прокси в середине переписывают артефакт и удаляют (или восстанавливают) подпись pgp? Даже если вы доверяете своему экземпляру, как вы можете проверить правильность подписи для входящего артефакта перед его перезаписью? Что если вы проксируете от кого-то другого, кто использует Artifactory, они взломали вас или просто невольно взломали сеть доверия?

Если вы загружаете вещи из Интернета, проверка подписей PGP — это не то, о чем вы должны думать , а то, что вам нужноделать. Это единственный способ гарантировать, что артефакты из удаленного репозитория являются надежными, и Sonatype потратил много времени на то, чтобы артефакты, добавленные в репозитории Central Maven, репозитории Apache и репозитории Codehaus, сопровождались допустимые ключи PGP, которые находятся на сервере открытых ключей. В дополнение к этому, ASF очень серьезно относится к идее создания сети доверия. Вы не должны подписывать релиз ASF, если ваш ключ не подписан кем-то в сети доверия ASF во время события подписания ключа (ключи PGP лучше всего подписывать, только если вы можете проверить чью-либо подпись лицом к лицу). Кажется, стыдно выбрасывать всю эту работу, просто чтобы «очистить» POM от элементов репозитория.

Опять же, JFrog публично написал, что единственная причина, по которой это переписывание POM необходимо, заключается в том, что они думают, что Maven не работает. Но их исправление отбрасывает сеть доверия, которая позволяет проверять содержимое хранилища с использованием оригинальных ключей PGP от разработчиков проектов. Мы рассматривали подобные изменения в прошлом, но поскольку мы несем ответственность за поддержание некоторых из этих исходных репозиториев, мы вынуждены думать о последствиях наших изменений для сообщества. Создание менеджера репозитория, который просто «выбрасывает» подписи PGP для POM, кажется мне безответственным, когда мы начинаем выполнять сложную работу по обеспечению того, чтобы новые артефакты, добавленные к центральному, имели подписи PGP.

Артефактор производит нестандартные индексы

У нас также было несколько сообщений о странном поведении индексации. Первоначальный индексный формат представлял собой двоичный файл Lucene 2.3, заархивированный в удобный архив. Это создало проблему, потому что если вы хотите перейти на более новую версию Lucene, вы больше не можете создавать более старую отформатированную версию. Более новые версии Lucene не могут генерировать обратно совместимые двоичные индексные файлы. Поскольку сообществу необходимо было поддерживать обратную совместимость для всех старых клиентов, стандартный индекс, создаваемый основными общедоступными репозиториями, теперь представляет собой новый двоичный формат, полностью отделенный от Lucene. Вся эта работа была проделана в проекте Nexus Indexer, отдельном проекте с открытым исходным кодом, который был доступен в рамках Eclipse Public License (EPL) и который уже интегрирован во все менеджеры репозитория. Этот новый формат .gz. В дополнение к нейтральному формату,он также поддерживает инкрементные индексы. Индексы, произведенные Artifactory, используют застежку-молнию старого стиля, но с более новой версией Lucene. Это означает, что он нестандартный и не может использоваться всеми плагинами IDE или другими индексными клиентами.

Другая проблема, которую мы обнаружили, заключалась в том, что индексы, представленные «виртуальными» репозиториями (эквивалентно групповым индексам Nexus), обслуживают только индекс последнего репозитория в списке. Это означает, что на предприятии вы не можете получить индекс, содержащий все доступные вам артефакты, как внутренние, так и внешние. Хотя вы, безусловно, можете использовать интерфейс поиска Artifactory, обещание индекса репозитория заключается в том, что такие инструменты, как m2eclipse и другие плагины Maven, могут использовать этот индекс для быстрого поиска артефактов, которые содержат определенные классы, или быстрого создания списка версий для определенного artifactId.

Поскольку всем менеджерам хранилищ важно создавать совместимые индексы хранилищ, мы решили пожертвоватькод индексатора Nexus для Apache Software Foundation. Индекс Nexus является стандартным форматом для репозитория Maven, он интегрирован в Archiva, Nexus и Artifactory, и имеет смысл просто перенести код, создавший этот индекс, в открытое прозрачное сообщество, такое как Apache. Это улучшит видимость кода Nexus Indexer для людей, которые активно участвуют в сообществе Maven.

Artifactory Breaks Wagon

Maven и Maven Ant Tasks используют то, что называется Wagon, для передачи файлов в хранилище и из него. Это «транспортная абстракция, которая используется в коде Maven для обработки артефактов и хранилищ», и у нее есть провайдеры для SCP, HTTP, FTP и файлов. Каждый раз, когда Maven видит URL, компонент Maven Wagon обрабатывает передачу. Я не буду вдаваться в подробности этого компонента, но одна из вещей, которые должен сделать менеджер репозитория, — предоставить какой-то список файлов для каталога. У всех других протоколов с провайдерами Wagon есть какой-то способ получить список каталогов. Базовое подмножество HTTP, поддерживаемое всеми веб-серверами, не имеет этой команды, поэтому HTTP wagon использует репозиторий, возвращающий список ссылок на содержимое папки.

Вместо того, чтобы возвращать такой список содержимого папки, Artifactory пытается перенаправить клиента в пользовательский интерфейс. Он не возвращает список файлов, и все в Maven, которое полагается на способность Wagon получить список файлов, потерпит неудачу. Другими словами, все, что есть в Maven или любом плагине Maven, использующем интерфейс wagon.getFileList (), сломается, когда вы используете Artifactory. Вы можете видеть это здесь:

[INFO] Scanning remote file system: http://repo1.maven.org/maven2/org/apache/mav
en/apache-maven/2.0.10/ ...
[INFO] apache-maven-2.0.10-bin.tar.bz2
[INFO] apache-maven-2.0.10-bin.tar.bz2.asc
[INFO] apache-maven-2.0.10-bin.tar.bz2.asc.md5
[INFO] apache-maven-2.0.10-bin.tar.bz2.asc.sha1
[INFO] apache-maven-2.0.10-bin.tar.bz2.md5
[INFO] apache-maven-2.0.10-bin.tar.bz2.sha1
[INFO] apache-maven-2.0.10-bin.tar.gz
[INFO] apache-maven-2.0.10-bin.tar.gz.asc
[INFO] apache-maven-2.0.10-bin.tar.gz.asc.md5
[INFO] apache-maven-2.0.10-bin.tar.gz.asc.sha1
[INFO] apache-maven-2.0.10-bin.tar.gz.md5
[INFO] apache-maven-2.0.10-bin.tar.gz.sha1
[INFO] apache-maven-2.0.10-bin.zip
[INFO] apache-maven-2.0.10-bin.zip.asc
[INFO] apache-maven-2.0.10-bin.zip.asc.md5
[INFO] apache-maven-2.0.10-bin.zip.asc.sha1
[INFO] apache-maven-2.0.10-bin.zip.md5
[INFO] apache-maven-2.0.10-bin.zip.sha1
[INFO] apache-maven-2.0.10-sources.jar
[INFO] apache-maven-2.0.10-sources.jar.asc
[INFO] apache-maven-2.0.10-sources.jar.asc.md5
[INFO] apache-maven-2.0.10-sources.jar.asc.sha1
[INFO] apache-maven-2.0.10-sources.jar.md5
[INFO] apache-maven-2.0.10-sources.jar.sha1
[INFO] apache-maven-2.0.10.jar
[INFO] apache-maven-2.0.10.jar.asc
[INFO] apache-maven-2.0.10.jar.asc.md5
[INFO] apache-maven-2.0.10.jar.asc.sha1
[INFO] apache-maven-2.0.10.jar.md5
[INFO] apache-maven-2.0.10.jar.sha1
[INFO] apache-maven-2.0.10.pom
[INFO] apache-maven-2.0.10.pom.asc
[INFO] apache-maven-2.0.10.pom.asc.md5
[INFO] apache-maven-2.0.10.pom.asc.sha1
[INFO] apache-maven-2.0.10.pom.md5
[INFO] apache-maven-2.0.10.pom.sha1
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 32 seconds
[INFO] Finished at: Mon Jan 04 17:17:11 EST 2010
[INFO] Final Memory: 8M/47M
[INFO] ------------------------------------------------------------------------

C:\svn\staging-test>mvn validate
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building staging-test
[INFO] task-segment: [validate]
[INFO] ------------------------------------------------------------------------
[INFO] [wagon:list {execution: upload-javadoc}]
[INFO] Scanning remote file system: http://repo.jfrog.org/artifactory/libs-relea
ses/org/apache/maven/apache-maven/2.0.10/ ...
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error handling resource

Embedded error: Error transferring file
Server redirected too many times (20)
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch

Резюме

В прошлый раз, когда я писал что-то об Artifactory, основатели компании вернулись и назвали меня предвзятым и не объективным. Посудите сами, я привел некоторые конкретные факты в этом посте.

Я должен сказать вам, что вещь, которая действительно поразила меня и других инженеров в Sonatype, была идея, что кто-то мог написать сообщение в блоге, говоря, что Sonatype — «все разговоры». Это просто не имеет никакого смысла, как корпорация, мы вложили ресурсы в фундаментальные технологии, которые используют наши конкуренты. Я провожу большую часть своего времени , работая над проектом Maven, останавливая отказ в обслуживании атак на Центральной, я на РМС, много того времени тратится пытается сделать Maven лучший продукт. Большая часть этой работы включает в себя беседу с нашими конкурентами о способах улучшения Maven и связанных с ними технологий. Откровенно говоря, слышать, как кто-то приходит к нам, потому что мы «все говорим», оскорбительно, учитывая количество часов (нет, лет), которые мы вложили в это сообщество с открытым исходным кодом.