Compare commits

...

260 Commits

Author SHA1 Message Date
root 93e7759687 TG-606
2 weeks ago
root 273e38c5ec TG-293
12 months ago
root f70f7f8e97 Fix: поправлено имя переменной cl_update_binhost_set для cl-builder
1 year ago
root d9a4dc08ec TG-210
1 year ago
root 242863e85a TG-198
1 year ago
root 5efa64ed5a TG-148
1 year ago
root 75a9f4cce9 TG-154
1 year ago
root 4aaab34ac8 TG-148
1 year ago
root 7ed6fc2847 TG-125
1 year ago
root c2c6314a80 TG-125
1 year ago
root 59880c5ce3 исправление
1 year ago
root 54e3fc5881 TG-130
1 year ago
root 4426fbee48 TG-127
1 year ago
root a5b4e5fcc7 TG-127
1 year ago
root a86bd7f1ff TG-127
1 year ago
root f4dc9ce9d4 Merge branch 'master' of https://git.calculate-linux.org/calculate/calculate-utils-3-update
1 year ago
root 945c398bf7 TG-106
1 year ago
Павел Иванов 3eee4d2afd TG-108 fix type
1 year ago
root 052f9c9874 TG-70
1 year ago
root 9b04b1bca6 TG-93
1 year ago
root 48169a8f47 TG-85
1 year ago
root ac4cf20de9 TG-86
1 year ago
root 017fc09c31 TG-80 TG-50
1 year ago
root ee6aa3c018 TG-78
1 year ago
root 9faf04df67 TG-58
1 year ago
root 157c642386 TG-73
1 year ago
root 0aae4a0461 cl-update: fix: other repos sync fix
1 year ago
root 8b275377a5 TG-59
1 year ago
root b8f1789db3 feature: async binhost
1 year ago
root 5137d0f9ff изменено: pym/update/utils/cl_update.py
1 year ago
root 231512dd49 cl-update: remove inner var; fix cache logic for calculating
1 year ago
root c0e82e8a7b Fix: логика выполнения пересена в модуль действий
2 years ago
root 7644f43bd8 изменено: pym/update/update.py
2 years ago
root bbe7d914ce cl-update: Fix: detect_best_binhost logic. Add tmp solution for
2 years ago
root 5e2a3f16ca изменено: pym/update/update.py
2 years ago
root 0bca2fc5cd изменено: pym/update/update.py
2 years ago
root 9aad9102be Fix: cl-update-profile
2 years ago
root c7744229ef Fix: cl-update-profile migrate repo condition
2 years ago
root 61d86149ff calculate-utils: Fix cl-update-profile
2 years ago
root bf6b759bc2 изменено: pym/update/variables/update.py
2 years ago
root 7a01f44877 изменено: pym/update/update.py
2 years ago
root 1ee37f9c43 изменено: pym/update/variables/update.py
2 years ago
root d9f6f0f859 Добавлена обработка логикии версии 3.7.3.0 для cl-builder
2 years ago
Artur 4bb1f3184b изменено: pym/update/update.py
2 years ago
Artur 33c97c66a9 изменено: pym/update/update.py
2 years ago
root 09b21a9740 изменено: pym/update/variables/update.py
2 years ago
root eb9850069d изменено: pym/update/variables/update.py
2 years ago
root a9e5b78c64 изменено: pym/update/update.py
2 years ago
root 7ebe12260f изменено: pym/update/wsdl_update.py
2 years ago
root 061401ca2e изменено: pym/update/update.py
2 years ago
root a03581b798 изменено: pym/update/update.py
2 years ago
root c59f7b06fb изменено: pym/update/update.py
2 years ago
root 78e9deb98a изменено: pym/update/update.py
2 years ago
root 91d05b39e9 изменено: pym/update/update.py
2 years ago
root 9f69807513 изменено: pym/update/update.py
2 years ago
root 2abe2f904b изменено: pym/update/update.py
2 years ago
root f019452b97 изменено: pym/update/update.py
2 years ago
root 413c9155af изменено: pym/update/update.py
2 years ago
root 98bbebd1f6 изменено: pym/update/update.py
2 years ago
Павел Иванов 8534ea0481 Добавлена поддерка нового пути к портежам
2 years ago
Павел Иванов 3d3afa2f3a Удалено условие выбора директории портежей
2 years ago
Павел Иванов 15b833a22a Путь к портежам по умолчанию - /usr/portage
2 years ago
Павел Иванов 4d8f8bf675 Перенос /usr/portage в /var/db/repos/gentoo
2 years ago
idziubenko ec0a21e2c1 added binhost.level check
2 years ago
idziubenko 224ef40ba3 now prints "sync" instead of "update" in sync-only update
2 years ago
idziubenko 75afc8b3a1 added vanilla kernel to module rebuild
2 years ago
idziubenko 9bdb486617 feat: module rebuild now ignores non calculate sources
2 years ago
idziubenko ca364e1dbf feat: added spinner before downloading
2 years ago
idziubenko 7bfae86bcf feat: git: to https:
2 years ago
idziubenko 5535168364 set check for world updated as non-essential
2 years ago
idziubenko a68d23c18f FEAT: added check for non-calculate world update
2 years ago
idziubenko 5deecf793e fixed clear_migration_host
2 years ago
idziubenko 3843da48ef FEAT: added tag saving
2 years ago
idziubenko 94e768f5a9 FIX: fixed migration level increasing on interrupt
2 years ago
idziubenko 006597de02 fixed translation
2 years ago
idziubenko 3c1febf7cb FEAT: added --ignore-level, --force-level,
2 years ago
idziubenko 78033cb110 small translation fix
2 years ago
idziubenko 10ca94e46b fixed localization
2 years ago
idziubenko fa1f25fb93 tooltip encoding fix
2 years ago
idziubenko ccd4e8837d fixed potential error with update level
3 years ago
idziubenko 52b8ade427 updated output grammar
3 years ago
idziubenko 91dd507a21 minor fix to the way binhost_level is chosen
3 years ago
idziubenko 15b6d3b152 fixed builder-update bug
3 years ago
idziubenko 3142073819 fixed scenario when local level is higher than all binhost's
3 years ago
idziubenko 9dfc73b8a1 now if repo's .git is damaged redownloads repo, but doesn't alter folder
3 years ago
idziubenko 0bc12b3320 migration mode is now turned off when --branch is present
3 years ago
idziubenko 489ec1a7a5 fixed cl-builder-update crash when host machine doesn't have a chosen
3 years ago
idziubenko 10b5a0132d fixed builder_update using migration mode
3 years ago
idziubenko 9157e7061d fixed filling in empty update_level in calculate.env
3 years ago
idziubenko d99c45dda3 changed the way decect_best_binhost works with levels
3 years ago
idziubenko 529aa6bc74 added level restoration, general bugfixes
3 years ago
idziubenko 96874fe0ea multiple improvements to migration algo
3 years ago
idziubenko 98c4deae97 multiple improvements to migration algo
3 years ago
idziubenko 9d49a68b38 added output
3 years ago
idziubenko efe2b5bc3c changed behavior of increment_current_level
3 years ago
idziubenko 5fdb31e5c8 removed unneeded import
3 years ago
Иван Дзюбенко 2ff2810339 fixed set level
3 years ago
Иван Дзюбенко 3b79f758eb progress
3 years ago
Иван Дзюбенко 4c1f92d549 added migration host capabilities
3 years ago
idziubenko 1dd1cd46a4 preparation for migration project
3 years ago
idziubenko dbfc0a2110 fixed emerge-like output sometimes crashing
3 years ago
idziubenko 6952049842 pre update for future migration capabilities
3 years ago
idziubenko a2349f2273 ftp to https
3 years ago
idziubenko 7e4d754690 Fixed encoding bugs in update methods
3 years ago
idziubenko e6b5f2e11b fixed hashing
3 years ago
idziubenko 5ebcea46b0 imports to relative
3 years ago
idziubenko 8b356a3d22 fixed/reverted regex
3 years ago
idziubenko 1f2b817d6e list compr, general improvements
3 years ago
idziubenko 0826021939 Merge branch 'master' of git.calculate-linux.org:calculate/calculate-utils-3-update
3 years ago
idziubenko 10922f61c6 Py3 changes
3 years ago
Хирецкий Михаил 5596090d22 Setup fix
3 years ago
idziubenko 659f1d1920 i
3 years ago
Хирецкий Михаил beed790b61 Исправлена проверка обновления
3 years ago
Хирецкий Михаил 2451599fdf Добавлено обновление информации для domain-fastlogin
3 years ago
Хирецкий Михаил fc0315cd7d Исправлен сброс маркера наличия обновлений
3 years ago
Хирецкий Михаил c131228cbc Отключено выполнение обновления если не было изменений в репозиториях или /etc/portage
3 years ago
Хирецкий Михаил 3de843415e Добавлено изменение сборочных зависимостей бинарных пакетов в зависимости от bdeps
4 years ago
Хирецкий Михаил a08838f21d Добавлен параметр --dynamic-deps, при вызове depclean
4 years ago
Хирецкий Михаил 4002685a22 Добавлено создание previous.eix
4 years ago
Хирецкий Михаил 7fd17fd332 Исправлено определение запущенного emerge
4 years ago
Хирецкий Михаил 62dd0d255b Отказ от ветки master64
4 years ago
Хирецкий Михаил e4ed00c052 Использование master64 только для calculate,distros,gentoo
4 years ago
Хирецкий Михаил 9dee71ea21 Переход на ветку master64
4 years ago
Хирецкий Михаил 79bc71f3b6 Исправлена проверка запущенного emerge
4 years ago
Хирецкий Михаил 30e4e3e36d Опция --skip-revdep-rebuild заменена на --revdep-rebuild
4 years ago
Хирецкий Михаил f6bfde8c7e calculate.conf zz-calculate.conf
5 years ago
Хирецкий Михаил 8cdddda360 Переход с Layman на repos.conf
5 years ago
Хирецкий Михаил f204e530e8 Исрпавлено определение пакета текущего загруженного ядра
5 years ago
Хирецкий Михаил 3ece80cac4 Изменено назначение with-bdeps
5 years ago
Хирецкий Михаил 661e8c868e Исправлена ошибка кодировок
5 years ago
Хирецкий Михаил ba91aa0397 Изменёно значение --with-bdeps на y для depclean
5 years ago
Хирецкий Михаил a2243c79d7 Использование параметра with-bdeps только для depclean
5 years ago
Хирецкий Михаил 81b3b9535f Добавлено переименование custom.{short} файлов при переключении профиля
5 years ago
Хирецкий Михаил 84446e44bc Изменена переменная ac_update_sync
6 years ago
Хирецкий Михаил a7bb8b6349 Исравлено удаление устаревших пакетов
6 years ago
Хирецкий Михаил d95aa814d4 Изменён порядок провреки base binhost
6 years ago
Хирецкий Михаил d275ed169a Исправлен двойной вывод сообщения о том, что сервер не найден
6 years ago
Хирецкий Михаил 13cd521646 Исправлена фраза для перевода
6 years ago
Хирецкий Михаил 5e21141676 Обновлены фразы
6 years ago
Хирецкий Михаил 3986bf1b9b Исправлена настройка выбранного зеркала
6 years ago
Хирецкий Михаил 5a20e18d5e Исправлен вызов update_layman
6 years ago
Хирецкий Михаил c28b889044 Исправлено создание директории для временного каталога GPG
6 years ago
root 0dc306541f Переписан проверка подписи Packages
6 years ago
Хирецкий Михаил c859c815f3 Добавлена проверка подписи Packages
6 years ago
Хирецкий Михаил 1614dd4eea Добавлено обновление конфигурационных файлов при сканировании серверов обновлений
6 years ago
Хирецкий Михаил 6f46c24213 Изменены права на закрытые репозитории
7 years ago
Хирецкий Михаил 321f616059 Исправлена ошибка импорта
7 years ago
Хирецкий Михаил 9f916977cf Изменены права на закрытые репозитории
7 years ago
Хирецкий Михаил 9453f0196b Исправлено выполнение шаблонов при переключении профилей
7 years ago
Хирецкий Михаил 78161512fb Добавлена поддержка закрытых репозиториев
7 years ago
Хирецкий Михаил 000b720e7d Исправлено определение with-bdeps
7 years ago
Хирецкий Михаил 1e0187472f Исправлен вызов emerge
7 years ago
Хирецкий Михаил 439b9dd1ee Добавлены переменные для базового бинхоста. Расширены возможности вызова emerge.
7 years ago
Хирецкий Михаил 572ab1de99 Изменена синхронизация репозиториев
7 years ago
Хирецкий Михаил 53669b7f71 Исправлен вывод описания пакетов
7 years ago
Хирецкий Михаил 84e2721236 Изменены права на запуск методов
7 years ago
Хирецкий Михаил 794c480f77 Удален вывод версии в полном названии дистрибутива
7 years ago
Хирецкий Михаил 1168020f6d Вызов depclean при смене параметра --with-bdeps
7 years ago
Хирецкий Михаил cfed8845d5 Исправлены описания переменных
7 years ago
Хирецкий Михаил 20695d8513 Добавлен параметр --with-bdeps для возможности задействовать
7 years ago
Хирецкий Михаил 44a1cd2ec0 Исправлено выполнение команды через CommandExecutor
7 years ago
Хирецкий Михаил 75868e2454 Исправлено вычисление переменных на "сломаных" профилях
7 years ago
Хирецкий Михаил 9084ad5d5c Исправлено выполнение только синхронизации репозиториев
7 years ago
Хирецкий Михаил e3b204f335 Исправлен скрипт-обёртка для синхронизации layman`ом
7 years ago
Хирецкий Михаил 4deee242ee Исправлены Profile переменные
7 years ago
Хирецкий Михаил cc68cd25b5 Исправлена проверка обновления
7 years ago
Хирецкий Михаил 0822bf5fee Добавлена дополнительная проверка необходимости запуска emerge @preserved-rebuild
7 years ago
Хирецкий Михаил c03f98ddd0 Исправлено скачивание Packages.xz для небинарных систем
7 years ago
Хирецкий Михаил 45e124476a Исправлен вызов исправления настроек системы (при использовании --merge-world, rebuild-world)
7 years ago
Хирецкий Михаил 8d38cfe0c0 Изменён порядок репозиториев в сообщение update eix
7 years ago
Хирецкий Михаил d89445dd5c Изменён поряток выполнения emerge -uDN world
7 years ago
Хирецкий Михаил eca0cabfaf Отключено принудительное использование --with-bdeps для вычисления зависимостей
7 years ago
Хирецкий Михаил f60b09185d Исправлна попытка скачивать Packages если binhost пуст
7 years ago
Хирецкий Михаил d26c91369e Добавлено скачивание Packages если он отсутствует или у него не тот TTL
7 years ago
Хирецкий Михаил 2fbafa7f68 Множественные изменения
7 years ago
Хирецкий Михаил 9358b1a4a5 Добавлена возможность изменения номеров установленных пакетов
7 years ago
Хирецкий Михаил 3501cbac2d Добавлена новая задача поиск автозависимостей
7 years ago
Хирецкий Михаил 7ff158264e English update
8 years ago
Хирецкий Михаил 5dab34aa14 English update
8 years ago
Хирецкий Михаил 8a1456c182 Переименована ini.evn/[update] -> [system]
8 years ago
Хирецкий Михаил e832e2348b Изменён порядок репозиториев в сообщение update eix cache
8 years ago
Хирецкий Михаил 193736b850 Исправлен вывод списка обновляемых пакетов
8 years ago
Хирецкий Михаил 13279e6107 Изменён признак определения наличия обновлений: через файл /var/lib
8 years ago
Хирецкий Михаил e7e6acef3c Обновлены иконки
8 years ago
Хирецкий Михаил 6b90d029d7 Удалён вызов python-updater
8 years ago
Хирецкий Михаил d81fc4b781 Исправлена смена профиля
8 years ago
Хирецкий Михаил be07c37b14 Исправлено преключение профиля
8 years ago
Хирецкий Михаил 3594859663 Исправлено вычисление переменной вне действия
8 years ago
Хирецкий Михаил d8e25f5185 Исправлено переключение профилей
8 years ago
Хирецкий Михаил 678735dae2 Скрыта ошибка при синхронизации репозитория, если указанный каталог
8 years ago
Хирецкий Михаил 92af9f18bc Исправлен путь по умолчанию для репозиториев git.calculate.ru -> github.com
8 years ago
Хирецкий Михаил 04b42ba821 Исправлен вывод ошибки о недоступности профиля
8 years ago
Хирецкий Михаил bdbab3c071 Обновлёно отображение названий репозиториев
8 years ago
Хирецкий Михаил 2a28744e41 Исправлено переключение на unstable серверы обновлений
8 years ago
Хирецкий Михаил 0638f9663d Изменён порядок опций
8 years ago
Хирецкий Михаил a7f035d655 Изменён порядок параметров cl-update
8 years ago
Хирецкий Михаил 990c23d454 Исправлена переменная
8 years ago
Хирецкий Михаил a087ecad89 Исправлено использование testing сервера обновлений
8 years ago
Хирецкий Михаил d7dc318e1a Добавлена поддержка использование testing серверов обновлений
8 years ago
Хирецкий Михаил 6188d9c1eb Исправлена синхронизация portage репозитория
8 years ago
Хирецкий Михаил 1039fca5ec Поддержка gentoo названия для /usr/portage
8 years ago
Хирецкий Михаил 97db03579b Update copyrights.
8 years ago
Хирецкий Михаил acaf5b3b76 Исправлена распаковка репозиториев
9 years ago
Хирецкий Михаил 9f988d3bbe Изменено сообщение при eix-update
9 years ago
Хирецкий Михаил b6759a7040 Добавлено логгирование обновления списка бинхостов
9 years ago
Хирецкий Михаил 3adbb14780 Добавлено сообщение если --scan выдал тот же сервер
9 years ago
Хирецкий Михаил 9fc3da1b1f Обновлён вывод сообщения при обновлении eix
9 years ago
Хирецкий Михаил 231d79d8ee Исключён downgrade репозиториев по timestamp
9 years ago
Хирецкий Михаил 72393cf50f Изменены критерии сортировки серверов обновления
9 years ago
Хирецкий Михаил bbcec6fbf0 Обновлены фразы
9 years ago
Хирецкий Михаил a21d0643c9 Улучшена работа с репозиториями
9 years ago
Хирецкий Михаил d0a23b0528 Исправлено вывод версии с которой обновляется пакет
9 years ago
Mike Khiretskiy 4f2809e224 Refactoring
9 years ago
Mike Khiretskiy 20d09bbabf Refactoring
9 years ago
Mike Khiretskiy b3ca8fed9c Рефакторинг
9 years ago
Mike Khiretskiy 66cd9596d7 Refactoring
9 years ago
Mike Khiretskiy 9933d9cdc4 Обработка timeout для urllib.
9 years ago
Mike Khiretskiy 8de913d54a Исправлена работа layman в сборках
9 years ago
Mike Khiretskiy dad8051be9 os.rename заменён на shutil.move
9 years ago
Mike Khiretskiy 23442e2747 Исправлена работа парсера emerge с использованием --ask.
9 years ago
Mike Khiretskiy e3ee99d0c2 Исправлено использование EMERGE_DEFAULT_OPTS
9 years ago
Mike Khiretskiy 3a10dff960 Обработка TemplatesError
9 years ago
Mike Khiretskiy f42e11410b Исправлено обновление репозитория в git
9 years ago
Mike Khiretskiy e43677c569 Обновление иконок
9 years ago
Mike Khiretskiy ef4dee467a Обновление переводов
9 years ago
Mike Khiretskiy c1578da76f Исправлена установка значений переменных
9 years ago
Mike Khiretskiy f445d23e28 Исправлены сообщение и вызов emerge команды
9 years ago
Mike Khiretskiy 3f219d74e1 Переименованы фразы
9 years ago
Mike Khiretskiy 0b8a5e8fe0 Переименованы заголовки таблиц branch
9 years ago
Mike Khiretskiy ee4f335ba9 Переход на константы-ветки
9 years ago
Mike Khiretskiy 301c7759bf Исправление экспертных параметров
9 years ago
Mike Khiretskiy a801ce6dbf Добавлено сообщение при смене binhost, исправлен binhost_list
9 years ago
Mike Khiretskiy eceb9a9f72 cl_builder_binhosts -> cl_builder_binhost_list
9 years ago
Хирецкий Михаил 87d317ac69 Изменён путь до timestamp
9 years ago
Хирецкий Михаил 37aa89c4d2 Смена иконок
9 years ago
Mike Khiretskiy 51637effcf Удалена отладочная информация
9 years ago
Mike Khiretskiy 8c39a51e32 Изенена синхронизация до веток и тэгов
9 years ago
Mike Khiretskiy afdd27ff23 Добавлена поддержка binhost
9 years ago
Mike Khiretskiy abb1c37275 Множественные изменения для использования с calculate-assemble
9 years ago
Mike Khiretskiy f61f898d3c Исправлена работа cl-update в tmux
9 years ago
Mike Khiretskiy 3276ff0a2f Удалён параметр --jobs=1 в emerge parser
9 years ago
Mike Khiretskiy 8b467fc281 Сброс кэша если в списке пакетов есть blocks
9 years ago
Mike Khiretskiy 3bebabda12 Добавлено обновление кэша настраиваемых пакетов после синхронизации
9 years ago
Mike Khiretskiy 6584c7ef30 Исправлено создание отметки необходимости удаления старого ядра
9 years ago
Mike Khiretskiy e15842fe7c Исправлено определение стадии получения бинарных пакетов
9 years ago
Mike Khiretskiy 7008a04a38 Переход на cl-variable
9 years ago
Mike Khiretskiy 246d7861f0 Обновлены переводы
9 years ago
Mike Khiretskiy c0ba8fb019 Добавлена поддержка layman 2.3
9 years ago
Mike Khiretskiy bae480342c Исправлен перевод
9 years ago
Mike Khiretskiy 9a29e24119 При выключенном обновление update.updates не выставляются в on.
9 years ago
Mike Khiretskiy 105c060f6c Исправлена обработка EMERGE_DEFAULT_OPTS
9 years ago
Mike Khiretskiy 9514151562 Сброс статуса наличия обновление ini.env/update.updates при выключении
9 years ago
Mike Khiretskiy 648ff5154e Исправлено вычисление переменной ядра
9 years ago
Mike Khiretskiy f1303ba0a8 Отключена параллельная установка пакетов во время cl-update
9 years ago
Mike Khiretskiy 71c376f8b6 Добавлен параметр пропуска revdep-rebuild
9 years ago
Mike Khiretskiy 3c144a611e Исправлена зависимость setup.py от модуля calculate-lib
9 years ago
Mike Khiretskiy 2ffa285517 Пропуск eix-sync и прочих действий основанных на значении cl_update_other_set
9 years ago
Mike Khiretskiy 15160e92a4 Исправлен вывод при удалении пакета
9 years ago
Mike Khiretskiy 7841fcdbf2 Исправлено определение бинарных пакетов в выводе emerge
10 years ago
Mike Khiretskiy 64d3bd36f1 Обновление переводов
10 years ago

6
.gitignore vendored

@ -0,0 +1,6 @@
revert_changes_to_vmachine
push_to_vmachine*
.vscode
*.pyc
*.pyo
*.bak

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# если выполняется обновление уже полученного репозитория # если выполняется обновление уже полученного репозитория
if [[ $1 == "pull" ]] if [[ $1 == "pull" ]] || [[ $1 == "remote" ]]
then then
# получить название репозитория # получить название репозитория
if [[ -f profiles/repo_name ]] if [[ -f profiles/repo_name ]]
@ -16,13 +16,15 @@ then
fi fi
# получить список репозиториев дистрибутива # получить список репозиториев дистрибутива
native_reps=,$(/usr/sbin/cl-core --method core_variables_show \ native_reps=,$(/usr/libexec/calculate/cl-variable --value update.cl_update_rep_name),
--only-value update.cl_update_rep_name),
# если обновляемый репозиторий от дистрибутива # если обновляемый репозиторий от дистрибутива
if echo $native_reps | grep -q ,${repo_name}, if echo $native_reps | grep -q ,${repo_name},
then then
# отбновить репозиторий через утилиты Calculate if [[ $1 == "pull" ]]
/usr/sbin/cl-core --method update --rep $repo_name --sync-only on --skip-eix-update -T none then
# отбновить репозиторий через утилиты Calculate
/usr/sbin/cl-core --method update --rep $repo_name --sync-only on --skip-eix-update -T none
fi
else else
# выполнить обновление через git # выполнить обновление через git
/usr/bin/git $* /usr/bin/git $*

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2012-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,14 +14,14 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
__app__ = 'calculate-update' __app__ = 'calculate-update'
__version__ = '3.1.8' __version__ = '3.4.1'
import os
import sys import sys
from calculate.lib.datavars import DataVars from calculate.lib.datavars import DataVars
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_update3',sys.modules[__name__])
setLocalTranslate('cl_update3', sys.modules[__name__])
class DataVarsUpdate(DataVars): class DataVarsUpdate(DataVars):
"""Variable class for desktop package""" """Variable class for desktop package"""
@ -31,4 +31,3 @@ class DataVarsUpdate(DataVars):
self.importVariables() self.importVariables()
self.importVariables('calculate.update.variables') self.importVariables('calculate.update.variables')
self.defaultModule = "update" self.defaultModule = "update"

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2014 Calculate Ltd. http://www.calculate-linux.org # Copyright 2015-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -13,6 +13,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import hashlib import hashlib
import os import os
@ -22,13 +23,16 @@ import re
import sys import sys
from calculate.lib.utils.colortext.palette import TextState from calculate.lib.utils.colortext.palette import TextState
from calculate.lib.utils.tools import ignore from calculate.lib.utils.tools import ignore
from calculate.lib.utils.portage import EmergePackage, PackageList, EmergeUpdateInfo, \ from calculate.lib.utils.git import Git, GitError
EmergeRemoveInfo, Git, GitError from calculate.lib.utils.portage import (EmergePackage, PackageList,
EmergeUpdateInfo,
EmergeRemoveInfo)
Colors = TextState.Colors Colors = TextState.Colors
import pexpect import pexpect
from calculate.lib.utils.files import getProgPath, readLinesFile, listDirectory, \ from calculate.lib.utils.files import (getProgPath, readLinesFile,
writeFile, readFile listDirectory,
writeFile, readFile)
from calculate.lib.utils.colortext.output import XmlOutput from calculate.lib.utils.colortext.output import XmlOutput
from calculate.lib.utils.colortext.converter import (ConsoleCodes256Converter, from calculate.lib.utils.colortext.converter import (ConsoleCodes256Converter,
XmlConverter) XmlConverter)
@ -39,6 +43,7 @@ from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
linux_term_env = {'TERM': 'linux'}
class EmergeError(Exception): class EmergeError(Exception):
""" """
@ -50,7 +55,7 @@ class EmergeNeedRootError(EmergeError):
pass pass
class CommandExecutor(object): class CommandExecutor():
""" """
Запуск программы для объекта Emerge Запуск программы для объекта Emerge
""" """
@ -59,27 +64,39 @@ class CommandExecutor(object):
def __init__(self, cmd, params, env=None, cwd=None, logfile=None): def __init__(self, cmd, params, env=None, cwd=None, logfile=None):
self.cwd = cwd self.cwd = cwd
self.env = env or dict(os.environ) self.env = env or dict(os.environ)
self.env.update({'EINFO_QUIET':'NO'}) self.env.update({'EINFO_QUIET': 'NO'})
self.env.update(linux_term_env)
self.cmd = cmd self.cmd = cmd
self.params = params self.params = params
self.child = None self.child = None
if logfile: if logfile:
self.logfile = logfile self.logfile = logfile
def get_command(self):
return [self.cmd] + list(self.params)
#TODO make sure pexpect encoding doesn't mess up anything
#if it does, instead put log file as binary maybe?
def execute(self): def execute(self):
if self.child is None: if self.child is None:
self.child = pexpect.spawn(self.cmd, command_data = self.get_command()
self.child = pexpect.spawn(command_data[0], command_data[1:],
logfile=open(self.logfile, 'w'), logfile=open(self.logfile, 'w'),
env=self.env, cwd=self.cwd, timeout=None) env=self.env, cwd=self.cwd, timeout=None,
encoding="UTF-8", codec_errors='ignore')
return self.child return self.child
def close(self): def close(self):
if self.child is not None: if self.child is not None:
self.child.close() try:
self.child.close()
except pexpect.ExceptionPexpect:
self.child.close(force=True)
self.child = None self.child = None
def success(self): def success(self):
if self.child: if self.child:
self.child.read()
if self.child.isalive(): if self.child.isalive():
self.child.wait() self.child.wait()
return self.child.exitstatus == 0 return self.child.exitstatus == 0
@ -99,51 +116,98 @@ class EmergeCommand(CommandExecutor):
""" """
# параметры по умолчанию # параметры по умолчанию
default_params = ["-av", "--color=y", "--nospinner"] default_params = ["-av", "--color=y", "--nospinner"]
cmd = getProgPath("/usr/bin/emerge") emerge_cmd = getProgPath("/usr/bin/emerge")
def __init__(self, packages, extra_params=None, env=None, cwd=None, def __init__(self, packages, extra_params=None, env=None, cwd=None,
logfile=None, emerge_default_opts=None): logfile=None, emerge_default_opts=None, env_update=None,
use=""):
extra_params = extra_params or [] extra_params = extra_params or []
self.child = None if env is None:
self.packages = packages if emerge_default_opts is None:
self.params = self.default_params + extra_params env = {'CLEAN_DELAY': '0'}
wrong_default_opts = ("--columns","--ask ", "--ask=") else:
if emerge_default_opts is None: env = {
default_env = {'CLEAN_DELAY': '0'} 'CLEAN_DELAY': '0',
else: 'EMERGE_DEFAULT_OPTS': re.sub(
default_env = { r'(?:^|\s)(--columns)(?=\s|$)', '',
'CLEAN_DELAY': '0', emerge_default_opts)
'EMERGE_DEFAULT_OPTS': " ".join(filter( }
lambda x: not any(y in x for y in wrong_default_opts), if use:
emerge_default_opts)) env["USE"] = use
} env.update(os.environ)
default_env.update(os.environ) if env_update is not None:
self.env = env or default_env env.update(env_update)
self.cwd = cwd
if logfile:
self.logfile = logfile
def execute(self): params = self.default_params + extra_params + packages
if self.child is None: super().__init__(self.emerge_cmd, params=params,
self.child = pexpect.spawn(self.cmd, self.params + self.packages, env=env, cwd=cwd, logfile=logfile)
logfile=open(self.logfile, 'w'),
env=self.env, cwd=self.cwd, timeout=None)
return self.child
class EmergeInformationBlock(object): def Chroot(chroot_path, obj):
_color_block = "(?:\033\[[^m]+?m)?" """
_new_line = "\r*\n" Преобразовать команду (экземпляр объекта) в chroot
:param obj: экземпляр команды
:param chroot_path: путь для chroot
:return:
"""
old_get_command = obj.get_command
def get_command():
chrootCmd = '/usr/bin/chroot'
bashCmd = '/bin/bash'
bash_command = (
"env-update &>/dev/null;"
"source /etc/profile &>/dev/null;"
"{cmd}".format(cmd=" ".join(old_get_command())))
return [chrootCmd, chroot_path, bashCmd, "-c", bash_command]
obj.get_command = get_command
return obj
def Linux32(obj):
"""
Преобразовать команду (экземпляр объекта) в вызов под linux32
:param obj: экземпляр команды
:return:
"""
old_get_command = obj.get_command
def get_command():
return ["/usr/bin/linux32"] + old_get_command()
obj.get_command = get_command
return obj
class InfoBlockInterface():
"""
Интерфейс для информационного блока
"""
action = None
token = None token = None
result = None
text_converter = ConsoleCodes256Converter(XmlOutput())
def get_block(self, child):
pass
def add_element(self, element):
"""
:type element: InfoBlockInterface
"""
pass
class EmergeInformationBlock(InfoBlockInterface):
_color_block = "(?:\033\[[^m]+?m)?"
_new_line = "(?:\r*\n)"
end_token = ["\n"] end_token = ["\n"]
re_block = None re_block = None
action = None
re_match_type = type(re.match("", "")) re_match_type = type(re.match("", ""))
re_type = type(re.compile("")) re_type = type(re.compile(""))
def __init__(self, parent): def __init__(self, parent):
""" """
:type parent: EmergeParser :type parent: InfoBlockInterface
""" """
self.result = None self.result = None
self.text_converter = parent.text_converter self.text_converter = parent.text_converter
@ -152,6 +216,9 @@ class EmergeInformationBlock(object):
self.children = [] self.children = []
def add_element(self, element): def add_element(self, element):
"""
:type element: InfoBlockInterface
"""
self.children.append(element) self.children.append(element)
def __str__(self): def __str__(self):
@ -209,18 +276,22 @@ class InstallPackagesBlock(EmergeInformationBlock):
""" """
list = PackageList([]) list = PackageList([])
remove_list = PackageList([]) remove_list = PackageList([])
block_packages = False
_new_line = EmergeInformationBlock._new_line _new_line = EmergeInformationBlock._new_line
_color_block = EmergeInformationBlock._color_block
token = "\n[" token = "\n["
end_token = ["\r\n\r", "\n\n"] end_token = ["\r\n\r", "\n\n"]
re_block = re.compile(r"((?:^\[.*?{nl})+)".format(nl=_new_line), re_block = re.compile(r"((?:^\[.*?{nl})+)".format(nl=_new_line),
re.MULTILINE) re.MULTILINE)
re_blocks = re.compile(r"\[{c}blocks{c} {c}b".format(c=_color_block))
def get_data(self, match): def get_data(self, match):
super(InstallPackagesBlock, self).get_data(match) super().get_data(match)
list_block = XmlConverter().transform(self.result).split('\n') list_block = XmlConverter().transform(self.result).split('\n')
self.list = PackageList(map(EmergeUpdateInfo, list_block)) self.list = PackageList(map(EmergeUpdateInfo, list_block))
self.remove_list = PackageList(map(EmergeRemoveInfo, list_block)) self.remove_list = PackageList(map(EmergeRemoveInfo, list_block))
self.block_packages = any(self.re_blocks.search(x) for x in list_block)
class UninstallPackagesBlock(EmergeInformationBlock): class UninstallPackagesBlock(EmergeInformationBlock):
@ -232,7 +303,7 @@ class UninstallPackagesBlock(EmergeInformationBlock):
_new_line = EmergeInformationBlock._new_line _new_line = EmergeInformationBlock._new_line
_color_block = EmergeInformationBlock._color_block _color_block = EmergeInformationBlock._color_block
token = ["Calculating removal order", token = ["Calculating removal order",
"These are the packages that would be unmerged",] "These are the packages that would be unmerged"]
end_token = re.compile("All selected packages:.*\n") end_token = re.compile("All selected packages:.*\n")
re_block = re.compile( re_block = re.compile(
r"(?:{token}).*?{nl}(.*){nl}All selected packages: (.*?){nl}". r"(?:{token}).*?{nl}(.*){nl}All selected packages: (.*?){nl}".
@ -251,7 +322,29 @@ class UninstallPackagesBlock(EmergeInformationBlock):
self.list = PackageList(map(EmergePackage, list_block)) self.list = PackageList(map(EmergePackage, list_block))
class FinishEmergeGroup(EmergeInformationBlock): class GroupEmergeInformationBlock(EmergeInformationBlock):
"""
Группа блоков
"""
def get_block(self, child):
self.children_get_block(child)
self.result = True
def children_get_block(self, child):
for block in self.children:
block.get_block(child)
def children_action(self, child):
for block in (x for x in self.children if x.result and x.action):
if block.action(child) is False:
return False
def action(self, child):
self.children_action(child)
return False
class FinishEmergeGroup(GroupEmergeInformationBlock):
""" """
Блок завершения команды Блок завершения команды
""" """
@ -274,19 +367,6 @@ class FinishEmergeGroup(EmergeInformationBlock):
else: else:
self.result = True self.result = True
def children_get_block(self, child):
for block in self.children:
block.get_block(child)
def children_action(self, child):
for block in (x for x in self.children if x.result and x.action):
if block.action(child) is False:
break
def action(self, child):
self.children_action(child)
return False
class PrepareErrorBlock(EmergeInformationBlock): class PrepareErrorBlock(EmergeInformationBlock):
""" """
@ -335,21 +415,88 @@ class DownloadSizeBlock(EmergeInformationBlock):
else: else:
return "0 kB" return "0 kB"
class SkippedPackagesBlock(EmergeInformationBlock):
"""
Размер скачиваемых обновлений
"""
token = "The following update has been skipped"
end_token = ["For more information, see the MASKED"]
re_block = re.compile(
r"(The following update has.*?)(?=For more information)", re.S)
class QuestionBlock(EmergeInformationBlock): def __str__(self):
if self.result:
return self.result
else:
return ""
class QuestionGroup(GroupEmergeInformationBlock):
""" """
Блок вопроса Группа блоков разбора вопросов от emerge
""" """
default_answer = "yes"
_color_block = EmergeInformationBlock._color_block
token = "Would you like" token = "Would you like"
end_token = ["]", "\n"] end_token = ["]", "\n"]
_color_block = EmergeInformationBlock._color_block
re_block = re.compile( re_block = re.compile(
"(Would you.*)\[{c}Yes{c}/{c}No{c}".format(c=_color_block)) "(Would you.*)\[{c}Yes{c}/{c}No{c}".format(c=_color_block))
def get_block(self, child):
try:
before = child.before
token = child.match
if type(self.end_token) == self.re_type:
child.expect(self.end_token)
match = child.match.group()
else:
child.expect_exact(self.end_token)
match = child.match
data = token + child.before + match
child.before = before
for block in self.children:
child.match = re.search(block.token, data)
block.get_block(child)
if block.result:
break
except pexpect.EOF:
child.buffer = "".join(
[x for x in (child.before, child.after, child.buffer)
if type(x) == str])
class QuestionChangeConfigBlock(GroupEmergeInformationBlock):
"""
Вопрос об изменении конфигурационных файлов
"""
token = "Would you like to add these changes to your config files"
def get_block(self, child):
if child.match:
self.result = self.token
self.children_get_block(child)
def action(self, child):
if self.result:
child.send("no\n")
if child.isalive():
child.wait()
self.children_action(child)
class QuestionBlock(EmergeInformationBlock):
"""
Блок вопроса
"""
default_answer = "yes"
token = "Would you"
def get_block(self, child):
if child.match:
self.result = self.token
def action(self, child): def action(self, child):
if self.result: if self.result:
child.send("%s\n" % self.default_answer) child.send("%s\n" % self.default_answer)
return False
class NeedRootBlock(EmergeInformationBlock): class NeedRootBlock(EmergeInformationBlock):
@ -370,7 +517,7 @@ class NotifierInformationBlock(EmergeInformationBlock):
Информационный блок поддерживающий observing Информационный блок поддерживающий observing
""" """
def __init__(self, parent): def __init__(self, parent):
super(NotifierInformationBlock, self).__init__(parent) super().__init__(parent)
self.observers = [] self.observers = []
def get_data(self, match): def get_data(self, match):
@ -379,6 +526,13 @@ class NotifierInformationBlock(EmergeInformationBlock):
def add_observer(self, f): def add_observer(self, f):
self.observers.append(f) self.observers.append(f)
def clear_observers(self):
self.observers = []
def remove_observer(self, f):
if f in self.observers:
self.observers.remove(f)
def notify(self, observer, groups): def notify(self, observer, groups):
observer(groups) observer(groups)
@ -427,11 +581,12 @@ class FetchingTarball(NotifierInformationBlock):
Происходит скачивание архивов Происходит скачивание архивов
""" """
token = "Saving to:" token = "Saving to:"
re_block = re.compile("Saving to:\s*(\S+)?") re_block = re.compile("Saving to:\s*['](\S+)?[']")
def notify(self, observer, groups): def notify(self, observer, groups):
observer(groups[0]) observer(groups[0])
class InstallingPackage(NotifierInformationBlock): class InstallingPackage(NotifierInformationBlock):
""" """
Запуск устанавливаемого пакета Запуск устанавливаемого пакета
@ -447,7 +602,8 @@ class InstallingPackage(NotifierInformationBlock):
"of {c}(\d+){c}\) {c}([^\s\033]+){c}".format(c=_color_block)) "of {c}(\d+){c}\) {c}([^\s\033]+){c}".format(c=_color_block))
def notify(self, observer, groups): def notify(self, observer, groups):
binary = bool(self.binary and groups[2] in self.binary) strpkg = str(EmergePackage(groups[2]))
binary = bool(self.binary and strpkg in self.binary)
observer(EmergePackage(groups[2]), binary=binary) observer(EmergePackage(groups[2]), binary=binary)
def mark_binary(self, package): def mark_binary(self, package):
@ -507,23 +663,27 @@ class RevdepPercentBlock(NotifierInformationBlock):
except pexpect.EOF: except pexpect.EOF:
self.result = "" self.result = ""
class EmergeParser(object): class EmergeParser(InfoBlockInterface):
""" """
Парсер вывода emerge Парсер вывода emerge
""" """
def __init__(self, command, run=False): def __init__(self, command, run=False):
self.text_converter = ConsoleCodes256Converter(XmlOutput())
self.command = command self.command = command
self.elements = {} self.elements = {}
self.install_packages = InstallPackagesBlock(self) self.install_packages = InstallPackagesBlock(self)
self.uninstall_packages = UninstallPackagesBlock(self) self.uninstall_packages = UninstallPackagesBlock(self)
self.question = QuestionBlock(self) self.question_group = QuestionGroup(self)
self.change_config_question = QuestionChangeConfigBlock(
self.question_group)
self.question = QuestionBlock(self.question_group)
self.finish_block = FinishEmergeGroup(self) self.finish_block = FinishEmergeGroup(self)
self.need_root = NeedRootBlock(self) self.need_root = NeedRootBlock(self)
self.prepare_error = PrepareErrorBlock(self.finish_block) self.prepare_error = PrepareErrorBlock(self.finish_block)
self.change_config_question.add_element(self.prepare_error)
self.download_size = DownloadSizeBlock(self) self.download_size = DownloadSizeBlock(self)
self.skipped_packages = SkippedPackagesBlock(self)
self.emerging_error = EmergeingErrorBlock(self) self.emerging_error = EmergeingErrorBlock(self)
self.installing = InstallingPackage(self) self.installing = InstallingPackage(self)
@ -544,6 +704,9 @@ class EmergeParser(object):
self.fetching.action = lambda child: None self.fetching.action = lambda child: None
def add_element(self, element): def add_element(self, element):
"""
:type element: InfoBlockInterface
"""
if element.token: if element.token:
if type(element.token) == list: if type(element.token) == list:
for token in element.token: for token in element.token:
@ -559,7 +722,7 @@ class EmergeParser(object):
while True: while True:
index = child.expect_exact(self.elements.keys()) index = child.expect_exact(self.elements.keys())
element = self.elements.values()[index] element = list(self.elements.values())[index]
element.get_block(child) element.get_block(child)
if element.action: if element.action:
if element.action(child) is False: if element.action(child) is False:
@ -575,7 +738,7 @@ class EmergeParser(object):
self.close() self.close()
class MtimeCheckvalue(object): class MtimeCheckvalue():
def __init__(self, *fname): def __init__(self, *fname):
self.fname = fname self.fname = fname
@ -597,30 +760,31 @@ class MtimeCheckvalue(object):
class Md5Checkvalue(MtimeCheckvalue): class Md5Checkvalue(MtimeCheckvalue):
def value_func(self, fn): def value_func(self, fn):
return hashlib.md5(readFile(fn)).hexdigest() return hashlib.md5(readFile(fn, binary=True)).hexdigest()
class GitCheckvalue(object): class GitCheckvalue():
def __init__(self, rpath): def __init__(self, git, rpath):
self.rpath = rpath self.rpath = rpath
self.git = Git() self.git = git
def checkvalues(self): def checkvalues(self):
with ignore(GitError): with ignore(GitError):
if self.git.is_git(self.rpath): if self.git.is_git(self.rpath):
yield self.rpath, Git().getCurrentCommit(self.rpath) yield self.rpath, self.git.getCurrentCommit(self.rpath)
class EmergeCache(object): class EmergeCache():
""" """
Кэш пакетов Кэш пакетов
""" """
cache_file = '/var/lib/calculate/calculate-update/world.cache' cache_file = '/var/lib/calculate/calculate-update/world.cache'
# список файлов проверяемый по mtime на изменения # список файлов проверяемый по mtime на изменения
check_list = [MtimeCheckvalue('/etc/make.conf', check_list = [MtimeCheckvalue('/etc/make.conf',
'/etc/portage', '/etc/portage',
'/etc/make.profile'), '/etc/make.profile'),
Md5Checkvalue('/var/lib/portage/world', Md5Checkvalue('/var/lib/portage/world',
'/var/lib/portage/world_sets')] '/var/lib/portage/world_sets')]
logger = log("emerge-cache", logger = log("emerge-cache",
filename="/var/log/calculate/emerge-cache.log", filename="/var/log/calculate/emerge-cache.log",
formatter="%(asctime)s - %(levelname)s - %(message)s") formatter="%(asctime)s - %(levelname)s - %(message)s")
@ -638,16 +802,16 @@ class EmergeCache(object):
f.write("{fn}={val}\n".format(fn=fn, val=val)) f.write("{fn}={val}\n".format(fn=fn, val=val))
f.write('\n') f.write('\n')
for pkg in package_list: for pkg in package_list:
f.write("%s\n"% str(pkg)) f.write("%s\n" % str(pkg))
self.logger.info("Setting cache (%d packages)"%len(package_list)) self.logger.info("Setting cache (%d packages)" % len(package_list))
def drop_cache(self, reason=None): def drop_cache(self, reason=None):
if path.exists(self.cache_file): if path.exists(self.cache_file):
with ignore(OSError): with ignore(OSError):
os.unlink(self.cache_file) os.unlink(self.cache_file)
self.logger.info("Droping cache. Reason: %s"%reason) self.logger.info("Droping cache. Reason: %s" % reason)
else: else:
self.logger.info("Droping empty cache. Reason: %s"%reason) self.logger.info("Droping empty cache. Reason: %s" % reason)
def get_cached_package_list(self): def get_cached_package_list(self):
self.read_cache() self.read_cache()
@ -667,10 +831,10 @@ class EmergeCache(object):
return True return True
else: else:
reason = "Unknown" reason = "Unknown"
for k,v in self.get_control_values().items(): for k, v in self.get_control_values().items():
if k in self.files_control_values: if k in self.files_control_values:
if v != self.files_control_values[k]: if v != self.files_control_values[k]:
reason = "%s was modified"%k reason = "%s was modified" % k
else: else:
reason = "Checksum of file %s is not exist" % k reason = "Checksum of file %s is not exist" % k
self.logger.info("Failed to get cache. Reason: %s" % reason) self.logger.info("Failed to get cache. Reason: %s" % reason)
@ -680,7 +844,7 @@ class EmergeCache(object):
self.files_control_values = {} self.files_control_values = {}
cache_file_lines = readLinesFile(self.cache_file) cache_file_lines = readLinesFile(self.cache_file)
for line in cache_file_lines: for line in cache_file_lines:
if not "=" in line: if "=" not in line:
break break
k, v = line.split('=') k, v = line.split('=')
self.files_control_values[k] = v.strip() self.files_control_values[k] = v.strip()
@ -689,6 +853,7 @@ class EmergeCache(object):
def get_control_values(self): def get_control_values(self):
def generate(): def generate():
for obj in self.check_list: for obj in self.check_list:
for checkvalue in obj.checkvalues(): for check_value in obj.checkvalues():
yield checkvalue yield check_value
return dict(generate()) return dict(generate())

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2014 Calculate Ltd. http://www.calculate-linux.org # Copyright 2014-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -13,37 +13,51 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import sys import sys
import os
from os import path from os import path
import shutil import shutil
import os from calculate.lib.utils.files import (listDirectory, readFile, readLinesFile,
from calculate.lib.utils.files import listDirectory, readFile, readLinesFile, \ makeDirectory, removeDir)
makeDirectory, removeDir from calculate.lib.utils.git import Git
from calculate.lib.utils.portage import Git from .update import UpdateError
from update import UpdateError
from calculate.lib.cl_lang import setLocalTranslate, _ from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
DEFAULT_BRANCH = "master" DEFAULT_BRANCH = Git.Reference.Master
class RepositoryStorageInterface():
def __iter__(self):
raise StopIteration
def get_profiles(self, url, branch=DEFAULT_BRANCH):
return []
def get_repository(self, url, branch=DEFAULT_BRANCH):
return None
class RepositoryStorage(object): class RepositoryStorage(RepositoryStorageInterface):
directory = '/tmp' directory = '/tmp'
def __init__(self, directory): def __init__(self, git, directory):
self.directory = directory self.directory = directory
self.git = git
makeDirectory(directory) makeDirectory(directory)
def __iter__(self): def __iter__(self):
git = Git()
for dn in listDirectory(self.directory, onlyDir=True, fullPath=True): for dn in listDirectory(self.directory, onlyDir=True, fullPath=True):
if git.is_git(dn): if self.git.is_git(dn):
yield ProfileRepository(path.basename(dn), self) yield ProfileRepository(self.git, path.basename(dn), self)
def get_profiles(self, url, branch=DEFAULT_BRANCH): def get_profiles(self, url, branch=DEFAULT_BRANCH):
return [] return []
def get_repository(self, url, branch=DEFAULT_BRANCH):
return None
class ProfileStorage(RepositoryStorage): class ProfileStorage(RepositoryStorage):
def get_profiles(self, url, branch=DEFAULT_BRANCH): def get_profiles(self, url, branch=DEFAULT_BRANCH):
rep = self.get_repository(url, branch) rep = self.get_repository(url, branch)
@ -54,6 +68,7 @@ class ProfileStorage(RepositoryStorage):
def get_repository(self, url, branch=DEFAULT_BRANCH): def get_repository(self, url, branch=DEFAULT_BRANCH):
return None return None
class LocalStorage(ProfileStorage): class LocalStorage(ProfileStorage):
""" """
Локальное хранилище репозиториев, при запросе по урлу смотрит, доступные Локальное хранилище репозиториев, при запросе по урлу смотрит, доступные
@ -64,7 +79,6 @@ class LocalStorage(ProfileStorage):
if rep.is_like(url, branch): if rep.is_like(url, branch):
return rep return rep
class CacheStorage(ProfileStorage): class CacheStorage(ProfileStorage):
""" """
Хранилище репозиториев, при запросе по урлу смотрит, доступные Хранилище репозиториев, при запросе по урлу смотрит, доступные
@ -76,15 +90,15 @@ class CacheStorage(ProfileStorage):
if rep.is_like(url, branch): if rep.is_like(url, branch):
return rep return rep
else: else:
return ProfileRepository.clone(url, self, branch) return ProfileRepository.clone(self.git, url, self,
branch or DEFAULT_BRANCH)
class RepositoryStorageSet(RepositoryStorage): class RepositoryStorageSet(RepositoryStorageInterface):
""" """
Набор хранилищ репозиториев Набор хранилищ репозиториев
""" """
def __init__(self): def __init__(self, *storages):
self.storages = [LocalStorage('/var/lib/layman'), self.storages = storages
CacheStorage('/var/calculate/tmp/update')]
def get_profiles(self, url, branch=DEFAULT_BRANCH): def get_profiles(self, url, branch=DEFAULT_BRANCH):
""" """
@ -108,6 +122,10 @@ class RepositoryStorageSet(RepositoryStorage):
for rep in self: for rep in self:
if rep.is_like(url, branch): if rep.is_like(url, branch):
return rep return rep
for storage in self.storages:
rep = storage.get_repository(url, branch)
if rep:
return rep
return None return None
def is_local(self, url, branch=DEFAULT_BRANCH): def is_local(self, url, branch=DEFAULT_BRANCH):
@ -123,7 +141,7 @@ class RepositoryStorageSet(RepositoryStorage):
def __repr__(self): def __repr__(self):
return "Repository set" return "Repository set"
class Profile(object): class Profile():
""" """
Профиль репозитория Профиль репозитория
""" """
@ -133,14 +151,22 @@ class Profile(object):
self.repository = repository self.repository = repository
self.profile = profile self.profile = profile
self.arch = arch self.arch = arch
self._path = None
@property @property
def path(self): def path(self):
if self._path:
return self._path
return path.join(self.repository.directory,"profiles", self.profile) return path.join(self.repository.directory,"profiles", self.profile)
@path.setter
def path(self, value):
self._path = value
return value
@classmethod @classmethod
def from_string(cls, repository, s): def from_string(cls, repository, s):
parts = filter(None, s.split()) parts = [x for x in s.split() if x]
if len(parts) == 3 and parts[0] in cls.available_arch: if len(parts) == 3 and parts[0] in cls.available_arch:
return Profile(repository, parts[1], parts[0]) return Profile(repository, parts[1], parts[0])
return None return None
@ -152,13 +178,14 @@ class Profile(object):
self.repository.directory) self.repository.directory)
class ProfileRepository(object): class ProfileRepository():
""" """
Репозиторий либо скачивается, либо берется из кэша Репозиторий либо скачивается, либо берется из кэша
""" """
def __init__(self, name, storage): def __init__(self, git, name, storage):
self._storage = storage self._storage = storage
self.name = name self.name = name
self.git = git
@property @property
def storage(self): def storage(self):
@ -180,22 +207,28 @@ class ProfileRepository(object):
str(e)) str(e))
@classmethod @classmethod
def clone(cls, url, storage, branch=DEFAULT_BRANCH): def clone(cls, git, url, storage, branch=DEFAULT_BRANCH):
name = path.basename(url) name = path.basename(url)
if name.endswith(".git"): if name.endswith(".git"):
name = name[:-4] name = name[:-4]
git = Git()
rpath = path.join(storage.directory, name) rpath = path.join(storage.directory, name)
if path.exists(rpath): if path.exists(rpath):
removeDir(rpath) removeDir(rpath)
if git.is_private_url(url):
try:
makeDirectory(rpath)
os.chmod(rpath, 0o700)
except OSError:
pass
git.cloneRepository(url, rpath, branch) git.cloneRepository(url, rpath, branch)
pr = cls(name, storage) pr = cls(git, name, storage)
repo_name = pr.repo_name repo_name = pr.repo_name
if name != repo_name: if name != repo_name:
rpath_new = path.join(storage.directory, repo_name) rpath_new = path.join(storage.directory, repo_name)
if not path.exists(rpath_new): if path.exists(rpath_new):
os.rename(rpath, rpath_new) removeDir(rpath_new)
pr = cls(repo_name, storage) shutil.move(rpath, rpath_new)
pr = cls(git, repo_name, storage)
return pr return pr
@property @property
@ -217,30 +250,32 @@ class ProfileRepository(object):
@property @property
def url(self): def url(self):
git = Git() return self.git.get_url(self.directory, "origin")
return git.get_url(self.directory, "origin")
@property @property
def branch(self): def branch(self):
git = Git() return self.git.getBranch(self.directory)
return git.getBranch(self.directory)
def sync(self): def sync(self):
""" """
Синхронизировать репозиторий Синхронизировать репозиторий
""" """
git = Git() if not self.git.pullRepository(self.directory, quiet_error=True):
if not git.pullRepository(self.directory, quiet_error=True): self.git.resetRepository(self.directory, to_origin=True)
git.resetRepository(self.directory, to_origin=True) self.git.pullRepository(self.directory, quiet_error=True)
git.pullRepository(self.directory, quiet_error=True)
def get_profiles(self): def get_profiles(self):
""" """
Получить список профилей репозитория Получить список профилей репозитория
""" """
profiles_desc = path.join(self.directory, "profiles/profiles.desc") profiles_desc = path.join(self.directory, "profiles/profiles.desc")
return filter(None, (Profile.from_string(self, line) return list(filter(None, (Profile.from_string(self, line)
for line in readLinesFile(profiles_desc))) for line in readLinesFile(profiles_desc))))
@staticmethod
def get_local_profiles(directory):
profiles_desc = path.join(directory, "profiles/profiles.desc")
return list(filter(None, (Profile.from_string(Profile, line)
for line in readLinesFile(profiles_desc))))
def __repr__(self): def __repr__(self):
return "<ProfileRepository %s url=%s>" % (self.directory, self.url) return "<ProfileRepository %s url=%s>" % (self.directory, self.url)

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2012-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -16,21 +16,18 @@
import os import os
from os import path from os import path
from itertools import ifilter
from calculate.core.datavars import DataVarsCore from calculate.core.datavars import DataVarsCore
from calculate.core.server.gen_pid import search_worked_process from calculate.core.server.gen_pid import search_worked_process
from calculate.lib.cl_template import SystemIni from calculate.lib.cl_template import SystemIni
from calculate.lib.utils.content import getCfgFiles from calculate.lib.utils.content import getCfgFiles
from calculate.lib.utils.files import getRunCommands, readFile from calculate.lib.utils.files import getRunCommands, readFile, writeFile
import time
class UpdateInfo(object): class UpdateInfo():
""" """
Информационный объект о процессе обновления Информационный объект о процессе обновления
""" """
section = "update" update_file = "/var/lib/calculate/calculate-update/updates.available"
varname = "updates"
def __init__(self, dv=None): def __init__(self, dv=None):
if dv is None: if dv is None:
@ -40,22 +37,27 @@ class UpdateInfo(object):
self.dv = dv self.dv = dv
def need_update(self): def need_update(self):
return self.update_ready() or self.check_for_dispatch() return self.update_ready()
@classmethod @classmethod
def update_ready(cls): def update_ready(cls):
""" """
Проверить есть ли обновления по ini.env Проверить есть ли обновления по ini.env
""" """
return SystemIni().getVar(cls.section, cls.varname) == u'on' return path.exists(cls.update_file)
@classmethod @classmethod
def set_update_ready(cls, value): def set_update_ready(cls, value):
""" """
Установить статус обновления Установить статус обновления
""" """
SystemIni().setVar(cls.section, try:
{cls.varname:"on" if value else "off"}) if value:
writeFile(cls.update_file).close()
else:
os.unlink(cls.update_file)
except OSError:
pass
def check_for_dispatch(self): def check_for_dispatch(self):
""" """
@ -68,7 +70,7 @@ class UpdateInfo(object):
""" """
Проверить есть ли уже запущенная копия console-gui Проверить есть ли уже запущенная копия console-gui
""" """
return any(ifilter(lambda x: "cl-console-gui" in x, getRunCommands())) return any([x for x in getRunCommands() if "cl-console-gui" in x])
def update_already_run(self): def update_already_run(self):
""" """
@ -92,10 +94,12 @@ class UpdateInfo(object):
@outdated_kernel.setter @outdated_kernel.setter
def outdated_kernel(self, value): def outdated_kernel(self, value):
flag_path = self.dv.Get('update.cl_update_outdated_kernel_path') flag_path = self.dv.Get('update.cl_update_outdated_kernel_path')
try:
if value: if value:
with open(flag_path, 'w') as f: with writeFile(flag_path) as f:
f.write(self.dv.Get('update.cl_update_kernel_version')) f.write(self.dv.Get('update.cl_update_kernel_version'))
else: else:
if path.exists(flag_path): if path.exists(flag_path):
os.unlink(flag_path) os.unlink(flag_path)
except IOError:
pass

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Copyright 2015-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed 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.
class EmergeMark:
Schedule = "schedule"
Premerge = "check updates"
PythonUpdater = "update python modules"
PerlCleaner = "update perl modules"
KernelModules = "update kernel modules"
Depclean = "depclean"
XorgModules = "update xorg modules"
PreservedLibs = "update preserved libs"
RevdepRebuild = "revdep rebuild"
Prelink = "prelink"
Automagic = "check for auto depends"
SaveTag = "save latest calculate update tag"

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,12 +15,13 @@
# limitations under the License. # limitations under the License.
import sys import sys
from calculate.core.server.func import Action, Tasks from calculate.core.server.func import Action
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.utils.files import FilesError from calculate.lib.utils.files import FilesError
from calculate.update.update import UpdateError from ..update import UpdateError
from calculate.lib.utils.portage import GitError from calculate.lib.utils.git import GitError
_ = lambda x: x
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
@ -36,12 +37,11 @@ class ClSetupUpdateAction(Action):
failedMessage = __("Failed to configure the updates autocheck procedure!") failedMessage = __("Failed to configure the updates autocheck procedure!")
interruptMessage = __("Configuration manually interrupted") interruptMessage = __("Configuration manually interrupted")
# список задач для действия
# список задач для дейсвия
tasks = [ tasks = [
{'name': 'set_variables', {'name': 'set_variables',
'method': 'Update.setAutocheckParams(cl_update_autocheck_set,' 'method': 'Update.setAutocheckParams(cl_update_autocheck_set,'
'cl_update_autocheck_interval,' 'cl_update_autocheck_interval,'
'cl_update_other_set,' 'cl_update_other_set,'
'cl_update_cleanpkg_set)'} 'cl_update_cleanpkg_set)'}
] ]

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,113 +15,363 @@
# limitations under the License. # limitations under the License.
import sys import sys
from calculate.core.server.func import Action, Tasks from calculate.core.server.func import Action, Tasks, AllTasks
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.utils.colortext import get_color_print, Colors from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.files import FilesError from calculate.lib.utils.binhosts import BinhostError
from calculate.update.update import UpdateError from calculate.lib.utils.files import FilesError, readFile
from calculate.update.emerge_parser import EmergeError from ..update import UpdateError
from calculate.lib.utils.portage import GitError, Eix, EmergeLog, \ from ..emerge_parser import EmergeError
EmergeLogNamedTask, PackageList from calculate.lib.utils.git import GitError
from calculate.lib.utils.portage import (EmergeLog, isPkgInstalled,
EmergeLogNamedTask, PackageList)
from ..update_tasks import EmergeMark
_ = lambda x: x
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
class ClUpdateAction(Action): def get_synchronization_tasks(object_name):
""" Object = lambda s: "%s.%s"%(object_name, s)
Действие обновление конфигурационных файлов return [
"""
# ошибки, которые отображаются без подробностей
native_error = (FilesError, UpdateError, GitError, EmergeError)
successMessage = None {'name': 'reps_synchronization',
failedMessage = None 'group': __("Repositories synchronization"),
interruptMessage = __("Update manually interrupted") 'tasks': [
# создать объект проверки PGP
{'name': 'prepare_gpg',
'method': Object("prepare_gpg()"),
},
# создать объект хранилище серверов обновлений
{'name': 'create_binhost_data',
'method': Object('create_binhost_data()')
},
{
'name': 'perform_migration_system_pre_check',
'method': Object('perform_migration_system_pre_check()'),
'condition': lambda Get, GetBool: (Get('cl_update_ignore_level') == 'off')
},
# проверить валиден ли текущий хост
{'name': 'check_current_binhost',
'message': __("Checking current binhost"),
'essential': False,
'method': Object('check_current_binhost(update.cl_update_binhost)'),
'condition': lambda GetBool, Get: (
not GetBool('update.cl_update_binhost_recheck_set') and
not Get('update.cl_update_binhost_choice') and
Get('update.cl_update_binhost_choice') != 'auto' and
Get('update.cl_update_sync_rep') and
Get('update.cl_update_binhost') and
Get('update.cl_update_use_migration_host') == 'off')
},
{'name': 'drop_packeges_cache',
'method': 'Update.drop_packages_cache()',
'depend': AllTasks.failed_all("check_current_binhost")
},
{'name': 'not_use_search:failed_base_binhost',
'error': __("Failed to use base binhost"),
'method': Object("delete_binhost()"),
'depend': AllTasks.failed_all("check_current_binhost")
},
{'name': 'check_chosen_binhost',
'message': _("Checking chosen binhost"),
'method': Object('check_chosen_binhost(update.cl_update_binhost_choice)'),
'essential': False,
'condition': lambda GetBool, Get: (
not GetBool('update.cl_update_binhost_recheck_set') and
Get('update.cl_update_binhost_choice') and
Get('update.cl_update_binhost_choice') != 'auto'),
'depend': AllTasks.hasnot("check_current_binhost")},
{'name': 'failed_check_chosen_binhost',
'method': Object('check_if_migration()'),
'depend': AllTasks.failed_all("check_chosen_binhost")},
{'name': 'group_find_binhost',
'group': '',
'while': (~AllTasks.has_any("detect_best_binhost") &
((AllTasks.failed_all("update_packages_cache")
& ~AllTasks.has_any("not_use_search")) |
~AllTasks.has_any("sync_reps"))) & Tasks.success(),
'condition': lambda GetBool, Get: (GetBool('update.cl_update_usetag_set') and
Get('update.cl_update_sync_rep')),
'tasks': [
# найти лучший сервер обновлений
{'name': 'detect_best_binhost',
'method': Object(f'detect_best_binhost({object_name.lower()}.cl_update_ignore_level)'),
'essential': False,
'depend': (Tasks.success() & ~AllTasks.has_any("not_use_search") &
(AllTasks.failed_one_of("check_current_binhost") |
AllTasks.failed_one_of("check_chosen_binhost") |
(AllTasks.hasnot("check_current_binhost") &
AllTasks.hasnot("check_chosen_binhost")) |
AllTasks.success_all("sync_reps"))),
'condition': lambda Get: Get('update.cl_update_use_migration_host') == 'off',
},
{'name': 'interrupt_on_no_leveled_binhost',
'method': Object("interrupt_on_no_leveled_binhost()"),
'essential': True,
'depend': (Tasks.success() & ~AllTasks.has_any("not_use_search") &
(~AllTasks.success_one_of("check_current_binhost")) &
AllTasks.failed_all("detect_best_binhost")),
'condition': lambda Get: Get('update.cl_update_use_migration_host') == 'off'
},
{'name': 'set_migration_binhost',
'method': Object('set_migration_host()'),
'depend': (Tasks.success() & ~AllTasks.has_any("not_use_search")|
AllTasks.success_all("sync_reps")),
'condition': lambda Get: Get('update.cl_update_use_migration_host') == 'on'
},
# запасная синхронизация, в ходе которой ветки обновляются до
# master
# {'name': 'sync_reps_fallback',
# 'foreach': 'update.cl_update_sync_rep',
# 'message':
# __("Fallback syncing the {eachvar:capitalize} repository"),
# 'method': Object('syncRepositories(eachvar,True)'),
# 'depend': Tasks.success() & AllTasks.failed_one_of("detect_best_binhost"),
# },
# # обновление переменных информации из binhost
# {'name': 'sync_reps_fallback:update_binhost_list',
# 'method': Object('update_binhost_list()'),
# 'depend': Tasks.success() & AllTasks.failed_one_of("detect_best_binhost"),
# },
# # найти лучший сервер обновлений
# {'name': 'sync_reps_fallback:detect_best_binhost',
# 'method': Object('detect_best_binhost()'),
# 'depend': Tasks.success() & AllTasks.failed_one_of("detect_best_binhost"),
# },
{'name': 'sync_reps',
'foreach': 'update.cl_update_sync_rep',
'message': __("Checking {eachvar:capitalize} updates"),
'method': Object('syncRepositories(eachvar)'),
'condition': lambda Get: Get('update.cl_update_sync_rep'),
'depend': Tasks.success() & ~AllTasks.success_all("update_packages_cache")
},
{'name': 'sync_reps:update_local_info_binhost',
'method': Object('update_local_info_binhost()'),
'condition': lambda Get: Get("update.cl_update_binhost_choice") == 'auto'
or not Get("update.cl_update_binhost_choice")
or Get("update.cl_update_binhost_recheck_set"),
'depend': AllTasks.hasnot('check_chosen_binhost')
},
{'name': 'sync_reps:update_binhost_list',
'essential': False,
'method': Object('update_binhost_list()'),
'condition': lambda GetBool: GetBool('update.cl_update_outdate_set')
},
{'name': 'sync_reps:update_packages_cache',
'message': __("Update packages index"),
'method': Object('download_packages(update.cl_update_portage_binhost,'
'update.cl_update_package_cache, update.cl_update_package_cache_sign,'
'update.cl_update_gpg)'),
'condition': lambda Get, GetBool: (
Get('update.cl_update_package_cache') and (
Get('update.cl_update_outdate_set') == 'on' or
Get('update.cl_update_package_cache_set') == 'on'))
},
],
},
{'name': 'no_server',
'error': __("Failed to find the binary updates server"),
'method': Object("delete_binhost()"),
# method: который должен удалить текущую информацию о сервере обновлений
'depend': (~Tasks.has_any("failed_base_binhost") & (Tasks.failed() |
Tasks.success() & AllTasks.failed_one_of("update_packages_cache"))),
'condition': lambda GetBool, Get: (GetBool('update.cl_update_usetag_set') and
Get('update.cl_update_sync_rep')),
},
{'name': 'sync_reps',
'foreach': 'update.cl_update_sync_rep',
'message': __("Checking {eachvar:capitalize} updates"),
'method': Object('syncRepositories(eachvar)'),
'condition': lambda Get, GetBool: (Get('update.cl_update_sync_rep') and
not GetBool('update.cl_update_usetag_set')),
},
{'name': 'update_rep_list',
'message': __("Repository cache update"),
'method': Object('update_rep_list()'),
'condition': lambda Get: (isPkgInstalled(
"app-eselect/eselect-repository", prefix=Get('cl_chroot_path')) and
Get('cl_chroot_path') != "/"),
'essential': False,
},
{'name': 'sync_other_reps',
'foreach': 'update.cl_update_other_rep_name',
'message': __("Syncing the {eachvar:capitalize} repository"),
'method': Object('syncOtherRepository(eachvar)'),
'condition': lambda GetBool: (GetBool('update.cl_update_other_set') or
not GetBool('update.cl_update_other_git_exists'))
},
{'name': 'trim_reps',
'foreach': 'update.cl_update_sync_rep',
'message': __("Cleaning the history of the "
"{eachvar:capitalize} repository"),
'method': Object('trimRepositories(eachvar)'),
'condition': lambda Get: (Get('update.cl_update_sync_rep') and
Get('update.cl_update_onedepth_set') == 'on')
},
{'name': 'sync_reps:regen_cache',
'foreach': 'update.cl_update_sync_overlay_rep',
'essential': False,
'method': Object('regenCache(eachvar)'),
'condition': (
lambda Get: (Get('update.cl_update_outdate_set') == 'on' and
Get('update.cl_update_egencache_force') != 'skip' or
Get('update.cl_update_egencache_force') == 'force'))
},
{'name': 'sync_other_reps:regen_other_cache',
'foreach': 'update.cl_update_other_rep_name',
'method': Object('regenCache(eachvar)'),
'essential': False,
},
{'name': 'eix_update',
'message': __("Updating the eix cache for "
"{update.cl_update_eix_repositories}"),
'method': Object('eixUpdate(cl_repository_name)'),
'condition': (
lambda Get: (Get('update.cl_update_outdate_set') == 'on' and
Get('update.cl_update_eixupdate_force') != 'skip' or
Get('update.cl_update_eixupdate_force') == 'force'))
},
{'name': 'update_setup_cache',
'message': __("Updating the cache of configurable packages"),
'method': Object('updateSetupCache()'),
'essential': False,
'condition': lambda Get: Get('update.cl_update_outdate_set') == 'on'
},
{'name': 'sync_reps:cleanpkg',
'message': __("Removing obsolete distfiles and binary packages"),
'method': Object('cleanpkg()'),
'condition': (
lambda Get: Get('update.cl_update_cleanpkg_set') == 'on' and
Get('update.cl_update_outdate_set') == 'on'),
'essential': False
},
# сообщение удачного завершения при обновлении репозиториев
{'name': 'success_syncrep',
'message': __("Synchronization finished"),
'depend': (Tasks.success() & Tasks.has_any("sync_reps",
"sync_other_reps",
"emerge_metadata",
"eix_update")),
}
]
},
]
class UpdateConditions():
@staticmethod
def was_installed(pkg, task_name): def was_installed(pkg, task_name):
def func(): def func():
task = EmergeLog(EmergeLogNamedTask(task_name)) task = EmergeLog(EmergeLogNamedTask(task_name))
return bool(PackageList(task.list)[pkg]) return bool(PackageList(task.list)[pkg])
return func return func
@staticmethod
def need_depclean(pkg, task_name): def need_depclean(pkg, task_name):
def func(Get): def func(Get):
task = EmergeLog(EmergeLogNamedTask(task_name)) task = EmergeLog(EmergeLogNamedTask(task_name))
return (bool(PackageList(task.list)[pkg]) return (bool(PackageList(task.list)[pkg])
or Get('cl_update_outdated_kernel_set') == 'on') or Get('cl_update_force_depclean_set') == 'on'
or Get('cl_update_outdated_kernel_set') == 'on'
or Get('cl_update_world_hash_set') == 'on')
return func return func
def need_upgrade(pkg): @staticmethod
def force_preserved(Get):
pfile = "/var/lib/portage/preserved_libs_registry"
content = readFile(pfile).strip()
if not content or content[1:-1].strip() == '':
return False
else:
return True
@staticmethod
def check_world_updated_after_tag_save():
def func(): def func():
return bool(Eix(pkg, Eix.Option.Upgrade).get_packages()) task = EmergeLog(EmergeLogNamedTask(EmergeMark.SaveTag))
return task.did_update_world_happen()
return func return func
def pkg_color(text): class ClUpdateAction(Action):
return text """
Действие обновление конфигурационных файлов
"""
# ошибки, которые отображаются без подробностей
native_error = (FilesError, UpdateError,
TemplatesError, BinhostError,
GitError, EmergeError)
log_names = {'schedule': "schedule", successMessage = None
'premerge': "check updates", failedMessage = None
'python_updater': "update python modules", interruptMessage = __("Update manually interrupted")
'perl_cleaner': "update perl modules",
'kernel_modules': "update kernel modules",
'depclean': "depclean",
'xorg_modules': "update xorg modules",
'preserved_libs': "update preserved libs",
'revdep': "revdep rebuild"}
emerge_tasks = [ emerge_tasks = [
{'name': 'save_bdeps_val',
'method': 'Update.save_with_bdeps()',
'essential': False
},
{'name': 'update_fastlogin_domain',
'method': "Update.update_fastlogin_domain_path()"
},
{'name': 'drop_portage_hash_on_sync',
'method': 'Update.drop_portage_state_hash()',
'condition': lambda Get: Get('cl_update_outdate_set') == 'on'
},
{'name': 'premerge_group', {'name': 'premerge_group',
'group': __("Checking for updates"), 'group': __("Checking for updates"),
'tasks': [ 'tasks': [
{'name': 'premerge', {'name': 'premerge',
'message': __("Calculating dependencies"), 'message': __("Calculating dependencies"),
'method': 'Update.premerge("-uDN","--with-bdeps=y","@world")', 'method': 'Update.premerge("-uDN","@world")',
'condition': lambda Get:Get('cl_update_sync_only_set') == 'off' 'condition': lambda Get: (
Get('cl_update_sync_only_set') == 'off' and
Get('cl_update_pretend_set') == 'on') and \
(Get('cl_update_world') != "update" or
Get('cl_update_outdate_set') == 'on' or
Get('cl_update_settings_changes_set') == 'on' or
Get('cl_update_binhost_recheck_set') == 'on' or
Get('cl_update_force_fix_set') == 'on' or
Get('update.cl_update_package_cache_set') == 'on')
}], }],
}, },
{'name': 'premerge:update', {'name': 'update',
'condition': lambda Get:Get('cl_update_pretend_set') == 'off', 'condition': lambda Get:Get('cl_update_pretend_set') == 'off' and \
'depend': Tasks.result("premerge", eq='yes') (Get('cl_update_world') != "update" or
}, Get('cl_update_outdate_set') == 'on' or
Get('cl_update_settings_changes_set') == 'on' or
Get('cl_update_binhost_recheck_set') == 'on' or
Get('cl_update_force_fix_set') == 'on' or
Get('cl_update_available_set') == 'on' or
Get('update.cl_update_package_cache_set') == 'on')
},
{'name': 'update_other', {'name': 'update_other',
'condition': lambda Get: ( Get('cl_update_pretend_set') == 'off' and 'condition': lambda Get: ( Get('cl_update_pretend_set') == 'off' and
Get('cl_update_sync_only_set') == 'off') Get('cl_update_sync_only_set') == 'off')
}, },
{'name': 'update:update_world', {'name': 'update:update_world',
'group': __("Updating packages"), 'group': __("Updating packages"),
'tasks': [ 'tasks': [
{'name': 'update:update_world', {'name': 'update_world',
'message': __("Calculating dependencies"), 'message': __("Calculating dependencies"),
'method': 'Update.emerge("-uDN","--with-bdeps=y","@world")', 'method': 'Update.emerge_ask(cl_update_pretend_set,'
} '"-uDN","@world")',
] }
}, ],
{'name': 'update:update_python', 'condition': lambda Get: (Get('cl_update_sync_only_set') == 'off' and
'group': __("Updating Python"), (Get('update.cl_update_outdate_set') == 'on' or
Get('cl_update_settings_changes_set') == 'on'))
},
{'name': 'update_other:update_perl',
'group': __("Updating Perl modules"),
'tasks': [ 'tasks': [
{'name': 'update:python_updater', {'name': 'update_other:perl_cleaner',
'message': __('Find & rebuild packages broken due '
'to a Python upgrade'),
'method': 'Update.emergelike("python-updater")',
'condition': was_installed('dev-lang/python$',
log_names['python_updater']),
'decoration': 'Update.update_task("%s")' % log_names[
'python_updater']
},
]
},
{'name': 'update:update_perl',
'group': __("Updating Perl"),
'tasks': [
{'name': 'update:perl_cleaner',
'message': __('Find & rebuild packages and Perl header files ' 'message': __('Find & rebuild packages and Perl header files '
'broken due to a perl upgrade'), 'broken due to a perl upgrade'),
'method': 'Update.emergelike("perl-cleaner", "all")', 'method': 'Update.emergelike("perl-cleaner", "all")',
'condition': was_installed('dev-lang/perl$', 'condition': UpdateConditions.was_installed(
log_names['perl_cleaner']), 'dev-lang/perl$', EmergeMark.PerlCleaner),
'decoration': 'Update.update_task("%s")' % log_names[ 'decoration': 'Update.update_task("%s")' % EmergeMark.PerlCleaner
'perl_cleaner']
}, },
] ]
}, },
@ -131,8 +381,9 @@ class ClUpdateAction(Action):
{'name': 'update_other:update_depclean', {'name': 'update_other:update_depclean',
'message': __("Calculating dependencies"), 'message': __("Calculating dependencies"),
'method': 'Update.depclean()', 'method': 'Update.depclean()',
'condition': need_depclean('.*', log_names['depclean']), 'condition': UpdateConditions.need_depclean(
'decoration': 'Update.update_task("%s")' % log_names['depclean'] '.*', EmergeMark.Depclean),
'decoration': 'Update.update_task("%s")' % EmergeMark.Depclean
}, },
] ]
}, },
@ -141,47 +392,55 @@ class ClUpdateAction(Action):
'tasks': [ 'tasks': [
{'name': 'update_other:module_rebuild', {'name': 'update_other:module_rebuild',
'message': __('Updating Kernel modules'), 'message': __('Updating Kernel modules'),
'method': 'Update.emerge("@module-rebuild")', 'method': 'Update.emerge("","@module-rebuild")',
'condition': was_installed('sys-kernel/.*source', 'condition': UpdateConditions.was_installed(
log_names['kernel_modules']), 'sys-kernel/(calculate-sources|gentoo-kernel|vanilla-kernel)', EmergeMark.KernelModules),
'decoration': 'Update.update_task("%s")' % log_names[ 'decoration': 'Update.update_task("%s")' %
'kernel_modules'] EmergeMark.KernelModules
}, },
{'name': 'update_other:x11_module_rebuild', {'name': 'update_other:x11_module_rebuild',
'message': __('Updating X.Org server modules'), 'message': __('Updating X.Org server modules'),
'method': 'Update.emerge("@x11-module-rebuild")', 'method': 'Update.emerge("","@x11-module-rebuild")',
'condition': was_installed('x11-base/xorg-server', 'condition': UpdateConditions.was_installed(
log_names['xorg_modules']), 'x11-base/xorg-server', EmergeMark.XorgModules),
'decoration': 'Update.update_task("%s")' % log_names[ 'decoration': 'Update.update_task("%s")' %
'xorg_modules'] EmergeMark.XorgModules
}, },
{'name': 'update_other:preserved_rebuild', {'name': 'update_other:preserved_rebuild',
'message': __('Updating preserved libraries'), 'message': __('Updating preserved libraries'),
'method': 'Update.emerge("@preserved-rebuild")', 'method': 'Update.emerge("","@preserved-rebuild")',
'condition': was_installed('.*', log_names['preserved_libs']), 'condition': lambda Get: (UpdateConditions.was_installed(
'decoration': 'Update.update_task("%s")' % log_names[ '.*', EmergeMark.PreservedLibs)() or
'preserved_libs'] UpdateConditions.force_preserved(Get)),
}, 'decoration': 'Update.update_task("%s")' %
EmergeMark.PreservedLibs
},
{'name': 'update_other:revdev_rebuild', {'name': 'update_other:revdev_rebuild',
'message': __('Checking reverse dependencies'), 'message': __('Checking reverse dependencies'),
'method': 'Update.revdep_rebuild("revdep-rebuild")', 'method': 'Update.revdep_rebuild("revdep-rebuild")',
'condition': was_installed('.*', log_names['revdep']), 'condition': lambda Get: (Get(
'decoration': 'Update.update_task("%s")' % log_names['revdep'] 'cl_update_revdep_rebuild_set') == 'on' and
UpdateConditions.was_installed(
'.*', EmergeMark.RevdepRebuild)()),
'decoration': 'Update.update_task("%s")' %
EmergeMark.RevdepRebuild
}, },
{'name': 'update_other:dispatch_conf_end', {'name': 'update_other:dispatch_conf_end',
'message': __("Updating configuration files"), 'message': __("Updating configuration files"),
'method':'Update.dispatchConf()', 'method': 'Update.dispatchConf()',
'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and 'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and
Get('cl_update_pretend_set') == 'off') Get('cl_update_pretend_set') == 'off')
}, },
] ]
}, },
{'name': 'update:set_upto_date_cache', {'name': 'set_upto_date_cache',
'method': 'Update.setUpToDateCache()' 'method': 'Update.setUpToDateCache()',
'condition': lambda Get: Get('cl_update_sync_only_set') == 'off' and \
Get('cl_update_pretend_set') == 'off'
} }
] ]
# список задач для дейсвия # список задач для действия
tasks = [ tasks = [
{'name': 'check_schedule', {'name': 'check_schedule',
'method': 'Update.checkSchedule(cl_update_autocheck_interval,' 'method': 'Update.checkSchedule(cl_update_autocheck_interval,'
@ -192,103 +451,110 @@ class ClUpdateAction(Action):
{'name': 'check_run', {'name': 'check_run',
'method': 'Update.checkRun(cl_update_wait_another_set)' 'method': 'Update.checkRun(cl_update_wait_another_set)'
}, },
{'name': 'reps_synchronization', {'name': 'check_if_world_was_updated',
'group': __("Repositories synchronization"), 'method': 'Update.update_set_current_saved_tag()',
'tasks': [ 'essential': False,
{'name': 'sync_reps', 'condition': lambda Get: (Get('cl_update_sync_only_set') == 'off' and \
'foreach': 'cl_update_sync_rep', Get('cl_update_pretend_set') == 'off' and \
'message': __("Syncing the {eachvar:capitalize} repository"), UpdateConditions.check_world_updated_after_tag_save()())
'method': 'Update.syncRepositories(eachvar)',
'condition': lambda Get: Get('cl_update_sync_rep')
},
{'name': 'sync_other_reps',
'foreach': 'cl_update_other_rep_name',
'message': __("Syncing the {eachvar:capitalize} repository"),
'method': 'Update.syncLaymanRepository(eachvar)',
'condition': lambda Get: Get('cl_update_other_set') == 'on'
},
{'name': 'sync_reps:regen_cache',
'foreach': 'cl_update_sync_overlay_rep',
'essential': False,
'method': 'Update.regenCache(eachvar)',
'condition': (
lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_egencache_force') != 'skip' or
Get('cl_update_egencache_force') == 'force'))
},
{'name': 'sync_other_reps:regen_other_cache',
'foreach': 'cl_update_other_rep_name',
'method': 'Update.regenCache(eachvar)',
'essential': False,
},
{'name': 'emerge_metadata',
'message': __("Metadata transfer"),
'method': 'Update.emergeMetadata()',
'condition': (
lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_metadata_force') != 'skip' or
Get('cl_update_metadata_force') == 'force'))
},
{'name': 'eix_update',
'message': __("Updating the eix cache"),
'method': 'Update.eixUpdate()',
'condition': (
lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_eixupdate_force') != 'skip' or
Get('cl_update_eixupdate_force') == 'force'))
},
{'name': 'sync_reps:cleanpkg',
'message': __("Removing obsolete distfiles and binary packages"),
'method': 'Update.cleanpkg()',
'condition': (lambda Get: Get('cl_update_cleanpkg_set') == 'on' and
Get('cl_update_outdate_set') == 'on'),
'essential': False
},
# сообщение удачного завершения при обновлении репозиториев
{'name': 'success_syncrep',
'message': __("Synchronization finished"),
'depend': (Tasks.success() & Tasks.has_any("sync_reps",
"sync_other_reps",
"emerge_metadata",
"eix_update")),
}
]
}, },
{'name': 'reps_synchronization', ] + get_synchronization_tasks("Update") + [
{'name': 'system_configuration',
'group': __("System configuration"), 'group': __("System configuration"),
'tasks': [ 'tasks': [
{'name': 'binhost_changed',
'method': 'Update.message_binhost_changed()'
},
{'name': 'revision', {'name': 'revision',
'message': __("Fixing the settings"), 'message': __("Fixing the settings"),
'method': 'Update.applyTemplates(install.cl_source,' 'method': 'Update.applyTemplates(install.cl_source,'
'cl_template_clt_set,True,None,False)', 'cl_template_clt_set,True,None,False)',
'condition': lambda Get: Get('cl_templates_locate') 'condition': lambda Get, GetBool: (Get('cl_templates_locate') and
}, (Get('cl_update_world') != "update" or
GetBool('cl_update_outdate_set') or
GetBool('cl_update_binhost_recheck_set') or
GetBool('cl_update_force_fix_set') or
GetBool('update.cl_update_package_cache_set')))
},
{'name': 'dispatch_conf', {'name': 'dispatch_conf',
'message': __("Updating configuration files"), 'message': __("Updating configuration files"),
'method':'Update.dispatchConf()', 'method': 'Update.dispatchConf()',
'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and 'condition': lambda Get, GetBool: (Get('cl_dispatch_conf') != 'skip' and
Get('cl_update_pretend_set') == 'off') Get('cl_update_pretend_set') == 'off' and
}, (GetBool('cl_update_outdate_set') or
GetBool('cl_update_binhost_recheck_set') or
GetBool('cl_update_force_fix_set') or
GetBool('update.cl_update_package_cache_set')))
},
] ]
} }
] + emerge_tasks + [ ] + emerge_tasks + [
{'name':'failed', {'name': 'check success configure',
'error':__("Update failed"), 'method': 'Update.check_success_configure()',
},
{'name': 'failed',
'error': __("Update failed"),
'depend': (Tasks.failed() & Tasks.hasnot("interrupt") & 'depend': (Tasks.failed() & Tasks.hasnot("interrupt") &
(Tasks.hasnot("check_schedule") | (Tasks.hasnot("check_schedule") |
Tasks.success_all("check_schedule")))}, Tasks.success_all("check_schedule")))},
{'name': 'failed', {'name': 'failed',
'depend': Tasks.failed_all("check_schedule") 'depend': Tasks.failed_all("check_schedule")
}, },
# сообщение удачного завершения при обновлении ревизии
{'name': 'drop_portage_hash',
'method': 'Update.drop_portage_state_hash()',
'depend': Tasks.failed()
},
{'name': 'drop_world_hash',
'method': 'Update.drop_world_state_hash()',
'depend': Tasks.failed()},
{'name': 'update:set_current_level',
'method': 'Update.update_increment_current_level()',
'depend': (Tasks.success() & Tasks.hasnot("interrupt") &
Tasks.success_all("update") & Tasks.hasnot("check_schedule")),
'condition': lambda Get: Get('cl_update_sync_only_set') == 'off' and
Get('cl_update_pretend_set') == 'off' and
Get('update.cl_update_use_migration_host') == 'on'
},
{'name': 'update_world:set_latest_tag',
'method': 'Update.update_set_current_saved_tag()',
'depend': (Tasks.success() & Tasks.hasnot("interrupt") &
Tasks.success_all("update") & Tasks.hasnot("check_schedule")),
'condition': lambda Get: Get('cl_update_sync_only_set') == 'off' and
Get('cl_update_pretend_set') == 'off',
'decoration': 'Update.update_task("%s")' % EmergeMark.SaveTag
},
{'name': 'update:save_portage_hash',
'method': 'Update.save_portage_state_hash()',
'condition': lambda Get: Get('cl_update_sync_only_set') == 'off'
},
{'name': 'update:save_world_hash',
'method': 'Update.save_world_state_hash()',
'condition': lambda Get: Get('cl_update_sync_only_set') == 'off'
},
{'name': 'clear_migration_host',
'method': 'Update.delete_binhost()',
'depend': (Tasks.hasnot("check_schedule")),
'condition': lambda Get: Get('update.cl_update_use_migration_host') == 'on'
},
# сообщение удачного завершения при обновлении ревизии # сообщение удачного завершения при обновлении ревизии
{'name': 'success_rev', {'name': 'success_rev',
'message': __("System update finished!"), 'message': __("System update finished!"),
'condition': lambda Get: (Get('cl_update_rev_set') == 'on' and 'condition': lambda Get: (Get('cl_update_rev_set') == 'on' and
Get('cl_update_pretend_set') == 'off') Get('cl_update_pretend_set') == 'off' and
}, Get('cl_update_sync_only_set') == 'off')
},
# сообщение удачного завершения при обновлении ревизии
{'name': 'success_sync_only',
'message': __("System sync finished!"),
'condition': lambda Get: (Get('cl_update_rev_set') == 'on' and
Get('cl_update_pretend_set') == 'off' and
Get('cl_update_sync_only_set') == 'on')
},
# сообщение удачного завершения при пересоздании world # сообщение удачного завершения при пересоздании world
{'name': 'success_world', {'name': 'success_world',
'message': __("World rebuild finished!"), 'message': __("World rebuild finished!"),
'condition': lambda Get: Get('cl_rebuild_world_set') == 'on' 'condition': lambda Get: Get('cl_rebuild_world_set') == 'on'
}, },
] ]

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -17,10 +17,13 @@
import sys import sys
from calculate.core.server.func import Action, Tasks from calculate.core.server.func import Action, Tasks
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.binhosts import BinhostError
from calculate.lib.utils.files import FilesError from calculate.lib.utils.files import FilesError
from calculate.update.update import UpdateError from ..update import UpdateError
from calculate.lib.utils.portage import GitError from calculate.lib.utils.git import GitError
_ = lambda x: x
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
@ -30,96 +33,76 @@ class ClUpdateProfileAction(Action):
Действие обновление конфигурационных файлов Действие обновление конфигурационных файлов
""" """
# ошибки, которые отображаются без подробностей # ошибки, которые отображаются без подробностей
native_error = (FilesError, UpdateError, GitError) native_error = (FilesError,
TemplatesError, BinhostError,
UpdateError, GitError)
successMessage = __("The profile was successfully updated") successMessage = __("The profile was successfully updated")
failedMessage = __("Failed to update the profile") failedMessage = __("Failed to update the profile")
interruptMessage = __("Profile update manually interrupted") interruptMessage = __("Profile update manually interrupted")
# список задач для действия
# список задач для дейсвия
tasks = [ tasks = [
{'name': 'migrate_repository', {'name': 'migrate_repository',
'method': 'Update.migrateCacheRepository(' 'method': 'Update.migrateCacheRepository('
'cl_update_profile_rep,cl_update_profile_branch)', 'cl_update_profile_url,cl_update_profile_branch,'
'message': __("Repository transfer"), 'cl_update_profile_storage)',
'condition': lambda Get: not ( 'condition': lambda Get: Get('cl_update_profile_url')},
Get('cl_update_profile_storage').is_local( {'name': 'profile_from_url',
Get('cl_update_profile_rep'), 'group': __('setting up from url'),
Get('cl_update_profile_branch')))
},
{'name': 'reconfigure_vars',
'method': 'Update.reconfigureProfileVars()'
},
{'name': 'reps_synchronization',
'group': __("Repositories synchronization"),
'tasks': [ 'tasks': [
{'name': 'sync_reps', {'message': __("Repository transfer"),
'foreach': 'cl_update_profile_sync_rep', 'condition': lambda Get: not (
'message': __("Syncing the {eachvar:capitalize} repository"), Get('cl_update_profile_storage').is_local(
'method': 'Update.syncRepositories(eachvar)', Get('cl_update_profile_url'),
#'condition': lambda Get: Get('cl_update_profile_sync_rep') Get('cl_update_profile_branch'))) and Get('cl_update_profile_check_sync_allowed'),
}, },
{'name': 'sync_reps:regen_cache', {'name': 'reconfigure_vars1',
'foreach': 'cl_update_sync_overlay_rep', 'method': 'Update.invalidateVariables("cl_update_profile_storage")',
'message': __("Updating the {eachvar:capitalize} repository cache"),
'essential': False,
'method': 'Update.regenCache(eachvar)',
'condition': (
lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_metadata_force') != 'skip' or
Get('cl_update_metadata_force') == 'force'))
}, },
{'name': 'emerge_metadata', {'name': 'check_datavars',
'message': __("Metadata transfer"), 'error': _("Profile not found in master"),
'method': 'Update.emergeMetadata()', 'condition': lambda Get: not Get('update.cl_update_profile_datavars'),
'condition': (
lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_metadata_force') != 'skip' or
Get('cl_update_metadata_force') == 'force'))
}, },
{'name': 'eix_update', {'name': 'drop_binhosts',
'message': __("Updating the eix cache"), 'method': 'Update.drop_binhosts(update.cl_update_profile_datavars)',
'method': 'Update.eixUpdate()',
'condition': (
lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_eixupdate_force') != 'skip' or
Get('cl_update_eixupdate_force') == 'force'))
}, },
# сообщение удачного завершения при обновлении репозиториев {'name': 'reconfigure_vars',
{'name': 'success_syncrep', 'method': 'Update.reconfigureProfileVars(cl_update_profile_datavars,'
'message': __("Synchronization finished"), 'cl_chroot_path)',
'depend': (Tasks.success() & Tasks.has_any("sync_reps", },
"sync_other_reps", ],
"emerge_metadata", 'depend': Tasks.has('migrate_repository')
"eix_update")), },
}
]
},
{'name': 'reps_synchronization', {'name': 'reps_synchronization',
'group': __("Setting up the profile"), 'group': __("Setting up the profile"),
'tasks': [ 'tasks': [
{'name': 'set_profile', {'name': 'set_profile',
'message': __("Switching to profile {cl_update_profile_system}"), 'message': __("Switching to profile {cl_update_profile_system}"),
'method': 'Update.setProfile()' 'method': 'Update.setProfile(cl_update_profile_system)'
}, },
{'name': 'revision', {'name': 'rename_custom',
'message': __("Fixing the settings"), 'method': 'Update.rename_custom_files()',
'method': 'Update.applyTemplates(install.cl_source,' },
'cl_template_clt_set,True,None,False)', {'name': 'revision',
'condition': lambda Get: Get('cl_templates_locate') 'message': __("Fixing the settings"),
}, 'method': 'Update.applyProfileTemplates(cl_template_clt_set,'
{'name': 'reconfigure', 'True,False,"update_profile")',
'message': __("The system is being configured"), 'condition': lambda Get: Get('cl_templates_locate')
'method': 'Update.applyProfileTemplates(cl_template_clt_set,True,False)', },
'condition': lambda Get: (Get('cl_update_templates_locate') {'name': 'reconfigure',
and Get('cl_update_skip_setup_set') == 'off') 'message': __("The system is being configured"),
}, 'method': 'Update.applyProfileTemplates(cl_template_clt_set,'
{'name': 'dispatch_conf', 'True,False,"merge")',
'message': __("Updating configuration files"), 'condition': lambda Get: (
'method':'Update.dispatchConf()', Get('cl_update_templates_locate') and
'condition': lambda Get: Get('cl_dispatch_conf') != 'skip' Get('cl_update_skip_setup_set') == 'off')
}, },
{'name': 'dispatch_conf',
'message': __("Updating configuration files"),
'method': 'Update.dispatchConf()',
'condition': lambda Get: Get('cl_dispatch_conf') != 'skip'
},
] ]
} }
] ]

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- #-*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import action from . import action
import update from . import update
section = "update" section = "update"

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2013-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,10 +14,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import sys import sys
from os import path from calculate.lib.datavars import ReadonlyVariable
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_update3',sys.modules[__name__]) setLocalTranslate('cl_update3',sys.modules[__name__])
@ -29,6 +27,7 @@ class VariableAcUpdateSync(ReadonlyVariable):
""" """
def get(self): def get(self):
action = self.Get("cl_action") action = self.Get("cl_action")
if action in ("sync", 'update_profile'): if action in ("sync", 'update_profile') and \
not self.Get('cl_merge_pkg'):
return "on" return "on"
return "off" return "off"

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -16,20 +16,22 @@
import sys import sys
from calculate.lib.datavars import VariableError,DataVarsError,DataVars from calculate.lib.datavars import VariableError,DataVarsError
from calculate.core.server.func import WsdlBase from calculate.core.server.func import WsdlBase
from calculate.install.install import InstallError from calculate.install.install import InstallError
from calculate.update.update import Update,UpdateError from .update import Update, UpdateError
from calculate.lib.utils.portage import GitError from calculate.lib.utils.git import GitError
from utils.cl_update import ClUpdateAction from .utils.cl_update import ClUpdateAction
from utils.cl_update_profile import ClUpdateProfileAction from .utils.cl_update_profile import ClUpdateProfileAction
from utils.cl_setup_update import ClSetupUpdateAction from .utils.cl_setup_update import ClSetupUpdateAction
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
setLocalTranslate('cl_update3',sys.modules[__name__])
setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
class Wsdl(WsdlBase): class Wsdl(WsdlBase):
methods = [ methods = [
# #
@ -63,23 +65,36 @@ class Wsdl(WsdlBase):
# описание груп (список лямбда функций) # описание груп (список лямбда функций)
'groups': [ 'groups': [
lambda group: group(_("Update the system"), lambda group: group(_("Update the system"),
normal=(), normal=(
'cl_update_binhost_stable_opt_set',
'cl_update_binhost_recheck_set',
'cl_update_with_bdeps_opt_set',
'cl_update_binhost_choice',
'cl_update_rep_hosting_choice',
),
expert=( expert=(
'cl_update_sync_only_set', 'cl_update_other_set',
'cl_update_other_set', 'cl_update_sync_only_set',
'cl_update_pretend_set', 'cl_update_pretend_set',
'cl_update_sync_rep', 'cl_update_sync_rep',
'cl_update_cleanpkg_set', 'cl_update_emergelist_set',
'cl_update_emergelist_set', 'cl_update_check_rep_set',
'cl_update_world', 'cl_update_force_fix_set',
'cl_update_egencache_force', 'cl_update_ignore_level',
'cl_update_eixupdate_force', 'cl_update_force_level',
'cl_update_wait_another_set', 'cl_update_world',
'cl_update_branch', 'cl_update_gpg_force',
'cl_update_autocheck_schedule_set', 'cl_update_egencache_force',
'cl_templates_locate', 'cl_update_eixupdate_force',
'cl_verbose_set', 'cl_dispatch_conf'), 'cl_update_revdep_rebuild_set',
next_label=_("Perform"))]}, 'cl_update_wait_another_set',
'cl_update_autocheck_schedule_set',
'cl_update_onedepth_set',
'cl_update_cleanpkg_set',
'cl_update_branch_data',
'cl_templates_locate',
'cl_verbose_set', 'cl_dispatch_conf'),
next_label=_("Run"))]},
# #
# Сменить профиль # Сменить профиль
# #
@ -91,7 +106,9 @@ class Wsdl(WsdlBase):
# заголовок метода # заголовок метода
'title': __("Change the Profile"), 'title': __("Change the Profile"),
# иконка для графической консоли # иконка для графической консоли
'image': 'extension', 'image': 'calculate-update-profile,'
'notification-display-brightness-full,gtk-dialog-info,'
'help-hint',
# метод присутствует в графической консоли # метод присутствует в графической консоли
'gui': True, 'gui': True,
# консольная команда # консольная команда
@ -107,16 +124,15 @@ class Wsdl(WsdlBase):
'native_error': (VariableError, DataVarsError, 'native_error': (VariableError, DataVarsError,
InstallError, UpdateError, GitError), InstallError, UpdateError, GitError),
# значения по умолчанию для переменных этого метода # значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'update_profile'}, 'setvars': {'cl_action!': 'update_profile', 'cl_update_world_default': "rebuild"},
# описание груп (список лямбда функций) # описание груп (список лямбда функций)
'groups': [ 'groups': [
lambda group: group(_("Repository"), lambda group: group(_("Repository"),
brief=('cl_update_profile_repo_name',), brief=('cl_update_profile_repo_name',),
hide=('cl_update_profile_rep', hide=('cl_update_profile_url',
'cl_update_profile_sync_set'), 'cl_update_profile_sync_set'),
normal=('cl_update_profile_rep',), normal=('cl_update_profile_url',),
expert=('cl_update_profile_sync_set', expert=('cl_update_profile_sync_set',)),
'cl_update_profile_branch')),
lambda group: group(_("Profile"), lambda group: group(_("Profile"),
normal=('cl_update_profile_system', normal=('cl_update_profile_system',
'cl_update_world'), 'cl_update_world'),
@ -131,7 +147,7 @@ class Wsdl(WsdlBase):
'cl_update_profile_linux_fullname', 'cl_update_profile_linux_fullname',
'cl_update_profile_depend_data') 'cl_update_profile_depend_data')
)], )],
'brief': {'next': __("Perform"), 'brief': {'next': __("Run"),
'name': __("Set the profile")}}, 'name': __("Set the profile")}},
# #
# Настроить автопроверку обновлений # Настроить автопроверку обновлений
@ -142,15 +158,15 @@ class Wsdl(WsdlBase):
# категория метода # категория метода
'category': __('Configuration'), 'category': __('Configuration'),
# заголовок метода # заголовок метода
'title': __("The Update Check"), 'title': __("Update Check"),
# иконка для графической консоли # иконка для графической консоли
'image': 'software-properties,preferences-desktop', 'image': 'calculate-setup-update,software-properties,preferences-desktop',
# метод присутствует в графической консоли # метод присутствует в графической консоли
'gui': True, 'gui': True,
# консольная команда # консольная команда
'command': 'cl-setup-update', 'command': 'cl-setup-update',
# права для запуска метода # права для запуска метода
'rights': ['update'], 'rights': ['setup_update'],
# объект содержащий модули для действия # объект содержащий модули для действия
'logic': {'Update': Update}, 'logic': {'Update': Update},
# описание действия # описание действия

@ -3,7 +3,7 @@
# setup.py --- Setup script for calculate-update # setup.py --- Setup script for calculate-update
# Copyright 2012 Calculate Ltd. http://www.calculate-linux.org # Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -18,14 +18,56 @@
# limitations under the License. # limitations under the License.
__app__ = "calculate-update" __app__ = "calculate-update"
__version__ = "3.2.2" __version__ = "3.7.3" #TODO bump version
import os import os
from glob import glob from glob import glob
from distutils.core import setup from distutils.core import setup
from calculate.install_data import install_data from distutils.command import install_data as module_install_data
from distutils.util import change_root, convert_path
data_files = [('/usr/libexec/calculate', [('data/cl-git-wrapper', 0755)])] class install_data(module_install_data.install_data):
def run (self):
self.mkpath(self.install_dir)
for f in self.data_files:
if isinstance(f, str):
# it's a simple file, so copy it
f = convert_path(f)
if self.warn_dir:
self.warn("setup script did not provide a directory for "
"'%s' -- installing right in '%s'" %
(f, self.install_dir))
(out, _) = self.copy_file(f, self.install_dir)
self.outfiles.append(out)
else:
# it's a tuple with path to install to and a list of files
dir = convert_path(f[0])
if not os.path.isabs(dir):
dir = os.path.join(self.install_dir, dir)
elif self.root:
dir = change_root(self.root, dir)
self.mkpath(dir)
if f[1] == []:
# If there are no files listed, the user must be
# trying to create an empty directory, so add the
# directory to the list of output files.
self.outfiles.append(dir)
else:
# Copy files, adding them to the list of output files.
for data in f[1]:
# is's a simple filename without chmod
if isinstance(data,str):
chmod = None
else:
data, chmod = data
data = convert_path(data)
(out, _) = self.copy_file(data, dir)
if chmod and os.stat(out).st_mode != chmod:
os.chmod(out,chmod)
self.outfiles.append(out)
data_files = [('/usr/libexec/calculate', [('data/cl-git-wrapper', 0o755)])]
packages = [ packages = [
"calculate."+str('.'.join(root.split(os.sep)[1:])) "calculate."+str('.'.join(root.split(os.sep)[1:]))

Loading…
Cancel
Save