Сервер обновлений OS X — Reposado

Reposado — это набор инструментов, написанных на Python, которые воспроизводят основные функции Mac OS X Server’s Software Update Service.

Функции и возможности
Reposado, используя «curl» и веб-сервер, например Apache 2, позволяет размещать обновления программного обеспечения OS X на любом «железе» и ОС по вашему выбору…

Ограничения и зависимости
Apple’s Software Update Service делает несколько вещей. В первую очередь, реплицирует обновления программного обеспечения от Apple, загружая их на локальную машину. Во-вторых, функционирует в качестве веб-сервера, для возможности отдать эти обновления на клиентские машины. Reposado не дублирует функционал Web-сервера Apple’s Software Update Service. Вместо этого вы можете использовать любой существующий веб-сервер, который вы хотите.
Reposado использует «curl» для загрузки обновлений с серверов Apple. «curl» доступен на ОС X, в RedHat Linux и многих других ОС, включая Win32 и win64 версии. (См. http://curl.haxx.se для получения дополнительной информации)

Скопипастил здесь

Далее будет описано, как установить
Всё что будет написано ниже, 100% работает на Debian GNU/Linux 8 (jessie)
Исходные данные:
Сервер Debian GNU/Linux 8 (jessie)
имя сервера должно резолвится в сети!!!

Установить зависимости

[root@updsrv /] # # apt-get install git ntp apache2-mpm-itk
...

Установить reposado из git

[root@updsrv /tmp] # cd /tmp
[root@updsrv /tmp] # git clone git://github.com/wdas/reposado.git
Cloning into 'reposado'...
remote: Counting objects: 475, done.
remote: Total 475 (delta 0), reused 0 (delta 0), pack-reused 475
Receiving objects: 100% (475/475), 145.56 KiB | 225.00 KiB/s, done.
Resolving deltas: 100% (235/235), done.
Checking connectivity... done.
[root@updsrv /tmp] # mv reposado /usr/local/sbin

Хранилище

По-умолчанию обновления сохраняются в /var/local/reposado/. Необходимо не менее 120ГБ свободного места.
mkdir -p /var/local/reposado/{html,metadata}

Настройки веб-сервера

При условии, что это единственный веб-сервис, предоставляемый данным сервером, редактируем /etc/apache2/sites-enabled/000-default.conf
было
[root@updsrv /tmp] # cat /etc/apache2/sites-enabled/000-default.conf |egrep -v '^$|^\s*#'

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

стало
[root@updsrv /tmp] # cat /etc/apache2/sites-enabled/000-default.conf |egrep -v '^$|^\s*#'

        ServerAdmin webmaster@localhost
        DocumentRoot /var/local/reposado/html
        
                Options FollowSymLinks Indexes
                AllowOverride All
                Require all granted
        
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

Удобства

Забегая вперёд…, при настройке клиентов, нужно будет указать ссылку на локальное хранилище в формате
http://ВВВ.ИМЯ.СЕРВЕРА/content/catalogs/index_.sucatalog
Например для OS X 10.9.X Maverick:
http://ВВВ.ИМЯ.СЕРВЕРА/content/catalogs/others/index-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog
а для OS X 10.8.x Mountain Lion:
http://ВВВ.ИМЯ.СЕРВЕРА/content/catalogs/others/index-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog
и так «каждому своё». Но! этого можно избежать.
Используем модуль апача rewrite и файл «.htaccess»
Включаем модуль:
[root@updsrv /tmp] # a2enmod rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
  service apache2 restart
Создаём файл .htaccess
cat > /var/local/reposado/html/.htaccess <<EOF
RewriteEngine On
Options FollowSymLinks
RewriteBase  /
RewriteCond %{HTTP_USER_AGENT} Darwin/8
RewriteRule ^index(.*)\.sucatalog$ content/catalogs/index$1.sucatalog [L]
RewriteCond %{HTTP_USER_AGENT} Darwin/9
RewriteRule ^index(.*)\.sucatalog$ content/catalogs/others/index-leopard.merged-1$1.sucatalog [L]
RewriteCond %{HTTP_USER_AGENT} Darwin/10
RewriteRule ^index(.*)\.sucatalog$ content/catalogs/others/index-leopard-snowleopard.merged-1$1.sucatalog [L]
RewriteCond %{HTTP_USER_AGENT} Darwin/11
RewriteRule ^index(.*)\.sucatalog$ content/catalogs/others/index-lion-snowleopard-leopard.merged-1$1.sucatalog [L]
RewriteCond %{HTTP_USER_AGENT} Darwin/12
RewriteRule ^index(.*)\.sucatalog$ content/catalogs/others/index-mountainlion-lion-snowleopard-leopard.merged-1$1.sucatalog [L]
RewriteCond %{HTTP_USER_AGENT} Darwin/13
RewriteRule ^index(.*)\.sucatalog$ content/catalogs/others/index-10.9-mountainlion-lion-snowleopard-leopard.merged-1$1.sucatalog [L]
RewriteCond %{HTTP_USER_AGENT} Darwin/14
RewriteRule ^index(.*)\.sucatalog$ content/catalogs/others/index-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1$1.sucatalog [L]
RewriteCond %{HTTP_USER_AGENT} Darwin/15
RewriteRule ^index(.*)\.sucatalog$ content/catalogs/others/index-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1$1.sucatalog [L]
EOF 
Перезапускаем веб-сервер
[root@updsrv /tmp] # service apache2 restart
Проверяем «удобства»
ВВВ.ИМЯ.СЕРВЕРА=updsrv.mydrafts.local
[root@updsrv ~] # curl --user-agent "Darwin/10.4.0" http://updsrv.mydrafts.local/index_testing.sucatalog > /tmp/testing
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   353  100   353    0     0  29917      0 --:--:-- --:--:-- --:--:-- 32090
[root@updsrv ~] # grep "not found" /tmp/testing
The requested URL /content/catalogs/others/index-leopard-snowleopard.merged-1.sucatalog was not found on this server.

[root@updsrv ~] # curl --user-agent "Darwin/11.8.0" http://updsrv.mydrafts.local/index_testing.sucatalog > /tmp/testing
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   358  100   358    0     0  31566      0 --:--:-- --:--:-- --:--:-- 29833
[root@updsrv ~] # grep "not found" /tmp/testing
The requested URL /content/catalogs/others/index-lion-snowleopard-leopard.merged-1.sucatalog was not found on this server.
Пока в хранилище пусто, получаем соответствующую страничку, но из содержимого видно, что реврайт сработал

Конфигурация Reposado

[root@updsrv ~] # cd /usr/local/sbin/reposado/code/
[root@updsrv /usr/local/sbin/reposado/code] # ./repoutil --configure
Filesystem path to store replicated catalogs and updates [None]: /var/local/reposado/html/
Filesystem path to store Reposado metadata [None]: /var/local/reposado/metadata/
Base URL for your local Software Update Service
(Example: http://su.your.org -- leave empty if you are not replicating updates) [None]: http://updsrv.mydrafts.local

Запуск Reposado

Запуск будет осуществляться ежедневно, в час ночи
[root@updsrv /usr/local/sbin/reposado/code] # crontab -e
# Reposado
00      01      *       *       *       /usr/local/sbin/reposado/code/repo_sync
Запустить «вручную» загрузку обновлений, можно командой
/usr/local/sbin/reposado/code/repo_sync
Но прежде стоит обратить внимание на файл конфигурации, который находится по адресу:
/usr/local/sbin/reposado/code/preferences.plist
в частности на дополнительные возможности, которые невозможно изменить с помощью repoutil —configure
Итак,

Дополнительные ключи:

  • AdditionalCurlOptions
  • Настройки прокси для curl
    <key>AdditionalCurlOptions</key>
        <array>
            <string>proxy = "web-proxy.yourcompany.com:8080"</string>
        </array>
    Дополнительные настройки смотреть в документации к curl

  • AppleCatalogURLs
  • Массив строк для репликации с Apple. Если не установить, то по умолчанию имеет значение:
        <key>AppleCatalogURLs</key>
        <array>
            <string>http://swscan.apple.com/content/catalogs/index.sucatalog</string>
            <string>http://swscan.apple.com/content/catalogs/index-1.sucatalog</string>
            <string>http://swscan.apple.com/content/catalogs/others/index-leopard.merged-1.sucatalog</string>
            <string>http://swscan.apple.com/content/catalogs/others/index-leopard-snowleopard.merged-1.sucatalog</string>
            <string>http://swscan.apple.com/content/catalogs/others/index-lion-snowleopard-leopard.merged-1.sucatalog</string>
            <string>http://swscan.apple.com/content/catalogs/others/index-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog</string>
            <string>https://swscan.apple.com/content/catalogs/others/index-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog</string>
            <string>https://swscan.apple.com/content/catalogs/others/index-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog</string>
            <string>https://swscan.apple.com/content/catalogs/others/index-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog</string>
        </array>
    
    Список ссылок, актуален на ноябрь 2015.
    Следует убрать лишнее

  • PreferredLocalizations
  • Список предпочтительных языков локализации для описания обновлений. По умолчанию:
        <key>PreferredLocalizations</key>
        <array>
            <string>English</string>
            <string>en</string>
        </array>
    
  • CurlPath
  • Путь к curl. По умолчанию:
        <key>CurlPath</key>
        <string>/usr/bin/curl</string>
    
  • RepoSyncLogFile
  • repo_sync выводит результат своей деятельности, на стандартное устройство вывода. С помощью этого параметра можно указать путь к лог-файлу. Например:
        <key>RepoSyncLogFile</key>
        <string>/var/log/reposado_sync.log</string>
    
    Если включён лог, то неплохо бы добавить ротацию:
    # cat /etc/logrotate.d/reposado
    /var/log/reposado_sync.log {
    size 1M
    rotate 5
    compress
    delaycompress
    missingok
    notifempty
    }
    Пример для репликации Mac OS X 10.11 «El Capitan»
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>LocalCatalogURLBase</key>
        <string>http://updsrv.mydrafts.local</string>
        <key>UpdatesRootDir</key>
        <string>/var/local/reposado/html</string>
        <key>UpdatesMetadataDir</key>
        <string>/var/local/reposado/metadata</string>
        <key>AppleCatalogURLs</key>
          <array>
    	<string>https://swscan.apple.com/content/catalogs/others/index-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog</string>
          </array>
        <key>RepoSyncLogFile</key>
          <string>/var/log/reposado_sync.log</string>
    </dict>
    </plist>
Пожалуй с настройками всё. Можно проверить работу Reposado
[root@updsrv ~] # /usr/local/sbin/reposado/code/repo_sync &
[root@updsrv ~] # tail -f /var/log/reposado_sync.log
Nov 05 12:43:10 repo_sync run started
Nov 05 12:43:46 Downloading 4150687 bytes from https://swscan.apple.com/content/catalogs/others/index-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog...
Nov 05 12:43:48 517 products found in https://swscan.apple.com/content/catalogs/others/index-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog
Nov 05 12:43:49 Downloading 1359 bytes from http://swcdn.apple.com/content/downloads/05/56/031-02368/a0h5nceqb9kjzzs3eus566vngukimq9j86/BootCampESD.smd...
...

Управление Reposado

branch

branch — очень удобная возможность. Например, есть рабочее место, на котором установлено специфическое ПО. Обновлять такой компьютер следует с большой осторожностью, прежде желательно протестировать. Вот для этого служит branch.
Создать branch (ветвь), можно командой:
/usr/local/sbin/reposado/code/repoutil --new-branch=НАЗВАНИЕ_ВЕТКИ
Например создать release и testing:
# /usr/local/sbin/reposado/code/repoutil --new-branch=testing
# /usr/local/sbin/reposado/code/repoutil --new-branch=release
Посмотреть какие ветви есть:
# /usr/local/sbin/reposado/code/repoutil --branches
release
testing
Удалить ветвь:
# /usr/local/sbin/reposado/code/repoutil --delete-branch=testing2
Really remove branch testing? [y/n] y
Все команды можно посмотреть используя ключ −−help
Упрощает управление, веб-интерфейс Margarita

Подключение клиентов

Для того, что бы указать новый (иной) сервер обновлений установленный, нужно изменить значение по умолчанию. Для этого необходимо выполнить в командной строке клиента:
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate CatalogURL <catalog_url>
где catalog_url — URL к файлу каталога.
Например для клиента с Mountain Lion, необходимо указать:
http://updsrv.mydrafts.local/content/catalogs/others/index-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog
или в случае с использованием ветвей (branch):
http://su.yourorg.com/content/catalogs/others/index-mountainlion-lion-snowleopard-leopard.merged-1_<branchname>.sucatalog
Ранее было описано как избежать длинных и для каждой версии ОС X персональных url-строк, поэтому ссылка будет выглядеть так:
http://updsrv.mydrafts.local/index.sucatalog
или в случае с использованием ветвей (branch):
http://updsrv.mydrafts.local/index_<branchname>.sucatalog
Благодаря rewrite, на всех клиентах можно указать одинаковую ссылку:
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate CatalogURL http://updsrv.mydrafts.local/index_release.sucatalog
Вернуть значение по умолчанию, можно командой:
sudo defaults delete /Library/Preferences/com.apple.SoftwareUpdate CatalogURL


Много полезной документации есть на сайте разработчика. Рекомендую к просмотру 😉