Compare commits

...

264 Commits

Author SHA1 Message Date
Павел Иванов df262fa4d5 fix: Установка UEFI
3 months ago
Павел Иванов 210b51ee82 TG-532 fix PXE install
3 months ago
Павел Иванов 724985edb4 TG-392 Установка в раздел EFI
8 months ago
Павел Иванов ecac76290b TG-392 Установка системы на раздел EFI
8 months ago
root 40c800dc00 TG-230
1 year ago
root 397ac25381 Удаление 686
1 year ago
root 3e7f20f4ce TG-199
1 year ago
root d9c5771203 TG-195
1 year ago
root cdd9fbd751 TG-195
1 year ago
root f9ebdb892b Fix: изменение текста ненадежного пароля
1 year ago
root bd7a6e1973 TG-195
1 year ago
root e05cf14133 TG-174
1 year ago
root 45289a8516 TG-121
1 year ago
root ef5d75f040 Merge branch 'master' of https://git.calculate-linux.org/calculate/calculate-utils-3-install
1 year ago
root 0882d2e27b TG-121
1 year ago
Alexander Tratsevskiy a92d5a7d02 Update live handbook
1 year ago
root 0dabba6a6e TG-4
1 year ago
root 4330087bf3 Feature: fglrx removed from default list
1 year ago
Павел Иванов 47cfc98f11 Добавлена поддерка нового пути к портежам
2 years ago
Павел Иванов 35bb751fb5 Удалено условие выбора директории портежей
2 years ago
Павел Иванов 148f26ba66 Перенос /usr/portage в /var/db/repos/gentoo
2 years ago
Павел Иванов c0e1c32534 Fix: nvidia 470 booting
2 years ago
idziubenko fcab4a2780 added error case to installFbResolution
2 years ago
idziubenko 90c9d3dfd0 fixed server bootstrap on livecd
2 years ago
Alexander Tratsevskiy f471b47479 Do not configure calculate server on the first booting from the lxc
2 years ago
idziubenko 8936df0cf5 Fix: added /run to mounted dirs (builder)
2 years ago
idziubenko 2747fe8077 FIX: removed space_cache from btrfs fstab
2 years ago
idziubenko 49350af92d FIX: added exception when utilities can't get MType of iso
2 years ago
idziubenko 1a790afba7 FEAT: added local to depend for init.d/calculate
2 years ago
idziubenko 4528551f32 FEAT: cl-install now migrates machine-id
2 years ago
idziubenko c3c87d13ef added system error code for failed install due to build already present
2 years ago
idziubenko 77aea752b4 added exception for .old files in .ssh
2 years ago
idziubenko 8e8453f725 reverted ext4 fast_commit
3 years ago
idziubenko f97577dc16 Merge branch 'master' of git.calculate-linux.org:calculate/calculate-utils-3-install
3 years ago
idziubenko 32ed578925 added ext4 fast_commit option
3 years ago
Alexander Tratsevskiy ed525321e0 Removed discard mount option
3 years ago
idziubenko 9aeab9e184 fixed cl-video-install newline return
3 years ago
idzuibenko c6de0c9ec8 swapped PulseAudio for PipeWire
3 years ago
idzuibenko 7bd8f1bf17 removed undefined variable from nvidia get_legacy
3 years ago
idzuibenko 01cd79f702 fixed ip routes, removed maps
3 years ago
idzuibenko 7965493b9b loading bar now limited to 100%
3 years ago
Иван Дзюбенко fb8b83bdf4 fixed extcomparator
3 years ago
Иван Дзюбенко 6ef7e912f3 fixed zip related bugs (notably in install grub uefi)
3 years ago
Иван Дзюбенко b5993c5616 fixed encoding in timezone variables
3 years ago
idziubenko 53c76fde3a fixed build compare
3 years ago
idziubenko dcc9cb852d fixed cl-install flash
3 years ago
idziubenko 667112d919 fixed pipe encoding
3 years ago
idziubenko 9cda6d8384 fixed migrate users
3 years ago
idziubenko 4a14d64240 fixed division operations
3 years ago
idziubenko 1b187a1844 fixed clImagePath
3 years ago
idziubenko 9a2462c120 fixed hashing
3 years ago
idziubenko 49f760d3ee imports to relative
3 years ago
idziubenko b23b15293a Merge branch 'py3_forced'
3 years ago
idziubenko f30a4133f0 general py3 changes, regex fixes
3 years ago
idziubenko 57df4358f0 fixed old sorting function, modernized classes
3 years ago
idziubenko 545a3a583c added more list compr, general py3 changes
3 years ago
idziubenko aa3120cec2 replaced filters/maps with list comprehensions
3 years ago
idziubenko 072415613f more datavars fixes
3 years ago
idziubenko b1a5dc6e64 Py3 changes
3 years ago
Хирецкий Михаил 359e71ccae Fix setup.py
3 years ago
idziubenko 409534d108 i
3 years ago
Хирецкий Михаил d8c14903e9 Добавлена маскировка nvidia-drivers через calculate/ini.env
3 years ago
Хирецкий Михаил ad9a1a1cc9 Изменена настройка alsa volume
3 years ago
Хирецкий Михаил 9a85da3620 Добавлена поддержка f2fs
3 years ago
Хирецкий Михаил db3766eaa2 Исправлен выбор групп на CSS
3 years ago
Хирецкий Михаил 031a92dc28 Remove xdm before init.d/calculate
3 years ago
Хирецкий Михаил b686761529 Исправлено прописывание маски nvidia при первой загрузке
3 years ago
Хирецкий Михаил 8a79c02363 Изменён приоритет при определении текущего видеодрайвера
3 years ago
Хирецкий Михаил 0d2de67f8e Исправлена последовательность запуска (после display-manager)
3 years ago
Хирецкий Михаил d3440bc46d Добавлена переменная предпочтения файловых систем, предпочитаемой файловой системой назначена Btrfs
3 years ago
Хирецкий Михаил 5f9cd36e2d Добавлена возможность указывать степень сжатия btrfs через переменную
3 years ago
Хирецкий Михаил 144ca153cd Исправлена маскировка nvidia-drivers в зависимости от ID карты
3 years ago
Хирецкий Михаил e62d86880c Изменена установка на btrfs с сжатием
3 years ago
Хирецкий Михаил fc2e151e92 Добавлен часовой пояс Europe/Athens
3 years ago
Хирецкий Михаил 182b67f61c Добавлено округление при проверке размера bios_boot (2)
3 years ago
Хирецкий Михаил 227eb8a9fc Добавлено округление при проверке размера bios_boot
3 years ago
Хирецкий Михаил b960214b41 Исправлена ошибка сообщающая о примонтировании устройства без названия.
3 years ago
Хирецкий Михаил 2bb1d2a559 Исправлено вычисление переменных Kernel
3 years ago
Хирецкий Михаил 0b621dd63d Удалена настройка OpenGL через "eselect opengl"
3 years ago
Хирецкий Михаил 53e42d8282 Добавлена возможность выбора nvidia драйвера
3 years ago
Хирецкий Михаил c9bfd00424 Исправлено использование swap раздела для гибернации
3 years ago
Хирецкий Михаил 3c6df3681a Исправлено монтирование многослойной файловой системы при сборке
3 years ago
Хирецкий Михаил 6aaa79f03a Добавлена переменная cl_install_scaling, для указания hi, как увеличенного размера интерфейса
4 years ago
Хирецкий Михаил 0ed841e079 Add EDID variables and DPI
4 years ago
Хирецкий Михаил 377f714b9d Исправлена опечатка в handbook
4 years ago
Хирецкий Михаил 2f64c6a65f Добавлена попытка отключения устройств на которые будет ставиться система если используется параметр --force
4 years ago
Хирецкий Михаил 8787048376 Добавлена проверка на примонтированные разделы диска используемого для авторазметки
4 years ago
Хирецкий Михаил ba8c6fd336 Исправлена неправильное описание ошибки при попытке выбрать DOS таблицу и UEFI
4 years ago
Хирецкий Михаил e806d8e3a8 Исправлено разворачивание сборки на flash дистрибутивах
4 years ago
Хирецкий Михаил e6fcfca66a Remove swap partition for autopartition by default.
4 years ago
Хирецкий Михаил 3eb455e8dd Исправлена установка nvidia во время загрузки системы
4 years ago
Хирецкий Михаил a6e33a1357 PulseAudio по умолчанию
4 years ago
Хирецкий Михаил ab6b6d60a7 Добавлена возможность выбрать vesa драйвер из списка --video
4 years ago
Хирецкий Михаил c0b561bd13 lpadmin добавлен в список групп по умолчанию
4 years ago
Хирецкий Михаил 618d3a6d1e Исправлена установка PXE, и настройка live PXE
4 years ago
Хирецкий Михаил fcab3a6529 Добавлено сообщение "no" если загрузчик не устанавливается
4 years ago
Хирецкий Михаил 21cb6ac55b Добавлен перенос параметра загрузки ядра nomodeset
4 years ago
Хирецкий Михаил 9389352c6e Добавлена проверка наличия утилиты форматирования при выборе файловой системы для авторазметки
4 years ago
Хирецкий Михаил a088646cd1 Добавлено обновление списка правил для udev во вермя init.d/calculate
4 years ago
Хирецкий Михаил e9f463d419 Убрана wheel группа из списка по умолчанию
4 years ago
Хирецкий Михаил b4481e9d06 Добавлена переменная ac_install_config
4 years ago
Хирецкий Михаил e458e974f5 Добавлена переменная для определения типа MAC адреса
4 years ago
Хирецкий Михаил 57f32415b5 Добавлена переменная для определения типа сетевого интерфейса eth или wlan
4 years ago
Хирецкий Михаил b14ab8b647 Изменено вычисление значения по умолчанию для параметра "-D"
4 years ago
Хирецкий Михаил 79a4b7fb0b Add python and lib variables
4 years ago
Хирецкий Михаил 415845d370 --calculate-fs -> --data-fs
5 years ago
Хирецкий Михаил aff13dbe8f Добавлена возможность выборка modesetting видеодрайвера
5 years ago
Хирецкий Михаил b907d2c099 Добавлена поддержка Gentoo профиля 17.1
5 years ago
Хирецкий Михаил 9f14bb48e0 Изменено сообщение при необходимости ввести пароль пользователя
5 years ago
Хирецкий Михаил a7ac43c132 Добавлена возможность выбора разрешения FB
5 years ago
Хирецкий Михаил 5cf9f16ad6 Calculate раздел переименован в "Раздел для данных"
5 years ago
Хирецкий Михаил 749af0fdca Добавлена проверка на своп нулевого размера
5 years ago
Хирецкий Михаил b713311583 Изменён минимальный размер раздела BIOS boot
5 years ago
Хирецкий Михаил 226c4636bd Для переменной cl_splash_image_hash добавлен учёт изменений plymouth
5 years ago
Хирецкий Михаил 003ff5d128 Добавлен параметр для установки системы для обновления пакетов при первой загрузке
5 years ago
Хирецкий Михаил 4aaf71035e Исправлен импорт модуля
5 years ago
Хирецкий Михаил 2ca357b2c9 Исправлено использование уже отформатированных разделов
5 years ago
Хирецкий Михаил 420b9b27b2 Добавлена возможность выбора файловой системы для корня и данных при авторазметке
5 years ago
Хирецкий Михаил eeb361db80 Рефакторинг: работа с файлами
5 years ago
Хирецкий Михаил dd56b3dab0 Рефакторинг: работа с файлами
5 years ago
Хирецкий Михаил e4fa7c25b2 Изменён выбора файловой системы по умолчанию
5 years ago
Хирецкий Михаил 637ef24386 btrfs-comp переименован в btrfs-compress
5 years ago
Хирецкий Михаил b5635a3a6a Исправлен синтаксис
5 years ago
Хирецкий Михаил 06d93fbccc Добавлена проверка на устновку значения для cl_autopartiton_default_format
5 years ago
Хирецкий Михаил ae4acc744f Исключён из сжатия btrfs /var/calculate/linux и linux пути
5 years ago
Хирецкий Михаил e0cddd5831 Добавлен путь отключения сжатия btrfs для grub, исправлено формирование fstab
5 years ago
Хирецкий Михаил 74f24e86be Исправлено монтирование btrfs-comp
5 years ago
Хирецкий Михаил e76ea7985f Исправлена возможность выбора файловой системы при авторазметке
5 years ago
Хирецкий Михаил 5c2d6cfee0 Добавлена возможность ставить систему на btrfs с сжатием
5 years ago
Хирецкий Михаил 15e747257a Изменено вычисление переменной os_install_clock_type
5 years ago
Хирецкий Михаил 73f15496f2 Исправлено вычисление корня при авторазметке
5 years ago
Хирецкий Михаил b109623110 Удалена ссылка на IRC чат в русской справке на livecd
6 years ago
Хирецкий Михаил 8065b1ecb2 Исправлено определение os_chrootable_set
6 years ago
Хирецкий Михаил 96be7db2ab Заблокирована попытка уставновки дистрибутива в который нельзя выполнить chroot
6 years ago
Хирецкий Михаил cdd5e1c3f4 Изменёно выполнение grub-install
6 years ago
Хирецкий Михаил d6851726f2 Изменена проверка достпности записи в /run
6 years ago
Хирецкий Михаил fa37b9bbe3 Добавлены комментарии
6 years ago
Хирецкий Михаил cebf7ebea2 Исправлен запуск cl-install в readonly системе
6 years ago
Хирецкий Михаил 7cae9b9073 При установке системы chroot_status задаётся принудительно
6 years ago
Хирецкий Михаил 1b87cd19e7 Добавлена поддержка initramfs с early microcode
6 years ago
Хирецкий Михаил 2e67de479d ALSA по умолчанию
6 years ago
Хирецкий Михаил 1f0b7ed156 Исправлено вычисление звуковых переменных при отсутствии звуковых карт
6 years ago
Хирецкий Михаил c621888a53 Добавлены переменные для настройки asound.conf через идентификаторы карт
6 years ago
Хирецкий Михаил f39b0b2756 Исправлена установка на xfs с отдельным /boot
6 years ago
Хирецкий Михаил 648665965d Исправлена установка системы на xfs раздел
6 years ago
Хирецкий Михаил 60d75fc48b Изменено сообщение об ошибке при выборке EFI, изменено определение использования EFI раздела
6 years ago
Хирецкий Михаил 94060a2e4f Обновлён handbook
6 years ago
Хирецкий Михаил bbb69e5e50 Изменена установка nvidia-drivers во вермя загрузки системы
6 years ago
Хирецкий Михаил d006b91da3 Исключены двойное описание маршрута на один и тот же адрес
6 years ago
Хирецкий Михаил 0bc330ee9e Добавлена возможность настройки типа аппаратных часов (локальное время или UTC)
6 years ago
Хирецкий Михаил dda9e6d7f7 Исправлен перенос текущих пользователей при установке системы
6 years ago
Хирецкий Михаил 1dda7569dc Исправлена проверка переключения OpenGL
6 years ago
Хирецкий Михаил 8a7c7896cd Добавлена возможность выбора раскладки отдельно от локали
6 years ago
Хирецкий Михаил b75cb75f72 Изменена логика авторазметки
6 years ago
Хирецкий Михаил 688c332ad4 Исправлена инициализация сети при первой загрузке
6 years ago
Хирецкий Михаил 25cb9f28b5 Испралена настройка сети при первой загрузке и livecd
6 years ago
Хирецкий Михаил e0fad90a71 Merge remote-tracking branch 'origin/master-3.5'
6 years ago
Хирецкий Михаил ce76550392 Исправлен выбор разрешения для фреймбуфера в UEFI
6 years ago
Хирецкий Михаил 71197caada Удалена переменная для выбора framebuffer разрешения из cl-setup-video
6 years ago
Хирецкий Михаил b9539958a7 Изменён алгоритм получения текущего разрешения для X
6 years ago
Хирецкий Михаил 75cd00ab4b Изменён алгоритм вычисление разрешения для фреймбуффера
6 years ago
Хирецкий Михаил fb50c709e9 Отказ от вычисления разрешения framebuffer
6 years ago
Хирецкий Михаил 8f187edb86 Исправлен скрипт загрузки системы для lxc (merge with origin/master-3.5)
6 years ago
Хирецкий Михаил 64cb021046 Добавлено восстановление file capabilities по файлу описанию
6 years ago
Хирецкий Михаил b7f58754c2 Добавлен запуск calculate в lxc, исправлена настройка сети
6 years ago
Хирецкий Михаил 5575c18520 Изменена инициализация системы для lxc и livecd
6 years ago
Хирецкий Михаил f0cfadc55f Синхронзиация переводов
6 years ago
Хирецкий Михаил e2883a46b9 Удалёно обнволение зависимостей запуска в init.d/calculate если это не live
6 years ago
Хирецкий Михаил b8c38a7aa2 Изменены параметры для настройки сети и авторазметки
6 years ago
Хирецкий Михаил 264c8a66e5 Исправлен параметр alsa и x11
6 years ago
Хирецкий Михаил 0dbc20ab5b Исправлен параметр --route
6 years ago
Хирецкий Михаил 41158e98a2 Удалён вызов смены IO планировщика при cl-setup-boot
6 years ago
Хирецкий Михаил 5f0d019ae2 Удалён параметр настройка IO планировщика
6 years ago
Хирецкий Михаил 114184b7f6 Включен composite для amdgpu по умолчанию
6 years ago
Хирецкий Михаил 8bc147a172 Обновление фраз
7 years ago
Хирецкий Михаил f041dcbed3 Обновлены фразы
7 years ago
Хирецкий Михаил 14c755b269 Изменена таблица точек монтирования, выводимая перед установкой
7 years ago
Хирецкий Михаил d6da45321d Исправлено определение дисков из которых состоит RAID при определении IO планировщика
7 years ago
Хирецкий Михаил ee1d077076 Добавлено определение QEMU виртуальных дисков
7 years ago
Хирецкий Михаил 6687f99bca Исправлно проверка устройства, на которое ставится система как на Flash
7 years ago
Хирецкий Михаил 626209b32e Исправлено определение flash устройства
7 years ago
Хирецкий Михаил 167ab9c10e Исправлено использование методов модуля distr
7 years ago
Хирецкий Михаил 6e85862f33 Remove outdated code
7 years ago
Хирецкий Михаил 7fb3663fd3 Исправлено определение необходимости обновление nvram записи
7 years ago
Хирецкий Михаил cf60ba8800 Изменено алгоритм определения EFI разделов для авторазметки
7 years ago
Хирецкий Михаил d5f0a80358 Добавлена обрабока ошибок при авторазметке
7 years ago
Хирецкий Михаил 90f4296883 Изменён вид списка устройств для авторазметки
7 years ago
Хирецкий Михаил 221f24d6ff Изменена проверка совместимости --uefi и --mbr
7 years ago
Хирецкий Михаил a62401e819 Исправлен список устройств для установки mbr
7 years ago
Хирецкий Михаил b09e4e3dfa Исправлен порядок загрузки efi при raid
7 years ago
Хирецкий Михаил eebef51733 Исправлено определение parent устройства для авторазметки на RAID.
7 years ago
Хирецкий Михаил e9674b84c9 Изменена установка системы с EFI загрузчиком
7 years ago
Хирецкий Михаил 2b1868217d Рефакторинг
7 years ago
Хирецкий Михаил 3838464b11 Исправлены переменные cl_autopartition_disk_size, cl_autopartition_disk_size_full
7 years ago
Хирецкий Михаил 71b6a05939 Добавлено ожидание устройств при авторазметке
7 years ago
Хирецкий Михаил e7cefcd6e2 Добавлена обработка ошибок при создании разделов в авторазметке
7 years ago
Хирецкий Михаил 2682389436 Рефакторинг. Удаление неиспользуемого кода.
7 years ago
Хирецкий Михаил 23a5389c01 Добавлены проверки использования дисков для разметки
7 years ago
Хирецкий Михаил 24712fc9f1 Переписан модуль авторазметки
7 years ago
Хирецкий Михаил 89630bbfaf Изменено содержимое os_disk_parent
7 years ago
Хирецкий Михаил 2716260626 Рефакторинг
7 years ago
Хирецкий Михаил b1e46276fd Использование calculate-lib:Lvm
7 years ago
Хирецкий Михаил fa3b455d1f Рефакторинг
7 years ago
Хирецкий Михаил d9e1f446a1 Рефакторинг
7 years ago
Хирецкий Михаил 918c262f92 Рефакторинг. Вынос логики чтения /sys через отдельный класс.
7 years ago
Хирецкий Михаил 9570bea5ef Обновление вызовов в связи с рефакторингом calculate-lib LVM
7 years ago
Хирецкий Михаил 51b1432365 Обновление вызовов в связи с рефакторингом calculate-lib getUdevDeviceInfo
7 years ago
Хирецкий Михаил bc6c1a7ad2 Изменены опции загрузки dracut
7 years ago
Хирецкий Михаил 0e7fd021fb Исправлена миграция пользователей. (установка без пользователей)
7 years ago
Хирецкий Михаил d4fcc11fa2 Исправлен выбор групп для пользователя
7 years ago
Хирецкий Михаил 6268b21371 Удалена проверка при установки btrfs и dos
7 years ago
Хирецкий Михаил a592279cd0 Добавлена сортировка групп пользователя
7 years ago
Хирецкий Михаил ca49100504 Исправлено фразы
7 years ago
Хирецкий Михаил 319f9a2aec Исправлен выбор типа администратора для пользователя
7 years ago
Хирецкий Михаил 796438c279 Исправлен вызов cl-core для удаления локальных сертификатов
7 years ago
Хирецкий Михаил 81c01ae826 Обновлены значения для переменной миграции пользователей
7 years ago
Хирецкий Михаил 0f97259c1e Переименование значений переменных
7 years ago
Хирецкий Михаил edf3cbefc3 Исправлена миграция пользователей
7 years ago
Хирецкий Михаил 5061936d63 Добавлена настройка админов в устанавливаемую систему (2)
7 years ago
Хирецкий Михаил 96cf2427da Добавление guest в администраторы на livecd
7 years ago
Хирецкий Михаил 3280fab3a6 Исправлен init.d/calculate для настройки livecd
7 years ago
Хирецкий Михаил a26ddfc631 Исправлены поля выбора роли пользователя
7 years ago
Хирецкий Михаил f65739b4d3 Добавлена настройка админов в устанавливаемую систему
7 years ago
Хирецкий Михаил ec53b8a92a Добавлена настройка calculate-core при первой загрузке в init.d/calculate
7 years ago
Хирецкий Михаил e9ccb9d503 Модифицирован init.d/calculate
7 years ago
Хирецкий Михаил 1aff0b033f Добавлена возможность указывать пользователей администраторов
7 years ago
Хирецкий Михаил f6ac3b645e Исправлено указание сетевых маршрутов через cl-setup-network --route
7 years ago
Хирецкий Михаил 8ce1811d0e Отключена возможность установки системы из контейнеров
7 years ago
Хирецкий Михаил 2831d89668 Добавлена поддержка дистрибутива контейнер типа
7 years ago
Хирецкий Михаил 9bd75ef654 Исключение запуска в контейнере init.d/calculate
7 years ago
Хирецкий Михаил ecd210d899 Исправлен скрипт автовхода пользователя в Xorg сервере сеанс
7 years ago
Хирецкий Михаил c1ec3af29b Исправлены сообщения об ошибке
7 years ago
Хирецкий Михаил b9f5aad68e Исправлено изменение параметра use grub password при переустановке
7 years ago
Хирецкий Михаил f4f2940738 Пароль на grub по умолчанию для livecd
7 years ago
Хирецкий Михаил 19ef16d129 Переименованы параметры
7 years ago
Хирецкий Михаил 1ca4d18ad6 Исправлено определение наличия пароля root
7 years ago
Хирецкий Михаил 4156f6dd4b Исправлен работа с паролем root из shadow (поддержка только sha256)
7 years ago
Хирецкий Михаил fda9d5c48e Поддержка пароля для grub
7 years ago
Хирецкий Михаил 8c285d2792 Добавлена переменная os_install_x11_resolution_preferred
7 years ago
Хирецкий Михаил 1eba78b7ac Удалено повторное внесение загрузочной записи в nv-ram, если её параметры не менялись
7 years ago
Хирецкий Михаил c23191fa01 Оптимизирован алгоритм опредления изменений темы grub и splash
7 years ago
Хирецкий Михаил 5d2da6a18b Добавлена команда cl-setup-themes и переменные для её работы
7 years ago
Хирецкий Михаил 6ad5e6ad3a Исправлена установка на flash
7 years ago
Хирецкий Михаил 1afc8d5732 Исправлена создание пользовательской директории
7 years ago
Хирецкий Михаил ebff48f9d3 Исправлены права на homedir при создании guest
7 years ago
Хирецкий Михаил 1d8e753d89 Отключено создание bios_grub раздела авторазметкой с UEFI установкой
7 years ago
Хирецкий Михаил 95720642a5 Исправлена авторазметка по умолчанию для livecd
7 years ago
Хирецкий Михаил 74cc73cb63 Исправлена проверка наличия настроенного утилитами DHCP сервера
7 years ago
Хирецкий Михаил 3ac3478644 Включена авторазметка по умолчанию для установки системы с livecd
7 years ago
Хирецкий Михаил b2ea124cb8 Изменён вывод списка звуковых карт,устройств
7 years ago
Хирецкий Михаил ead5a0351c Добавлена обработка параметра /proc/cmdline calculate=audio:alsa
7 years ago
Хирецкий Михаил cc89cfb5b0 English update
8 years ago
Хирецкий Михаил 204edf162f Исправлена смена видеодрайвера
8 years ago
Хирецкий Михаил b156c6dade --audio-card -> --card
8 years ago
Хирецкий Михаил 8b13f20d67 Исправлена звуковая переменная (отображалась только последняя карта)
8 years ago
Хирецкий Михаил 158fe56af6 Изменён формат переменных os_audio_
8 years ago
Хирецкий Михаил a2879751ce Скрыты для отображаения параметры авторазметки root size, swap size
8 years ago
Хирецкий Михаил a2d822cf7f Добавлена переменная содержащая версию ядра в /usr/src/linux и
8 years ago
Хирецкий Михаил 52cd2e9c68 Запрет на " " в имени хоста
8 years ago
Хирецкий Михаил ae74fbcd31 Добавлена переменная cl_install_kernel_build для сборки нескольких ядер
8 years ago
Хирецкий Михаил 8cd503b289 Merge remote-tracking branch 'origin/master3.4'
8 years ago
Хирецкий Михаил 2072dd4b31 Обновлены иконки
8 years ago
Хирецкий Михаил 287e88695f Merge remote-tracking branch 'origin/master3.4'
8 years ago
Хирецкий Михаил 9dd4fd602e Подготовка к alpha
8 years ago

6
.gitignore vendored

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

@ -21,6 +21,8 @@ TTYNUM=${2:-7}
DISPLAYNUM=${3:-\:0}
MAINLOOP=1
XDMCMD=/usr/share/calculate/xdm/xdm
# write pid for init.d/xdm (detect X for this xautologin)
echo $BASHPID >/var/run/bash.pid
@ -94,7 +96,10 @@ do
XPID=$!
if waitX ${DISPLAYNUM}
then
env USER=${XUSER} /usr/share/calculate/xdm/xdm --login || break
if [[ -e ${XDMCMD} ]]
then
env USER=${XUSER} ${XDMCMD} --login || break
fi
# write pam enviroment for pam_ck_connector
cat >/home/${XUSER}/.pam_environment <<EOF
CKCON_DISPLAY_DEVICE=
@ -132,7 +137,10 @@ source /usr/bin/startx' &
then
sleep $WAITRELOGIN
fi
env USER=${XUSER} /usr/share/calculate/xdm/xdm --logout
if [[ -e ${XDMCMD} ]]
then
env USER=${XUSER} ${XDMCMD} --logout
fi
fi
[[ -n $XPID ]] && kill $XPID
wait $XPID

@ -17,15 +17,20 @@ CL_VIDEO_INSTALL=/usr/libexec/calculate/cl-video-install
depend() {
need localmount root fsck modules
before keymaps consolefont dbus xdm
before keymaps consolefont dbus display-manager local
use swap hostname
keyword -timeout
keyword -timeout -docker -systemd-nspawn -vserver
}
check_install_ability()
{
local pkg=$1
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles emerge -fq $pkg &>/dev/null
if [[ -d "/var/db/repos/gentoo" ]]
then
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/var/calculate/distfiles emerge -fq $pkg &>/dev/null
else
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles emerge -fq $pkg &>/dev/null
fi
}
is_already_install()
@ -41,15 +46,26 @@ install_pkg()
{
local pkg=$1
ebegin "Installing $pkg"
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles emerge $pkg &>/dev/null
if [[ -d "/var/db/repos/gentoo" ]]
then
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/var/calculate/distfiles emerge $pkg &>/dev/null
else
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles emerge $pkg &>/dev/null
fi
}
new_install_pkg()
{
local pkg=$1
local mask=$2
pkg=`echo $pkg | cut -d\/ -f2`
ebegin "Installing $pkg"
FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles PKGDIR=/usr/portage/packages ${CL_VIDEO_INSTALL} $pkg &>/dev/null
if [[ -d "/var/db/repos/gentoo" ]]
then
FETCHCOMMAND=false DISTDIR=/var/calculate/distfiles PKGDIR=/var/calculate/packages ${CL_VIDEO_INSTALL} $pkg $mask &>/dev/null
else
FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles PKGDIR=/usr/portage/packages ${CL_VIDEO_INSTALL} $pkg $mask &>/dev/null
fi
eend $?
}
@ -68,8 +84,11 @@ install_video_driver()
;;
nvidia)
local nvidiamask=`variable_value install.os_nvidia_mask`
[[ -n $nvidiamask ]] && \
if [[ -n $nvidiamask ]]
then
[[ -d /etc/portage/package.mask ]] || mkdir /etc/portage/package.mask
echo $nvidiamask >/etc/portage/package.mask/nvidia
fi
local drv="x11-drivers/nvidia-drivers"
;;
*)
@ -82,7 +101,7 @@ install_video_driver()
then
if [[ -x ${CL_VIDEO_INSTALL} ]]
then
new_install_pkg $drv
new_install_pkg $drv $nvidiamask
else
check_install_ability $drv && install_pkg $drv
fi
@ -105,8 +124,9 @@ create_nonroot_user() {
local nonroot_user="guest"
ebegin "Creating ${nonroot_user} user"
LANG=C useradd -p "${nonroot_pw}" \
--groups users,wheel,audio,cdrom,video,cdrw,usb,plugdev,games,lp,scanner,uucp \
--groups users,wheel,audio,cdrom,video,cdrw,usb,plugdev,games,lp,lpadmin,scanner,uucp \
${nonroot_user}
chmod 700 /home/${nonroot_user}
eend $?
fi
}
@ -129,45 +149,100 @@ setup_alsautils() {
checkpath -q -d -m 0700 -o root:root ${alsahomedir}
mkdir -p "${alsastatedir}"
local osaudio=`variable_value install.os_audio`
if [[ $osaudio == "alsa" ]]
then
local vlevel="85%"
else
local vlevel="100%"
fi
einfo "Setting up ALSA Mixer Levels"
# set output volumes to 85% - 100%
amixer -c 0 scontrols | grep -v Mic | sed -nr "/Wave|Headphone|Master|Front|LFE|Center|Side|Speaker|Surround|PCM/ s/.*'([^']+)'.*/\\1/p" | xargs -I {} amixer -c 0 -q set "{}" $vlevel unmute &>/dev/null
# reduce beep
amixer -c 0 scontrols | sed -nr "/Beep/ s/.*'([^']+)'.*/\\1/p" | xargs -I {} amixer -c 0 -q set "{}" 10% mute &>/dev/null
# mute all mics
amixer -c 0 scontrols | sed -nr "/Mic/ s/.*'([^']+)'.*/\\1/p" | xargs -I {} amixer -c 0 -q set "{}" 0% mute &>/dev/null
LANG=C alsactl -E HOME="${alsahomedir}" -I -f "${alsastatedir}/asound.state" store
fi
}
start() {
local rootflash=`variable_value main.os_root_flash_dev`
local roottype=`variable_value main.os_root_type`
if [[ $roottype != "livecd" ]] || grep -e "video:nvidia" -e "video:fglrx" /proc/cmdline &>/dev/null
restore_filecaps() {
if [[ -f /var/lib/calculate/filecaps ]] && type filecap &>/dev/null
then
install_video_driver
while read line;
do
filecap $line
done </var/lib/calculate/filecaps
fi
setup_alsautils
LANG=C create_nonroot_user
LANG=C /usr/sbin/cl-core --method setup_system --no-progress --usenew-conf --live on
LANG=C configure_users
[[ -n $rootflash ]] && mount -o remount,rw $rootflash
# reinit net.* services
local rootdev=`variable_value main.os_root_dev`
if [[ $roottype == "livecd" ]] && [[ $rootdev == "/dev/nfs" ]]
rm -f /var/lib/calculate/filecaps
}
start() {
if rc-config list boot | grep -q -e "calculate " -e "calculate$"
then
touch /* /bin/* /sbin/*
udevadm trigger --action="add" --subsystem-match=net
fi
local roottype=`variable_value main.os_root_type`
local subsystem=`variable_value main.os_subsystem`
local rootflash=`variable_value main.os_root_flash_dev`
[[ $subsystem == "lxc" ]] && restore_filecaps
if [[ $roottype != "livecd" ]] || grep "video:nvidia" /proc/cmdline &>/dev/null
then
install_video_driver
fi
setup_alsautils
LANG=C create_nonroot_user
if [[ $subsystem == "lxc" ]] || [[ $roottype == "livecd" ]]
then
LANG=C /usr/sbin/cl-core --method setup_system --no-progress --usenew-conf --live on --network on
else
LANG=C /usr/sbin/cl-core --method setup_system --no-progress --usenew-conf --live on
fi
LANG=C configure_users
[[ -n $rootflash ]] && mount -o remount,rw $rootflash
/sbin/rc-update --update
# reinit net.* services
local roottypeext=`variable_value main.os_root_type_ext`
if [[ $roottypeext == "nfs" ]]
then
touch /* /bin/* /sbin/*
fi
local roottype=`variable_value main.os_root_type`
if [[ $roottype == "hdd" ]] && rc-config list boot | grep -q -e "calculate " -e "calculate$"
then
rc-update del calculate boot
local distdir="/usr/portage/distfiles"
local pkgdir="/usr/portage/packages"
local video_script="/usr/local/sbin/cl-video-install"
local cache_video="/var/cache/calculate/video_drivers"
[[ -d "${distdir}" ]] && [[ -n "`ls ${distdir}`" ]] && rm ${distdir}/*
[[ -d "${pkgdir}" ]] && [[ -n "`ls ${pkgdir}`" ]] && rm -r ${pkgdir}/*
[[ -f "${video_script}" ]] && rm -f "${video_script}"
[[ -f "${cache_video}" ]] && rm -f "${cache_video}"
# set en_US sort service order (make net.eth,net.br,net.wlan more preferable than NetworkManager)
LANG=en_US.utf8 /sbin/rc-update --update
udevadm control --reload
udevadm trigger --action="add" --subsystem-match=net
if [[ $subsystem != "lxc" ]] && ! [[ -f /var/calculate/server/ca/server.key ]]
then
LANG=C /usr/sbin/cl-core --bootstrap
fi
if [[ $roottype == "livecd" ]]
then
LANG=C /usr/sbin/cl-core -u guest
fi
if [[ $roottype == "hdd" ]]
then
/usr/sbin/cl-core --clear-localuser-cert
if [[ -d "/var/db/repos/gentoo" ]]
then
local distdir="/var/calculate/distfiles"
local pkgdir="/var/calculate/packages"
else
local distdir="/usr/portage/distfiles"
local pkgdir="/usr/portage/packages"
fi
local video_script="/usr/local/sbin/cl-video-install"
local cache_video="/var/cache/calculate/video_drivers"
[[ -d "${distdir}" ]] && [[ -n "`ls ${distdir}`" ]] && rm ${distdir}/*
[[ -d "${pkgdir}" ]] && [[ -n "`ls ${pkgdir}`" ]] && rm -r ${pkgdir}/*
[[ -f "${video_script}" ]] && rm -f "${video_script}"
[[ -f "${cache_video}" ]] && rm -f "${cache_video}"
fi
else
ewarn "System already configured!"
fi
return 0

@ -1,9 +1,8 @@
#!/bin/bash
PKG=$1
MASK=`cl-core --method core_variables_show --only-value install.os_nvidia_mask 2>/dev/null`
MASK=$2
WORLD=/var/lib/portage/world
LOG=/var/log/calculate/video-install.log
:> $LOG
LOG=/dev/tty12
WRITEPKG=
[[ -z "$(tail -c1 $WORLD)" ]] || echo >> $WORLD
@ -13,12 +12,36 @@ do
then
if [[ $package_dir == "binary" ]]
then
ACCEPT_KEYWORDS="**" FEATURES="-getbinpkg" PKGDIR=/usr/portage/packages emerge -OK1 =$category/$pn-$pv &>>$LOG || exit 1
else
binary_packages="$binary_packages =$category/$pn-$pv"
fi
fi
done </var/cache/calculate/video_drivers
if [[ -n $binary_packages ]]
then
if [[ -d "/var/db/repos/gentoo" ]]
then
ACCEPT_KEYWORDS="**" FEATURES="-getbinpkg" PKGDIR=/var/calculate/packages emerge -OK1 $binary_packages 2>&1 | cat &>>$LOG || exit 1
else
ACCEPT_KEYWORDS="**" FEATURES="-getbinpkg" PKGDIR=/usr/portage/packages emerge -OK1 $binary_packages 2>&1 | cat &>>$LOG || exit 1
fi
fi
while read category pn pv package_dir pkgname pkgmask;
do
if [[ $PKG == $pkgname ]] && [[ $MASK == $pkgmask ]]
then
if [[ $package_dir != "binary" ]]
then
cd $package_dir
ebuild=$category/$pn/$pn-${pv}.ebuild
[[ -f $ebuild ]] || git checkout $(dirname $ebuild) >>$LOG
DISTDIR=/usr/portage/distfiles ebuild $ebuild merge --skip-manifest &>>$LOG || exit 1
[[ -f $ebuild ]] || git checkout $(dirname $ebuild) 2>&1 | cat &>>$LOG
if [[ -d "/var/db/repos/gentoo" ]]
then
DISTDIR=/var/calculate/distfiles ebuild $ebuild merge --skip-manifest | grep --color=never -P "^>>> [^/]" 2>&1 | cat &>>$LOG || exit 1
else
DISTDIR=/usr/portage/distfiles ebuild $ebuild merge --skip-manifest | grep --color=never -P "^>>> [^/]" 2>&1 | cat &>>$LOG || exit 1
fi
WRITEPKG="$category/$pn"
fi
fi

@ -35,10 +35,10 @@ pre {font-size:133% }
<li>CLDL - Calculate Linux Desktop LXQt</li>
<li>CLDM - Calculate Linux Desktop MATE</li>
<li>CLDX - Calculate Linux Desktop Xfce</li>
<li>CLS - Calculate Linux Scratch</li>
<li>CCM - Calculate Container Manager</li>
<li>CDS - Calculate Directory Server</li>
<li>CLS - Calculate Linux Scratch</li>
<li>CSS - Calculate Scratch Server</li>
<li>CMC - Calculate Media Center</li>
</ul>
@ -59,10 +59,10 @@ As for any other operation performed on the Utilities Server (and this is how yo
<h2 id="Partition-management">Partition management<a href="#Partition-management" class="wiki-anchor">&para;</a></h2>
<p>Before installing, you may need to edit partitions on your hard disk. If you intend to install CLD, CLDC, CLDL, CLDM or CLDX, we recommend that you use the partition of at least 10 GB. More detailed hardware requirements can be found <a href="http://www.calculate-linux.org/main/en/hardware_requirements" class="external">here</a>. The swap partition will normally be twice the size of RAM. If the swap partition already exists, the system will use it. Moreover, it is wise to have a separate partition for your personal files (i.e. for the <code>/home</code> directory). See more detailed instructions on partitioning <a href="http://www.calculate-linux.org/main/en/disk_partitioning" class="external">here</a>.</p>
<p>Before installing, you may need to edit partitions on your hard disk. If you intend to install CLD, CLDC, CLDL, CLDM or CLDX, we recommend that you use the partition of at least 15 GB. More detailed hardware requirements can be found <a href="https://www.calculate-linux.org/main/en/hardware_requirements" target="_blank">here</a>. The swap partition will normally be twice the size of RAM. If the swap partition already exists, the system will use it. Moreover, it is wise to have a separate partition for your personal files (i.e. for the <code>/home</code> directory). See more detailed instructions on partitioning <a href="https://www.calculate-linux.org/main/en/disk_partitioning" target="_blank">here</a>.</p>
<p>CLD, CLDC, CLDL, CLDM and CLDX provide <em>Gparted</em> to edit partitions with, while CLS, CSS and CDS feature only command line utilities for the same purposes, namely <code>fdisk</code>, <code>gdisk or @cfdisk</code>.</p>
<p>CLD, CLDC, CLDL, CLDM and CLDX provide <em>Gparted</em> to edit partitions with, while CLS, CSS and CDS feature only command line utilities for the same purposes, namely <code>fdisk</code>, <code>gdisk or <code>cfdisk</code>.</p>
<p>To list all existing partitions, open your terminal as <em>root</em> and type:<br /><pre>
@ -84,8 +84,8 @@ fdisk -l
We provide several tools that get you install Calculate Linux. You can choose between :
<ul>
<li>the GUI installer, <a href="http://www.calculate-linux.org/main/en/calculate-console-gui" class="external">cl-console-gui</a>,</li>
<li>the command line installer, <a href="http://www.calculate-linux.org/main/en/calculate-console" class="external">cl-console</a>,</li>
<li>the GUI installer, <a href="https://www.calculate-linux.org/main/en/calculate-console-gui" target="_blank">cl-console-gui</a>,</li>
<li>the command line installer, <a href="https://www.calculate-linux.org/main/en/calculate-console" target="_blank">cl-console</a>,</li>
</ul>
@ -106,7 +106,7 @@ startx
</pre></p>
<p>To become <em>root</em>, use the <code>su</code> command. More details on creating user accounts can be found on <a href="http://www.calculate-linux.org/main/en/create_system_users" class="external">this page</a>.</p>
<p>To become <em>root</em>, use the <code>su</code> command. More details on creating user accounts can be found on <a href="https://www.calculate-linux.org/main/en/create_system_users" target="_blank">this page</a>.</p>
<p>By default, you need to be root to log into the system remotely, via the ssh protocole. To add space for other users or to replace the root user edit the <em>AllowUsers</em> line in your <code>/etc/ssh/sshd_config</code>. We recommend that you disable remote root login.</p>
@ -115,7 +115,7 @@ startx
<h2 id="System-update">System update<a href="#System-update" class="wiki-anchor">&para;</a></h2>
<p>Calculate Linux is a rolling-release distribution. You can update the system virtually unlimited number of times with <a href="http://www.calculate-linux.org/main/en/cl-update" class="external">cl-update</a>.</p>
<p>Calculate Linux is a rolling-release distribution. You can update the system virtually unlimited number of times with <a href="https://wiki.calculate-linux.org/en/system_update_guide" target="_blank">cl-update</a>.</p>
<p>To sync the list of packages and update all of your software, simply run:<br /><pre>
@ -128,7 +128,7 @@ cl-update --sync-only
</pre></p>
<p>After that, you can install any other applications you need with <code>emerge</code>. A quick reference can be found <a href="http://www.calculate-linux.org/main/en/add_and_remove_programs" class="external">here</a>. It may also be of interest to read our <a href="http://www.calculate-linux.org/main/en/system_update_guide" class="external">System Update Guide</a>.</p>
<p>After that, you can install any other applications you need with <code>emerge</code>. A quick reference can be found <a href="https://www.calculate-linux.org/main/en/add_and_remove_programs" target="_blank">here</a>. It may also be of interest to read our <a href="https://www.calculate-linux.org/main/en/system_update_guide" target="_blank">System Update Guide</a>.</p>
<h2 id="Help">Help<a href="#Help" class="wiki-anchor">&para;</a></h2>
@ -137,9 +137,9 @@ cl-update --sync-only
<p>If you have any difficulties installing Calculate Linux, or if you want to share your impressions, feel free to visit our IRC community channel <code>#calculate</code> on FreeNode. You just have to click on the <em>Hexchat</em> icon on top of your desktop.</p>
<p>The project site: <noindex><a class="external" href="http://www.calculate-linux.org" ref="nofollow">http://www.calculate-linux.org</a></noindex><br />Our English-speaking IRC community: <noindex><a class="external" href="http://www.calculate-linux.org/irc" ref="nofollow">http://www.calculate-linux.org/irc</a></noindex></p>
<p>The project site: <a href="https://www.calculate-linux.org" target="_blank">https://www.calculate-linux.org</a><br />Our English-speaking IRC community: <a href="https://chat.calculate-linux.org/?channel=#chat" target="_blank">https://chat.calculate-linux.org</a></p>
<p>You can find like-minded people on Facebook, on the <noindex><a href="https://www.facebook.com/CalculateLinux" class="external">Calculate Linux</a></noindex> page.</p>
<p>You can find like-minded people on Facebook, on the <a href="https://www.facebook.com/CalculateLinux" target="_blank">Calculate Linux</a> page.</p>
<p>&nbsp;<br /><em>Enjoy!</em><br /><em>Calculate Linux Team.</em></p>
</body>

@ -33,10 +33,10 @@ pre {font-size:133% }
<li>CLDL - Calculate Linux Desktop LXQt</li>
<li>CLDM - Calculate Linux Desktop MATE</li>
<li>CLDX - Calculate Linux Desktop Xfce</li>
<li>CLS - Calculate Linux Scratch</li>
<li>CCM - Calculate Container Manager</li>
<li>CDS - Calculate Directory Server</li>
<li>CLS - Calculate Linux Scratch</li>
<li>CSS - Calculate Scratch Server</li>
<li>CMC - Calculate Media Center</li>
</ul>
@ -54,13 +54,13 @@ pre {font-size:133% }
</ul>
<p>Подробнее в разделе <a href="http://www.calculate-linux.ru/main/ru/setup_network" class="external">Настройка сети</a>.</p>
<p>Подробнее в разделе <a href="https://www.calculate-linux.ru/main/ru/setup_network" target="_blank">Настройка сети</a>.</p>
<h2 id="Разбивка-диска">Разбивка диска<a href="#Разбивка-диска" class="wiki-anchor">&para;</a></h2>
<p>Перед установкой вам может понадобиться изменить разделы жесткого диска. Для установки CLD, CLDC, CLDL, CLDM и CLDX мы рекомендуем использовать раздел не менее 10 Гб. Более подробно аппаратные требования можно узнать <a href="http://www.calculate-linux.ru/main/ru/hardware_requirements" class="external">здесь</a>. Раздел подкачки (swap), как правило, выделяется вдвое большим размера оперативной памяти. Если раздел под swap уже существует, система будет использовать его. Полезно иметь отдельный раздел для личных файлов (<code>/home</code>). Наши рекомендации по разбиению диска описаны <a href="http://www.calculate-linux.ru/main/ru/disk_partitioning" class="external">здесь</a>.</p>
<p>Перед установкой вам может понадобиться изменить разделы жесткого диска. Для установки CLD, CLDC, CLDL, CLDM и CLDX мы рекомендуем использовать раздел не менее 15 Гб. Более подробно аппаратные требования можно узнать <a href="https://www.calculate-linux.ru/main/ru/hardware_requirements" target="_blank">здесь</a>. Раздел подкачки (swap), как правило, выделяется вдвое большим размера оперативной памяти. Если раздел под swap уже существует, система будет использовать его. Полезно иметь отдельный раздел для личных файлов (<code>/home</code>). Наши рекомендации по разбиению диска описаны <a href="https://www.calculate-linux.ru/main/ru/disk_partitioning" target="_blank">здесь</a>.</p>
<p>В CLD, CLDC, CLDL, CLDM и CLDX для изменения разделов диска используется программа <em>Gparted</em>. В CDS, CSS и CLS входят только консольные утилиты: <em>fdisk</em>,<em>gdisk</em> или <em>cfdisk</em>.</p>
@ -85,13 +85,13 @@ fdisk -l
Установить систему Calculate Linux вы можете одним из перечисленных способов:
<ul>
<li>графическим клиентом <a href="http://www.calculate-linux.ru/main/ru/calculate-console-gui" class="external">cl-console-gui</a>,</li>
<li>консольным клиентом <a href="http://www.calculate-linux.ru/main/ru/calculate-console" class="external">cl-console</a>,</li>
<li>напрямую сервером утилит <a href="http://www.calculate-linux.ru/main/ru/calculate-core" class="external">cl-core</a>.</li>
<li>графическим клиентом <a href="https://www.calculate-linux.ru/main/ru/calculate-console-gui" target="_blank">cl-console-gui</a>,</li>
<li>консольным клиентом <a href="https://www.calculate-linux.ru/main/ru/calculate-console" target="_blank">cl-console</a>,</li>
<li>напрямую сервером утилит <a href="https://www.calculate-linux.ru/main/ru/calculate-core" target="_blank">cl-core</a>.</li>
</ul>
<p>Система может быть установлена из squashfs-образа, если Вы загрузились с liveCD или USB Flash, либо из ISO-файла, размещенного в директории <code>/var/calculate/linux</code> или <code>/var/calculate/remote/linux</code>. Во втором случае Вы можете установить любую версию дистрибутива поддерживаемой архитектуры.</p>
<p>Система может быть установлена из squashfs-образа, если Вы загрузились с liveCD или USB Flash, либо из ISO-файла, размещенного в директории <code>/var/calculate/linux</code>.</p>
<p>Сервер утилит, консольный и графический клиенты входят в состав Calculate Linux, но могут быть установлены из оверлея Calculate в любом Gentoo-совместимом дистрибутиве.</p>
@ -99,8 +99,8 @@ fdisk -l
Подробное описание установки смотрите в соответствующих разделах:
<ul>
<li><a href="http://www.calculate-linux.ru/main/ru/calculate_install" class="external">Установка на жёсткий диск</a></li>
<li><a href="http://www.calculate-linux.ru/main/ru/calculate_install_flash" class="external">Установка на Flash</a></li>
<li><a href="https://www.calculate-linux.ru/main/ru/calculate_install" target="_blank">Установка на жёсткий диск</a></li>
<li><a href="https://www.calculate-linux.ru/main/ru/calculate_install_flash" target="_blank">Установка на Flash</a></li>
</ul></p>
@ -115,7 +115,7 @@ startx
</pre></p>
<p>Для получения прав пользователя <em>root</em> используйте команду <code>su</code>. Добавление новых пользователей подробно описано <a href="http://www.calculate-linux.ru/main/ru/create_system_users" class="external">здесь</a>.</p>
<p>Для получения прав пользователя <em>root</em> используйте команду <code>su</code>. Добавление новых пользователей подробно описано <a href="https://www.calculate-linux.ru/main/ru/create_system_users" target="_blank">здесь</a>.</p>
<p>По умолчанию вы можете зайти в систему удаленно (по протоколу ssh) только как пользователь root. В файле <code>/etc/ssh/sshd_config</code> в значение параметра <em>AllowUsers</em> можно добавить другие учётные записи. Мы рекомендуем убрать права удаленного доступа к системе для пользователя <em>root</em>.</p>
@ -124,7 +124,7 @@ startx
<h2 id="Обновление">Обновление<a href="#Обновление" class="wiki-anchor">&para;</a></h2>
<p>Calculate Linux использует rolling-release модель обновлений. Вы можете обновлять систему практически неограниченное количество раз, используя утилиту обновления системы <a href="http://www.calculate-linux.ru/main/ru/cl-update" class="external">cl-update</a>.</p>
<p>Calculate Linux использует rolling-release модель обновлений. Вы можете обновлять систему практически неограниченное количество раз, используя утилиту обновления системы <a href="https://wiki.calculate-linux.org/ru/system_update_guide" target="_blank">cl-update</a>.</p>
<p>Для выполнения синхронизации списка пакетов и обновления программ, выполните:<br /><pre>
@ -137,18 +137,18 @@ cl-update --sync-only
</pre></p>
<p>После этого вы можете установить новые программы при помощи менеджера пакетов <em>emerge</em>. Краткая справка приведена <a href="http://www.calculate-linux.ru/main/ru/add_and_remove_programs" class="external">здесь</a>. Прочтите так же <a href="http://www.calculate-linux.ru/main/ru/system_update_guide" class="external">Руководство по обновлению системы</a>.</p>
<p>После этого вы можете установить новые программы при помощи менеджера пакетов <em>emerge</em>. Краткая справка приведена <a href="https://www.calculate-linux.ru/main/ru/add_and_remove_programs" target="_blank">здесь</a>. Прочтите так же <a href="https://www.calculate-linux.ru/main/ru/system_update_guide" target="_blank">Руководство по обновлению системы</a>.</p>
<h2 id="Помощь">Помощь<a href="#Помощь" class="wiki-anchor">&para;</a></h2>
<p>Если установка системы вызвала сложности или вы хотите поделиться своим впечатлением, зайдите на <em>IRC</em> канал <em>#calculate-ru</em> (сервер FreeNode) сообщества пользователей Calculate Linux. Для этого достаточно воспользоваться иконкой <em>Hexchat</em> на вашем рабочем столе.</p>
<p>Если установка системы вызвала сложности или вы хотите поделиться своим впечатлением, зайдите в <em>IRC</em> чат <em>#chat-ru</em> (сервер irc.calculate.social) сообщества пользователей Calculate Linux. Для этого достаточно воспользоваться иконкой <em>Сообщество Calculate Linux</em> на вашем рабочем столе или перейдя по <a href="https://chat.calculate-linux.org/?channel=#chat-ru" target="_blank">ссылке.</a></p>
<p>Сайт проекта: <noindex><a class="external" href="http://www.calculate-linux.ru" ref="nofollow">http://www.calculate-linux.ru</a></noindex><br />IRC чат: <noindex><a class="external" href="http://www.calculate-linux.ru/irc" ref="nofollow">http://www.calculate-linux.ru/irc</a></noindex></p>
<p>Сайт проекта: <a href="https://www.calculate-linux.ru" target="_blank">https://www.calculate-linux.ru</a></p>
<p>Найти единомышленников можно и в социальных сетях:<br><noindex><a href="https://vk.com/calculatelinux" class="external">ВКонтакте</a></noindex>, <noindex><a href="https://www.facebook.com/CalculateLinux.ru" class="external">Facebook</a></noindex>, <noindex><a href="https://plus.google.com/communities/100511365552994940528" class="external">Google+</a></noindex>, <noindex><a href="http://www.ok.ru/calculate" rel="nofollow" target="_blank" class="external">Одноклассники</a></noindex> или <noindex><a href="http://twitter.com/calculatelinux" rel="nofollow" target="_blank" class="external">Twitter</a></noindex>.</p>
<p>Найти единомышленников можно и в социальных сетях:<br><a href="https://calculate.social/@news_ru" target="_blank">Mastodon</a>, <a href="https://vk.com/calculatelinux" target="_blank">ВКонтакте</a>, <a href="https://www.facebook.com/CalculateLinux.ru">Facebook</a> или <a href="https://www.ok.ru/calculate" target="_blank">Одноклассники</a>.</p>
<p><em>Приятной работы!<br />Команда разработчиков Calculate Linux.</em></p>
</body>

@ -19,35 +19,41 @@ from random import choice
import string
import os
from time import sleep
import datetime
import re
import sys
import operator
import json
from shutil import copyfile, copytree
from subprocess import Popen, PIPE
from itertools import *
from functools import partial
from calculate.lib.datavars import VariableError
from .datavars import DataVarsInstall
from calculate.lib.utils.files import (isMount, removeDir,
from calculate.lib.utils.mount import isMount, Btrfs, BtrfsError
from calculate.lib.utils.files import (removeDir,
processProgress, STDOUT,
typeFile, pathJoin, process,
listDirectory, checkUtils,
MAGIC_COMPRESS, MAGIC_SYMLINK,
MAGIC_CONTINUE, makeDirectory,
isEmpty, check_rw, calculate_exclude,
PercentProgress, getProgPath)
PercentProgress, getProgPath, xztaropen)
import calculate.lib.utils.device as device
from calculate.lib.utils.device import (detectDeviceForPartition,
getUdevDeviceInfo, countPartitions)
countPartitions)
from calculate.lib.utils.tools import classproperty, Signal, traverse
from calculate.lib.utils.text import _u8
from calculate.lib.variables.linux import LinuxDataVars, Linux
from calculate.lib.cl_lang import setLocalTranslate, _
from functools import reduce
setLocalTranslate('cl_install3', sys.modules[__name__])
class DefaultMountPath(object):
class DefaultMountPath():
"""
Пути по умолчанию для монтирования образов
"""
@ -92,13 +98,13 @@ class cpProcessProgress(processProgress):
return 100
def processString(self, strdata):
if strdata.startswith("cp:") or strdata.startswith("/bin/cp:"):
self._cachedata.append(strdata.partition(": ")[2])
if "->" in strdata:
if strdata.startswith(b"cp:") or strdata.startswith(b"/bin/cp:"):
self._cachedata.append(strdata.partition(b": ")[2])
if b"->" in strdata:
self.value += 1
if self.maxfiles:
percent = 100 * self.value / self.maxfiles
percent = min(percent, 99)
percent = 100 * self.value // self.maxfiles
percent = min(percent, 100)
if percent > self.percent:
self.percent = percent
return percent
@ -111,10 +117,10 @@ def progressCopyFile(source, dest):
Copy file with progress
"""
size = int(os.lstat(source).st_size)
bufsize = (100 - (size % 100) + size) / 100
bufsize = (100 - (size % 100) + size) // 100
with open(source, 'rb') as infile:
with open(dest, 'w') as outfile:
for i in xrange(1, 101):
with open(dest, 'wb') as outfile:
for i in range(1, 101):
outfile.write(infile.read(bufsize))
yield i
@ -124,12 +130,12 @@ class DistributiveError(Exception):
pass
class Distributive(object):
class Distributive():
"""
Distributive object. Parent object for all distributive.
"""
class Type(object):
class Type():
Directory = "dir"
Partition = "part"
SquashFS = "squash"
@ -174,11 +180,16 @@ class Distributive(object):
return IsoDistributive(filename)
elif "7-zip" in ftype or \
"POSIX tar archive" in ftype:
return ArchiveDistributive(filename)
if "rootfs.tar" in filename:
return ContainerDistributive(path.dirname(filename))
else:
return ArchiveDistributive(filename)
elif "Squashfs filesystem" in ftype:
return SquashDistributive(filename)
elif path.isdir(filename):
if path.isfile(path.join(filename, "livecd")):
if path.isfile(path.join(filename, "rootfs.tar.xz")):
return ContainerDistributive(filename)
elif path.isfile(path.join(filename, "livecd")):
return IsoDistributive(filename)
else:
important_dirs = ("etc", "lib", "bin", "sbin", "var")
@ -292,7 +303,10 @@ class Distributive(object):
def getEfiDirectory(self):
"""Get directory which contains boot/efi"""
return path.join(self.getDirectory(), "boot/efi")
return self.getEfiDirectories()[0]
def getEfiDirectories(self):
return [path.join(self.getDirectory(), "boot/efi")]
def _makeDirectory(self, pathname):
"""Make directory and parent.
@ -307,10 +321,10 @@ class Distributive(object):
return False
os.mkdir(pathname)
return True
except Exception, e:
except Exception as e:
raise DistributiveError(_("Failed to create the directory") +
" '%s':\n%s" % (pathname, str(e)))
except KeyboardInterrupt, e:
except KeyboardInterrupt as e:
raise DistributiveError(_("Failed to create the directory") +
" '%s':\n%s" % (pathname, str(e)))
@ -344,10 +358,10 @@ class Distributive(object):
def _copytree(self, indir, outdir):
try:
copytree(indir, outdir, symlinks=True)
except Exception, e:
except Exception as e:
raise DistributiveError(_("Failed to copy") + " '%s' to '%s':\n%s" \
% (indir, outdir, str(e)))
except KeyboardInterrupt, e:
except KeyboardInterrupt as e:
raise DistributiveError(_("Failed to copy") + " '%s' to '%s':\n%s" \
% (indir, outdir, str(e)))
@ -361,10 +375,10 @@ class Distributive(object):
joinFrom = partial(path.join, fromdir)
params = [cpCmd, "-x"] + \
(["--no-preserve=mode,ownership"] if noperm else ["-a"]) + \
map(joinFrom,
ifilterfalse(byfile or operator.not_,
listDirectory(fromdir))) + \
[todir]
[joinFrom(x) for x
in filterfalse(byfile or operator.not_,
listDirectory(fromdir))] + \
[todir]
cpProcess = cpProcessProgress(*params,
maxfiles=filesnum, stderr=STDOUT)
for perc in cpProcess.progress():
@ -373,12 +387,11 @@ class Distributive(object):
errmes = cpProcess.read()
# copy by one file
if byfile:
percFiles = filter(byfile,
listDirectory(fromdir))
percFiles = [x for x in listDirectory(fromdir) if byfile(x)]
if len(percFiles) > 1:
maxPercOnFile = 100 / len(percFiles)
maxPercOnFile = 100 // len(percFiles)
recountPerc = \
lambda perc, num: perc / len(
lambda perc, num: perc // len(
percFiles) + maxPercOnFile * num
else:
recountPerc = lambda perc, num: perc
@ -387,7 +400,7 @@ class Distributive(object):
path.join(todir, copyfile)):
if callbackProgress:
callbackProgress(recountPerc(perc, i))
except Exception, e:
except Exception as e:
res = False
errmes = str(e)
if not res:
@ -412,13 +425,13 @@ class Distributive(object):
def performFormat(self):
pass
def formatPartition(self, dev, format="ext4", label=""):
def formatPartition(self, dev, format="ext4", label="", purpose=None):
pass
def rndString(self):
"""Get random string with len 8 char"""
return "".join([choice(string.ascii_letters + string.digits)
for i in xrange(0, 8)])
for i in range(0, 8)])
def _getSquashNum(self, reMatch):
if reMatch.groups()[1] and reMatch.groups()[1].isdigit():
@ -428,28 +441,25 @@ class Distributive(object):
def _getLastLive(self, directory):
"""Get last live squashfs image from directory"""
squashfiles = filter(lambda x: x,
map(self.reLive.search,
listDirectory(directory)))
squashfiles = [x for x in map(self.reLive.search, listDirectory(directory)) if x]
if squashfiles:
return max(squashfiles, key=self._getSquashNum).group()
return None
def _mountToDirectory(self, file, directory, mountopts="", count=2):
"""Mount squashfs to directory"""
# 2816 code return by mount if device is absent (update /dev by udev)
NO_SUCH_DEVICE = 2816
if isMount(directory):
raise DistributiveError(
_("Failed to mount to the directory: %s\n")
% directory + _("Directory already mounted"))
mountopts_list = filter(lambda x: x,
mountopts.split(" "))
mountopts_list = [x for x in mountopts.split(" ") if x]
mountProcess = process('/bin/mount', file, directory, *mountopts_list,
stderr=STDOUT)
if mountProcess.success():
return True
else:
# 2816 code return by mount if device is absent (update /dev by udev)
# try mount 3 times with interval 0.5 second
if mountProcess.returncode() == NO_SUCH_DEVICE and count:
sleep(0.5)
@ -497,8 +507,6 @@ class Distributive(object):
try:
if path.lexists(path.join(directory, 'lib64')):
d['os_arch_machine'] = 'x86_64'
elif path.lexists(path.join(directory, 'lib')):
d['os_arch_machine'] = 'i686'
else:
d['os_arch_machine'] = ''
dv = LinuxDataVars(systemRoot=directory)
@ -512,6 +520,12 @@ class Distributive(object):
d['cl_profile_name'] = dv.Get('cl_profile_name')
# make lazy call
d['os_linux_files'] = partial(dv.Get, 'os_linux_files')
d['os_chrootable_set'] = "off"
try:
if process("/usr/bin/chroot", directory, "/bin/true").success():
d['os_chrootable_set'] = "on"
except Exception:
pass
except VariableError:
pass
return d.copy()
@ -540,8 +554,15 @@ class Distributive(object):
mapExtName = {DirectoryDistributive: "dir",
IsoDistributive: "isodir",
FlashDistributive: "flash",
ContainerDistributive: "lxc",
PartitionDistributive: "partdir"}
extname = mapExtName.get(distr.__class__, "")
if isinstance(distr, ContainerDistributive):
d = distr.get_information()
d['ext'] = extname
return d.copy()
if isinstance(distr, ArchiveDistributive):
raise DistributiveError("Not for archive distributive")
image = distr.convertToDirectory()
except Exception as e:
# TODO: отладка почему образ не подходит
@ -622,6 +643,10 @@ class DirectoryDistributive(Distributive):
'type': 'bind',
'target': 'var/calculate/remote',
'source': '/var/calculate/remote'},
{'name': 'run',
'type': 'bind',
'target': 'run/',
'source': '/run'}
]
def __init__(self, directory, parent=None, mdirectory=None):
@ -633,19 +658,36 @@ class DirectoryDistributive(Distributive):
if not parent:
self._makeDirectory(self.directory)
def hasSystemDirectories(self):
return self.system_mounted or self.directory == '/'
def mountSystemDirectories(self, skip=("remote",)):
"""
Подключить к дистрибутиву системые ресурсы (/proc, /sys)
:return:
"""
for obj in filter(lambda x: x['name'] not in skip, self.data):
target_path = path.join(self.directory, obj['target'])
if obj['type'] == 'bind':
self._mountToBind(obj['source'], target_path)
else:
self._mountToDirectory(obj['source'], target_path,
"-t %s" % obj['type'])
self.system_mounted = True
if not self.system_mounted:
self.clVars = DataVarsInstall()
# Если в режиме EFI, добавить раздел efivarfs
if self.clVars.GetBool('main.os_uefi_set'):
efi_data = {'name': 'efivars',
'type': 'efivarfs',
'target': 'sys/firmware/efi/efivars',
'source': 'efivarfs'}
if not efi_data in self.data:
self.data.append(efi_data)
for obj in (x for x in self.data if x['name'] not in skip):
target_path = path.join(self.directory, obj['target'])
if obj['type'] == 'bind':
if not path.exists(target_path):
self._makeDirectory(target_path)
if not path.exists(obj['source']):
self._makeDirectory(obj['source'])
self._mountToBind(obj['source'], target_path)
else:
self._mountToDirectory(obj['source'], target_path,
"-t %s" % obj['type'])
self.system_mounted = True
def umountSystemDirectories(self):
for obj in reversed(self.data):
@ -655,7 +697,7 @@ class DirectoryDistributive(Distributive):
self.system_mounted = False
def getType(self):
return _("directory '%s'") % self.directory
return _("directory '%s'") % _u8(self.directory)
def bindDirectory(self, mdirectory):
for child in self.childs:
@ -736,7 +778,7 @@ class DirectoryDistributive(Distributive):
return ld
class DataPartition(object):
class DataPartition():
"""Data partition"""
dev = None
mountPoint = None
@ -756,10 +798,8 @@ class MultiPartitions:
"""Add partition in data partition list"""
dictDataPart = reduce(lambda x, y: \
x.update({y: getattr(DataPartition, y)}) or x,
filter(lambda x: not x.startswith('_'),
DataPartition.__dict__), {})
updateAttrData = filter(lambda x: x[1] is not None,
dictDataPart.items())
[x for x in DataPartition.__dict__ if not x.startswith('_')], {})
updateAttrData = (x for x in dictDataPart.items() if x[1] is not None)
defaultAttr = []
for attrName, attrValue in updateAttrData:
if not attrName in argv.keys():
@ -770,14 +810,13 @@ class MultiPartitions:
if notFoundAttr:
raise DistributiveError(_("The following attributes "
"are not specified: (%s)") \
% ", ".join(
map(lambda x: "DataPartition.%s" % x, notFoundAttr)))
% ", ".join(("DataPartition.%s" % x for x in notFoundAttr)))
unnecessaryAttr = (set(dictDataPart.keys()) ^ set(argv.keys())) - \
set(dictDataPart.keys())
if unnecessaryAttr:
raise DistributiveError(_("Failed to use attributes (%s) ") \
% ", ".join(
map(lambda x: "DataPartition.%s" % x, unnecessaryAttr)))
("DataPartition.%s" % x for x in unnecessaryAttr)))
else:
partObj = DataPartition()
for attr, value in argv.items():
@ -788,27 +827,27 @@ class MultiPartitions:
def getSystemId(self):
"""Get systemID for change [None,82,...]"""
return map(lambda x: x.systemId, self.listPartitions)
return [x.systemId for x in self.listPartitions]
def getPartitionTable(self):
"""Get systemID for change [dos,gpt,...]"""
return map(lambda x: x.partitionTable, self.listPartitions)
return [x.partitionTable for x in self.listPartitions]
def getIsFormat(self):
"""Get list is format [True,...]"""
return map(lambda x: x.isFormat, self.listPartitions)
return [x.isFormat for x in self.listPartitions]
def getFileSystems(self):
"""Get list filesystems ["reiserfs",...]"""
return map(lambda x: x.fileSystem, self.listPartitions)
return [x.fileSystem for x in self.listPartitions]
def getPartitions(self):
"""Get list partition ["/dev/sda",...]"""
return map(lambda x: x.dev, self.listPartitions)
return [x.dev for x in self.listPartitions]
def getMountPoints(self):
"""Get list mount point ["/boot",...]"""
return map(lambda x: x.mountPoint, self.listPartitions)
return [x.mountPoint for x in self.listPartitions]
class FormatProcess(process):
@ -816,17 +855,29 @@ class FormatProcess(process):
dos_id = "0"
gpt_id = "0"
def __init__(self, dev, label=None):
def __init__(self, dev, label=None, purpose=None, compression=None):
self.dev = dev
self._label = label
super(FormatProcess, self).__init__(*self.format_command())
self.purpose = purpose
self.compression = compression
super().__init__(*self.format_command())
def format_command(self):
cmd = getProgPath(self.format_util)
if not cmd:
raise DistributiveError(_("command '%s' not found") % cmd)
params = (self.bootparam()
if self.purpose in ("root", "boot")
else self.param())
return list(traverse(
[cmd] + [x for x in self.param() if x]))
[cmd] + [x for x in params if x]))
def postaction(self):
return True
def bootparam(self):
return self.param()
def param(self):
return self.get_label(), self.dev
@ -864,6 +915,10 @@ class FormatExt4(FormatExt2):
format_util = "/sbin/mkfs.ext4"
class FormatExfat(FormatProcessGeneric):
format_util = "/sbin/mkfs.exfat"
class FormatJfs(FormatProcessGeneric):
format_util = "/sbin/mkfs.jfs"
@ -871,6 +926,15 @@ class FormatJfs(FormatProcessGeneric):
return self.get_label(), "-f", self.dev
class FormatF2FS(FormatProcessGeneric):
format_util = "/usr/sbin/mkfs.f2fs"
def label(self):
return "-l", self._label
def param(self):
return self.get_label(), "-f", self.dev
class FormatReiserfs(FormatProcessGeneric):
format_util = "/sbin/mkfs.reiserfs"
@ -891,6 +955,12 @@ class FormatXfs(FormatProcessGeneric):
def param(self):
return self.get_label(), "-f", self.dev
def nosparse(self):
return "-i", "sparse=0"
def bootparam(self):
return self.get_label(), self.nosparse(), "-f", self.dev
class FormatVfat(FormatProcess):
dos_id = "0b"
@ -942,7 +1012,9 @@ class PartitionDistributive(Distributive):
'ext2': FormatExt2,
'ext3': FormatExt3,
'ext4': FormatExt4,
'exfat': FormatExfat,
'jfs': FormatJfs,
'f2fs': FormatF2FS,
'reiserfs': FormatReiserfs,
'btrfs': FormatBtrfs,
'nilfs2': FormatNilfs2,
@ -951,13 +1023,16 @@ class PartitionDistributive(Distributive):
'ntfs-3g': FormatNtfs,
'ntfs': FormatNtfs,
'uefi': FormatUefi,
'btrfs': FormatBtrfs,
'btrfs-compress': FormatBtrfs,
'swap': FormatSwap
}
def __init__(self, partition, parent=None, mdirectory=None,
check=False, multipartition=None, flagRemoveDir=True,
fileSystem="ext4", isFormat=True, systemId=None,
rootLabel="Calculate", partitionTable=None):
rootLabel="Calculate", partitionTable=None,
compression=None):
"""Initialize partition distributive
mdirectory - directory for mount
@ -974,6 +1049,7 @@ class PartitionDistributive(Distributive):
self.DirectoryObject = None
self.systemId = systemId
self.rootLabel = rootLabel
self.compression = compression
self.partitionTable = partitionTable
def getType(self):
@ -1018,8 +1094,7 @@ class PartitionDistributive(Distributive):
def postinstallMountBind(self):
"""Mount bind mount point and create mount dirs"""
if self.multipartition and self.DirectoryObject:
mulipartDataBind = filter(lambda x: x[2] == "bind",
self.getMultipartData())
mulipartDataBind = [x for x in self.getMultipartData() if x[2] == "bind"]
dirObj = self.DirectoryObject
mdirectory = dirObj.directory
for srcDir, destDir, fileSystem, isFormat, partTable \
@ -1034,35 +1109,45 @@ class PartitionDistributive(Distributive):
parent=dirObj)
DirectoryDistributive(realDestDir, parent=partObj)
def getEfiDirectories(self):
return [path.join(self.getDirectory(), x)
for x in self.multipartition.getMountPoints()
if x.startswith("/boot/efi")
]
def getMultipartData(self):
"""Get multipartition data"""
mulipartData = zip(self.multipartition.getPartitions(),
mulipartData = list(zip(self.multipartition.getPartitions(),
self.multipartition.getMountPoints(),
self.multipartition.getFileSystems(),
self.multipartition.getIsFormat(),
self.multipartition.getPartitionTable())
self.multipartition.getPartitionTable()))
return mulipartData
def convertToDirectory(self):
"""Convert partition to directory by mounting"""
mapFS = {'btrfs-compress': 'btrfs'}
mapOpts = {'btrfs-compress': ' -o compress=%s' % self.compression}
mdirectory = self.mdirectory
for child in self.childs:
if isinstance(child, DirectoryDistributive) and \
mdirectory in child.directory:
return child
mdirectory = self._getMntDirectory(mdirectory)
self._mountPartition(self.partition, mdirectory)
self._mountPartition(self.partition, mdirectory,
mapOpts.get(self.fileSystem,""))
dirObj = DirectoryDistributive(mdirectory, parent=self)
if self.multipartition:
mulipartDataNotBind = filter(lambda x: x[2] != "bind",
self.getMultipartData())
mulipartDataNotBind = (x for x in self.getMultipartData() if x[2] != "bind")
for dev, mountPoint, fileSystem, isFormat, partTable \
in sorted(mulipartDataNotBind, key=lambda x: x[1]):
realMountPoint = None
if fileSystem != "swap":
realMountPoint = pathJoin(mdirectory, mountPoint)
self._mountPartition(dev, realMountPoint,
"-t %s" % fileSystem)
self._mountPartition(
dev, realMountPoint,
"-t %s" % mapFS.get(fileSystem,fileSystem) +
mapOpts.get(fileSystem,""))
partObj = PartitionDistributive(dev, flagRemoveDir=False,
fileSystem=fileSystem,
isFormat=isFormat,
@ -1089,10 +1174,13 @@ class PartitionDistributive(Distributive):
self.multipartition.getMountPoints() + \
["/"])
# get partition which need format
formatPartitions = map(lambda x: (x[FS], x[DEV], x[NEWID], x[MP]),
filter(
lambda x: x[NEEDFORMAT] and x[FS] != "bind",
dataPartitions))
formatPartitions = [(x[FS], x[DEV], x[NEWID], x[MP]) for x
in dataPartitions if x[NEEDFORMAT] and x[FS] != "bind"]
# if has separate /boot partition
bootmp = ["/boot", "/"]
purpose_map = {"/boot": "boot",
"/var/calculate": "calculate",
"/": "root"}
# format all get partition
for fileSystem, dev, newID, mp in formatPartitions:
if fileSystem == "swap":
@ -1102,17 +1190,18 @@ class PartitionDistributive(Distributive):
fileSystem = "uefi"
if dev == self.partition:
self.formatPartition(dev, format=fileSystem,
label=self.rootLabel)
label=self.rootLabel,
purpose=purpose_map.get(mp, None))
else:
if mp == '/var/calculate':
self.formatPartition(dev, format=fileSystem,
label="Calculate")
else:
self.formatPartition(dev, format=fileSystem)
self.formatPartition(dev, format=fileSystem,
purpose=purpose_map.get(mp, None))
# change system id for partitions
changeidPartitions = map(lambda x: (x[NEWID], x[DEV], x[PARTTABLE]),
filter(lambda x: x[NEWID],
dataPartitions))
changeidPartitions = [(x[NEWID], x[DEV], x[PARTTABLE]) for x
in dataPartitions if x[NEWID]]
for systemid, dev, partTable in changeidPartitions:
self.changeSystemID(dev, systemid, partTable)
return True
@ -1123,26 +1212,27 @@ class PartitionDistributive(Distributive):
raise DistributiveError(
_("Failed to format %s: this partition is mounted") % dev)
def formatPartition(self, dev, format="ext4", label=""):
def formatPartition(self, dev, format="ext4", label="", purpose=None):
"""Format partition"""
if not format in self.format_map:
raise DistributiveError(
_("The specified format of '%s' is not supported") % format)
if dev in map(lambda y: y.split(" ")[0],
filter(lambda x: x.startswith("/"),
open("/proc/swaps"))):
raise DistributiveError(
_("Failed to format %s: this partition is used as swap") % dev)
with open("/proc/swaps") as f:
if dev in (x.split(" ")[0] for x in f if x.startswith("/")):
raise DistributiveError(
_("Failed to format %s: this partition is used as swap") % dev)
self._checkMount(dev)
if not os.access(dev, os.W_OK):
raise DistributiveError(_("Failed to format the partition") +
" %s:\n%s" % (dev, _("Permission denied")))
format_process = self.format_map[format](dev, label)
format_process = self.format_map[format](dev, label=label,
purpose=purpose, compression=self.compression)
if format_process.failed():
raise DistributiveError(
_("Failed to format the partition") +
" %s:\n%s" % (dev, format_process.readerr()))
format_process.postaction()
def performFormat(self):
"""Perform format for all partition of this distributive"""
@ -1150,7 +1240,7 @@ class PartitionDistributive(Distributive):
self.formatAllPartitions()
elif self.isFormat:
self.formatPartition(self.partition, format=self.fileSystem,
label=self.rootLabel)
label=self.rootLabel, purpose="root")
if self.systemId:
self.changeSystemID(self.partition, self.systemId,
self.partitionTable)
@ -1165,9 +1255,9 @@ class PartitionDistributive(Distributive):
elif deviceName == "":
return True
fdiskProg, gdiskProg = checkUtils('/sbin/fdisk', '/usr/sbin/gdisk')
partitionNumber = \
getUdevDeviceInfo(name=dev).get('ID_PART_ENTRY_NUMBER', '') or \
getUdevDeviceInfo(name=dev).get('UDISKS_PARTITION_NUMBER', '')
info = device.udev.get_device_info(name=dev)
partitionNumber = (info.get('ID_PART_ENTRY_NUMBER','') or
info.get('UDISKS_PARTITION_NUMBER', ''))
devicePartitionCount = countPartitions(deviceName)
if deviceName and not partitionNumber:
raise DistributiveError(
@ -1177,20 +1267,22 @@ class PartitionDistributive(Distributive):
pipe = Popen([fdiskProg, deviceName],
stdin=PIPE, stdout=PIPE, stderr=PIPE)
if devicePartitionCount > 1:
pipe.stdin.write("t\n%s\n%s\nw\n" % (partitionNumber,
systemid))
tmp = "t\n%s\n%s\nw\n" % (partitionNumber, systemid)
pipe.stdin.write(tmp.encode("UTF-8"))
else:
pipe.stdin.write("t\n%s\nw\n" % systemid)
tmp = "t\n%s\nw\n" % systemid
pipe.stdin.write(tmp.encode("UTF-8"))
pipe.stdin.close()
pipe.wait()
elif parttable == "gpt":
pipe = Popen([gdiskProg, deviceName],
stdin=PIPE, stdout=PIPE, stderr=PIPE)
if devicePartitionCount > 1:
pipe.stdin.write("t\n%s\n%s\nw\ny\n" % (partitionNumber,
systemid))
tmp = "t\n%s\n%s\nw\ny\n" % (partitionNumber, systemid)
pipe.stdin.write(tmp.encode("UTF-8"))
else:
pipe.stdin.write("t\n%s\nw\ny\n" % systemid)
tmp = "t\n%s\nw\ny\n" % systemid
pipe.stdin.write(tmp.encode("UTF-8"))
pipe.stdin.close()
pipe.wait()
for waittime in (0.1, 0.2, 0.5, 1, 2, 4):
@ -1204,12 +1296,12 @@ class PartitionDistributive(Distributive):
def formatSwapPartition(self, dev):
"""Format swap partition"""
if dev in map(lambda y: y.split(" ")[0],
filter(lambda x: x.startswith("/"),
open("/proc/swaps"))):
raise DistributiveError(
_("Failed to execute 'mkswap %s': the swap partition is used "
"by the current system") % dev)
with open("/proc/swaps") as f:
if dev in (x.split(" ")[0] for x in f if x.startswith("/")):
raise DistributiveError(
_("Failed to execute 'mkswap %s': "
"the swap partition is used "
"by the current system") % dev)
if isMount(dev):
raise DistributiveError(
_("Failed to format %s: this partition is mounted") % dev)
@ -1268,6 +1360,8 @@ class ArchiveDistributive(Distributive):
return "gzip"
elif "7-zip archive data" in p_file.read():
return "7z"
elif "XZ compressed data" in p_file.read():
return "xz"
elif file and file.endswith(".tar.lzma"):
if path.exists('/usr/bin/7za'):
return "7z"
@ -1300,6 +1394,9 @@ class ArchiveDistributive(Distributive):
elif archiveType == "gzip":
arch_cmd = getProgPath('/bin/gzip')
params = ["-dc"]
elif archiveType == "xz":
arch_cmd = getProgPath('/bin/xz')
params = ["-dc"]
else:
raise DistributiveError(_("Unknown archive type '%s'") %
archfile)
@ -1325,6 +1422,7 @@ class ArchiveDistributive(Distributive):
def convertToDirectory(self):
"""Get archive as directory (unpack to directory)"""
# check may be the archive already unpacked
raise DistributiveError(_("Unsupported"))
mdirectory = self.mdirectory
for child in self.childs:
if isinstance(child, DirectoryDistributive) and \
@ -1375,6 +1473,83 @@ class ArchiveDistributive(Distributive):
return ld
class ContainerDistributive(ArchiveDistributive):
def __init__(self, basedir, parent=None, exclude=None,
include=None,
mdirectory="/var/calculate/tmp/stage"):
Distributive.__init__(self, parent=parent)
self.basedirectory = basedir
self.file = path.join(basedir, "rootfs.tar.xz")
self.meta = path.join(basedir, "meta.tar.xz")
self.lxd = path.join(basedir, "lxd.tar.xz")
self.exclude = [] if not exclude else exclude
self.include = [] if not include else include
self.mdirectory = mdirectory
def mtime2build(self, fn):
if path.exists(fn):
build_time = datetime.datetime.fromtimestamp(os.stat(fn).st_mtime)
return build_time.strftime("%Y%m%d")
return ""
def packToArchive(self, directory, file):
if not path.exists(self.basedirectory):
self._makeDirectory(self.basedirectory)
tar_command = getProgPath("/usr/bin/tar")
params = ["cf", file, "-J", "-C", directory]
if self.exclude:
exclude_list = list(calculate_exclude(
directory, exclude=self.exclude, include=self.include))
params += ["--exclude=./%s" % x for x in exclude_list]
params += ["."]
#debug_file = "/var/calculate/tmp/rootfs.tar.xz"
#if path.exists(debug_file):
# p = process("/bin/cp", debug_file, file)
#else:
p = process(tar_command, *params, stderr=process.STDOUT)
try:
if p.failed():
raise DistributiveError(_("Failed to create the archive") +
" '%s':\n%s" % (file, p.read()))
except BaseException:
removeDir(self.basedirectory)
raise
def get_information(self):
if path.exists(self.lxd):
with xztaropen(self.lxd) as f:
try:
metadata_yaml = f.getmember("metadata.yaml")
metadata = json.load(f.extractfile(metadata_yaml))
return {
'os_linux_build':
metadata["calculate"]['os_linux_build'],
'os_arch_machine':
metadata["calculate"]['os_arch_machine'],
'os_linux_shortname':
metadata["calculate"]['os_linux_shortname'],
'os_linux_subname':
metadata["calculate"]['os_linux_subname'],
'cl_profile_name':
metadata["calculate"]['cl_profile_name'],
'os_linux_name':
metadata["calculate"]['os_linux_name'],
'os_linux_ver':
metadata["calculate"].get('os_linux_ver', "17"),
}
except (KeyError, ValueError) as e:
pass
return {
'os_linux_build': self.mtime2build(self.file),
'os_arch_machine': "x86_64",
'os_linux_shortname': 'Container',
'os_linux_subname': "",
'cl_profile_name': "",
'os_linux_name': _('Unknown Container')
}
class SquashDistributive(Distributive):
def __init__(self, file, parent=None, mdirectory=None, exclude=None,
compress="", include=None):
@ -1427,7 +1602,8 @@ class SquashDistributive(Distributive):
if self.exclude:
exclude_list = list(calculate_exclude(directory, exclude=self.exclude,
include=self.include))
cmd += ["-e"] + exclude_list
if exclude_list:
cmd += ["-e"] + exclude_list
# возможность использовать заранее подготовленный livecd.squashfs
if path.exists('/var/calculate/tmp/livecd.squashfs'):
os.system('cp -L /var/calculate/tmp/livecd.squashfs %s' % file)
@ -1521,6 +1697,8 @@ class IsoDistributive(Distributive):
self._makeDirectory(directory)
tf = typeFile(magic=MAGIC_COMPRESS | MAGIC_SYMLINK | MAGIC_CONTINUE)
ftype = tf.getMType(file)
if ftype is None:
raise DistributiveError(_("Failed to get Mtype of the iso file"))
if "block special" in ftype:
mopts = "-o ro"
else:
@ -1710,7 +1888,7 @@ class FlashDistributive(PartitionDistributive):
clear_match = re.compile(
r"^(boot|efi|isolinux|syslinux|id.*\.uefi|"
"ldlinux.c32|ldlinux.sys|livecd|livecd.squashfs)$")
for fn in filter(clear_match.match, listDirectory(dn)):
for fn in [x for x in listDirectory(dn) if clear_match.match(x)]:
full_path = path.join(dn, fn)
try:
if path.isdir(full_path):
@ -1721,7 +1899,7 @@ class FlashDistributive(PartitionDistributive):
raise DistributiveError(
_("Failed to remove %s") % fn)
else:
super(FlashDistributive, self).performFormat()
super().performFormat()
def getType(self):
return _("USB flash %s") % self.partition
@ -1754,7 +1932,7 @@ class FlashDistributive(PartitionDistributive):
d = DirectoryDistributive(mp)
d.no_unmount = True
return d
return super(FlashDistributive, self).convertToDirectory()
return super().convertToDirectory()
def releaseChild(self, child):
"""Umount child Directory distributive"""
@ -1820,7 +1998,7 @@ class LayeredDistributive(Distributive):
:param image_file: образ оригинала
:param parent: родительский дистрибутив
"""
super(LayeredDistributive, self).__init__(parent=parent)
super().__init__(parent=parent)
self.mdirectory = mdirectory
self.diff_directory = diff_directory
self.workdir = "%s-work" % self.diff_directory
@ -1848,6 +2026,8 @@ class LayeredDistributive(Distributive):
self._makeDirectory(target)
if not path.exists(self.diff_directory):
self._makeDirectory(self.diff_directory)
if path.exists(self.workdir):
self._removeDirectory(self.workdir)
if not path.exists(self.workdir):
self._makeDirectory(self.workdir)
self._mountToDirectory("none", target, mountopts=(

@ -22,19 +22,85 @@ from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3', sys.modules[__name__])
class FileSystemManager(object):
class FileSystemManager():
"""Convert dict install option"""
defaultOpt = ['noatime']
defaultBindOpts = ['bind']
#Python3 compat problem:
# dict keys() now sorted based on insertion order,
# instead of being sorted arbitrary by hash.
# Just so the order of keys could be the same as
# in older version, I swaped some pairs around.
supportFS = {
'ext2': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext2',
'f2fs': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.f2fs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-l {labelname}',
'msdos': '83',
'ssd': [],
'compress': None,
'type': ['hdd', 'usb-hdd']},
'btrfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.btrfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': ['ssd'],
'type': ['hdd', 'usb-hdd'],
'compress': None,
'compatible': ['btrfs-compress']},
'ntfs-3g': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.ntfs',
'formatparam': '{labelparam} -FQ {device}',
'gpt': '8300',
'label': '-L {labelname}',
'ssd': [],
'auto': False,
'msdos': '7',
'compress': None,
'compatible': ['ntfs']},
'ntfs': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.ntfs',
'formatparam': '{labelparam} -FQ {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '7',
'auto': False,
'ssd': [],
'compress': None,
'compatible': ['ntfs-3g']},
'xfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.xfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'boot': '-i sparce=0',
'ssd': [],
'compress': None,
'type': ['hdd', 'usb-hdd']},
'btrfs-compress': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.btrfs',
'orig': 'btrfs',
'compress': "compress=%s",
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': ['ssd'],
'type': ['hdd', 'usb-hdd'],
'compatible': ['btrfs']},
'ext4': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext4',
'formatparam': '{labelparam} {device}',
'gpt': '8300',
'label': '-L {labelname}',
'ssd': [],
'msdos': '83',
'compress': None,
'type': ['hdd', 'usb-hdd']},
'ext3': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext3',
@ -43,46 +109,45 @@ class FileSystemManager(object):
'label': '-L {labelname}',
'ssd': [],
'msdos': '83',
'compress': None,
'type': ['hdd', 'usb-hdd']},
'ext4': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext4',
'ext2': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext2',
'formatparam': '{labelparam} {device}',
'gpt': '8300',
'label': '-L {labelname}',
'ssd': ['discard'],
'ssd': [],
'msdos': '83',
'compress': None,
'type': ['hdd', 'usb-hdd']},
'reiserfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.reiserfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-l {labelname}',
'msdos': '83',
'ssd': [],
'type': ['hdd', 'usb-hdd']},
'btrfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.btrfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': ['ssd', 'discard', 'space_cache'],
'type': ['hdd', 'usb-hdd']},
'uefi': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.vfat',
'formatparam': '{labelparam} -F 32 {device}',
'gpt': 'EF00',
'label': '-n {labelname}',
'msdos': '0b',
'ssd': [],
'auto': False,
'compress': None,
'type': ['hdd']},
'vfat': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.vfat',
'formatparam': '{labelparam} -F 32 {device}',
'gpt': '0700',
'label': '-n {labelname}',
'msdos': '0b',
'auto': False,
'ssd': [],
'compress': None,
'type': ['flash']},
'jfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.jfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': ['discard'],
'type': ['hdd', 'usb-hdd']},
'xfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.xfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': ['discard'],
'ssd': [],
'compress': None,
'type': ['hdd', 'usb-hdd']},
# 'nilfs2': {'defaultopt': defaultOpt,
# 'format': '/sbin/mkfs.nilfs2',
@ -98,41 +163,15 @@ class FileSystemManager(object):
'gpt': '8200',
'label': '',
'ssd': [],
'auto': False,
'compress': None,
'msdos': '82'},
'uefi': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.vfat',
'formatparam': '{labelparam} -F 32 {device}',
'gpt': 'EF00',
'label': '-n {labelname}',
'msdos': '0b',
'ssd': [],
'type': ['hdd']},
'vfat': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.vfat',
'formatparam': '{labelparam} -F 32 {device}',
'gpt': '0700',
'label': '-n {labelname}',
'msdos': '0b',
'ssd': ['discard'],
'type': ['flash']},
'ntfs': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.ntfs',
'formatparam': '{labelparam} -FQ {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '7',
'ssd': [],
'compatible': ['ntfs-3g']},
'ntfs-3g': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.ntfs',
'formatparam': '{labelparam} -FQ {device}',
'gpt': '8300',
'label': '-L {labelname}',
'ssd': [],
'msdos': '7',
'compatible': ['ntfs']}}
}
default_param = {'defaultopt': defaultOpt,
'gpt': '8300',
'msdos': '83',
'compress': None,
'ssd': []}
@classmethod
@ -143,29 +182,27 @@ class FileSystemManager(object):
else:
return ""
defaultFS = {
'hdd': ("ext4"
if path.exists(supportFS['ext4']['format']) else
"reiserfs"
if path.exists(supportFS['reiserfs']['format']) else
"ext3"),
'flash': "vfat",
'usb-hdd': ("ext4"
if path.exists(supportFS['ext4']['format']) else
"reiserfs"
if path.exists(supportFS['reiserfs']['format']) else
"ext3")
}
@classmethod
def get_default_fs(cls, dv, installtype):
if installtype == 'flash':
return 'vfat'
filesystems = dv.Get('install.cl_install_fs')
for fs in filesystems:
if fs in cls.supportFS and path.exists(cls.supportFS[fs]['format']):
return fs
return 'ext3'
@classmethod
def getDefaultOpt(cls, fs, ssd=False):
return ",".join(cls.supportFS.get(fs, cls.default_param)['defaultopt'] +
(cls.supportFS.get(fs, cls.default_param)['ssd']
if ssd else []))
def getDefaultOpt(cls, fs, ssd=False, compress=None):
fsopts = cls.supportFS.get(fs, cls.default_param)
return ",".join(fsopts['defaultopt'] +
(fsopts['ssd'] if ssd else []) +
([fsopts['compress'] % compress]
if fsopts['compress'] and compress else []))
@classmethod
def checkFSForTypeMount(cls, fs, roottype, mp):
if mp == '/boot/efi':
if mp.startswith('/boot/efi'):
if fs not in ('uefi', 'vfat'):
return False
else:

@ -21,28 +21,35 @@ import time
from os import path
from random import choice
import string
import glob
import shutil
from time import sleep
from calculate.core.server.func import MethodsInterface
from calculate.core.server.admin import Admins
from calculate.lib.utils.mount import isMount
from calculate.lib.utils.system import SystemPath
from calculate.lib.utils.files import (pathJoin,
isMount, process, listDirectory,
process, listDirectory, writeFile,
checkUtils, readFile, find, copyWithPath,
readLinesFile, getProgPath)
from collections import deque
import calculate.lib.utils.device as device
from calculate.lib.utils.device import (detectDeviceForPartition,
getUdevDeviceInfo, refreshLVM,
refreshUdev, countPartitions)
from datavars import DataVarsInstall
from calculate.install.variables.autopartition import AutoPartition
countPartitions)
from calculate.lib.utils.partition import DiskFactory
from .datavars import DataVarsInstall
from distr import DistributiveError
from .distr import DistributiveError, PartitionDistributive
from subprocess import Popen, PIPE, STDOUT
from itertools import *
from calculate.lib.utils.tools import traverse
class InstallError(Exception):
"""Installation Error"""
from migrate_users import migrate
from .migrate_users import migrate
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
@ -56,9 +63,9 @@ class Install(MethodsInterface):
def __init__(self):
self.clVars = None
# refresh information about LVM
refreshLVM()
device.lvm.refresh()
# refresh information about device in udevadm info
refreshUdev()
device.udev.refresh()
def initVars(self, datavars=None):
"""Primary initialization of variables"""
@ -72,10 +79,8 @@ class Install(MethodsInterface):
def canInstallGrub2(self, target):
"""Check that system has grub2 in current and installed system"""
if self.clVars.Get('os_grub2_path'):
return bool(
filter(lambda x: (x.startswith('grub-1.99') or
x.startswith('grub-2')),
listDirectory('/var/db/pkg/sys-boot')))
return bool([x for x in listDirectory('/var/db/pkg/sys-boot')
if (x.startswith('grub-1.99') or x.startswith('grub-2'))])
return False
def prepareBoot(self, target_distr):
@ -110,10 +115,10 @@ class Install(MethodsInterface):
partition_table = self.clVars.Select('os_device_table',
where='os_device_dev',
eq=disk, limit=1)
info = device.udev.get_device_info(name=partition)
partition_number = (
getUdevDeviceInfo(name=partition).get('ID_PART_ENTRY_NUMBER', '') or
getUdevDeviceInfo(name=partition).get('UDISKS_PARTITION_NUMBER', '')
)
info.get('ID_PART_ENTRY_NUMBER', '') or
info.get('UDISKS_PARTITION_NUMBER', ''))
device_partition_count = countPartitions(device_name)
if device_name and not partition_number:
@ -124,56 +129,78 @@ class Install(MethodsInterface):
if partition_table == "dos":
fdisk = process(fdisk_cmd, "-l", device_name)
DEVICENUM, AFLAG = 0, 1
change_active = map(
lambda x: x[DEVICENUM],
filter(
lambda x: (x[DEVICENUM] != partition_number and
x[AFLAG] == "*" or
x[DEVICENUM] == partition_number and
not x[AFLAG] == "*"),
list(map(
lambda x: [str(x[0]), x[1][1].strip()],
# enumerate partitions
enumerate(filter(None, map(
lambda x: x.split()[:2],
# drop string before information about partitions
dropwhile(
lambda x: not x.lstrip().startswith(
"Device"),
fdisk.readlines()))))))[1:]))
# change_active = map(
# lambda x: x[DEVICENUM],
# filter(
# lambda x: (x[DEVICENUM] != partition_number and
# x[AFLAG] == "*" or
# x[DEVICENUM] == partition_number and
# not x[AFLAG] == "*"),
# list(map(
# lambda x: [str(x[0]), x[1][1].strip()],
# # enumerate partitions
# enumerate(filter(None, map(
# lambda x: x.split()[:2],
# # drop string before information about partitions
# dropwhile(
# lambda x: not x.lstrip().startswith(
# "Device"),
# fdisk.readlines()))))))[1:]))
change_active = [x[DEVICENUM] for x
in [[str(y[0]), y[1][1].strip()] for y
in enumerate([z for z
in [o.split()[:2] for o
in dropwhile(lambda x: not x.lstrip().startswith("Device"),fdisk.readlines())]
if z])][1:]
if x[DEVICENUM] != partition_number and
x[AFLAG] == "*" or
x[DEVICENUM] == partition_number and
not x[AFLAG] == "*"]
else:
parted = process(parted_cmd, "-m", device_name, "print")
DEVICENUM, FLAGS = 0, 6
change_active = map(
lambda x: x[DEVICENUM], filter(
lambda x: (x[DEVICENUM] != partition_number and
boot_flag in x[FLAGS].strip(';').split(', ') or
x[DEVICENUM] == partition_number and
boot_flag not in
x[FLAGS].strip(';').split(', ')),
filter(lambda x: len(x) >= 7,
map(lambda x: x.split(':'),
parted.readlines()[2:]))))
# change_active = map(
# lambda x: x[DEVICENUM], filter(
# lambda x: (x[DEVICENUM] != partition_number and
# boot_flag in x[FLAGS].strip(';').split(', ') or
# x[DEVICENUM] == partition_number and
# boot_flag not in
# x[FLAGS].strip(';').split(', ')),
# filter(lambda x: len(x) >= 7,
# map(lambda x: x.split(':'),
# parted.readlines()[2:]))))
change_active = [x[DEVICENUM] for x
in [y for y
in [z.split(':') for z
in parted.readlines()[2:]]
if len(y) >= 7]
if x[DEVICENUM] != partition_number and
boot_flag in x[FLAGS].strip(';').split(', ') or
x[DEVICENUM] == partition_number and
boot_flag not in
x[FLAGS].strip(';').split(', ')]
if not change_active:
return True
if partition_table == "dos":
pipe = Popen([fdisk_cmd, device_name],
stdin=PIPE, stdout=PIPE, stderr=PIPE)
for part_num in change_active:
pipe.stdin.write("a\n%s\n" % part_num)
pipe.stdin.write("w\n")
write_str = "a\n%s\n" % part_num
pipe.stdin.write(write_str.encode("UTF-8"))
pipe.stdin.write(b"w\n")
pipe.stdin.close()
pipe.wait()
elif partition_table == "gpt":
pipe = Popen([gdisk_cmd, device_name],
stdin=PIPE, stdout=PIPE, stderr=PIPE)
if device_partition_count > 1:
pipe.stdin.write("x\n")
pipe.stdin.write(b"x\n")
for part_num in change_active:
pipe.stdin.write("a\n%s\n2\n\n" % part_num)
pipe.stdin.write("w\nY\n")
write_str = "a\n%s\n2\n\n" % part_num
pipe.stdin.write(write_str.encode("UTF-8"))
pipe.stdin.write(b"w\nY\n")
else:
pipe.stdin.write("x\na\n2\n\nw\nY\n")
pipe.stdin.write(b"x\na\n2\n\nw\nY\n")
pipe.stdin.close()
pipe.wait()
for wait_time in (0.1, 0.2, 0.5, 1, 2, 4):
@ -199,14 +226,17 @@ class Install(MethodsInterface):
raise DistributiveError(
_("Failed to write the master boot record\n%s") %
dd_process.read())
target.close()
# выполнить установку syslinux загрузчика
install_root_dev = self.clVars.Get('os_install_root_dev')
syslinux_process = process("/usr/bin/syslinux",
install_root_dev, stderr=STDOUT)
mount_path = target.convertToDirectory()
syslinux_process = process("/usr/bin/extlinux", '--install',
mount_path.directory, stderr=STDOUT)
if syslinux_process.failed():
raise DistributiveError(_("Failed to install syslinux\n%s") %
syslinux_process.read())
target.close()
# выполнить установку syslinux загрузчика
# установить загрузочный раздел активным
return self.setActivePartition(self.clVars.Get('os_install_root_dev'))
@ -231,6 +261,11 @@ class Install(MethodsInterface):
self.install_grub_uefi(cmd_grub_install, prefix_boot, target)
# не UEFI установка
else:
# необходимо удалить запись /boot/efi из текущей системы
# при выполнении cl-setup-boot --mbr
if self.clVars.Get('os_uefi'):
self.update_efi_fstab()
self.mount_efi_fstab()
self.install_grub_biosboot(cmd_grub_install, prefix_boot, target)
def install_grub_biosboot(self, cmd_grub_install, prefix_boot, target):
@ -247,59 +282,204 @@ class Install(MethodsInterface):
self.setActivePartition(boot_disk)
break
chroot_cmd = getProgPath('/usr/bin/chroot')
chroot_dn = target.getDirectory()
if chroot_dn == '/':
chrooting = []
else:
chrooting = [chroot_cmd, chroot_dn]
# если GRUB2 версии 2.00 и выше, обычная установка требует
# параметра --target=i386-pc, иначе GRUB2 может попытаться
# прописать себя как UEFI
if filter(lambda x: "2." in x,
process(cmd_grub_install, '--version')):
if [x for x
in process(*traverse([chrooting, cmd_grub_install, '--version']))
if "2." in x]:
platform = ["--target=i386-pc"]
else:
platform = []
# прописать GRUB2 на все указанные диски
for mbr_disk in self.clVars.Get('os_install_mbr'):
grub_process = process(cmd_grub_install,
"--boot-directory=%s" % pathJoin(
prefix_boot,
target.getBootDirectory()),
mbr_disk, "--force", *platform,
stderr=STDOUT, envdict=os.environ)
if grub_process.failed():
raise DistributiveError(
_("Failed to install the bootloader"))
targetdir = target.convertToDirectory()
if not targetdir.hasSystemDirectories():
targetdir.mountSystemDirectories()
try:
for mbr_disk in self.clVars.Get('os_install_mbr'):
grub_process = process(
*traverse([chrooting,
cmd_grub_install,
"--boot-directory=/%s" % path.relpath(target.getBootDirectory(),
chroot_dn),
mbr_disk, "--force",platform]),
stderr=STDOUT, envdict=os.environ)
if grub_process.failed():
raise DistributiveError(
_("Failed to install the bootloader"))
finally:
if targetdir.system_mounted:
targetdir.umountSystemDirectories()
def update_efi_fstab(self):
"""
Обновляем (или удаляем) запись /boot/efi в текущем /etc/fstab
Удаление используется в случае, если выполняется обновление загрузчика
в не EFI системе, хотя до этого она была установлена как EFI
"""
fstab_fn = pathJoin(self.clVars.Get('cl_chroot_path'), "/etc/fstab")
re_efi_record = re.compile("^(# /boot/efi|\S+\s/boot/efi).*\n",
flags=re.M)
efidata = self.clVars.Get('os_install_fstab_efi_conf')
if path.exists(fstab_fn):
data = readFile(fstab_fn)
m = re_efi_record.search(data)
newdata = re_efi_record.sub("", data)
if efidata:
if m:
newdata = "%s%s\n%s" % (newdata[:m.start()],
efidata, newdata[m.start():])
else:
newdata = "%s%s\n" % (newdata, efidata)
if data != newdata:
with writeFile(fstab_fn) as f:
f.write(newdata)
def format_efi(self):
formatdisk = [(dev, fs)
for dev, mp, fs, make in self.clVars.ZipVars(
'os_install_disk_dev',
'os_install_disk_mount',
'os_install_disk_format',
'os_install_disk_perform_format')
if mp.startswith('/boot/efi') and make == 'on'
]
if formatdisk:
self.startTask(_("Formatting the partitions"), progress=True,
num=len(formatdisk))
i = 1
for dev, fs in formatdisk:
self.formatPartition(dev, format="vfat")
self.setProgress(i)
i += 1
self.endTask(True)
def umountDirectory(self, directory):
return PartitionDistributive(None)._umountDirectory(directory)
def makeDirectory(self, directory):
return PartitionDistributive(None)._makeDirectory(directory)
def mountToDirectory(self, dev, mp):
return PartitionDistributive(None)._mountToDirectory(dev, mp)
def formatPartition(self, dev, format="ext4", label=""):
return PartitionDistributive(None).formatPartition(dev, format, label)
def mount_efi_fstab(self):
"""
Подключить /boot/efi (или отключить) согласно новым данным
Используется как для подключения /boot/efi, так и для отключения.
"""
oldmp_efi = self.clVars.select('os_disk_mount',
os_disk_mount__startswith="/boot/efi")
for dev, mp in self.clVars.ZipVars('os_install_disk_dev',
'os_install_disk_mount'):
if mp.startswith("/boot/efi"):
curdev = isMount(mp)
if curdev != dev:
if curdev:
self.umountDirectory(mp)
self.makeDirectory(mp)
self.mountToDirectory(dev, mp)
if mp in oldmp_efi:
oldmp_efi.remove(mp)
for mp in oldmp_efi:
self.umountDirectory(mp)
def install_grub_uefi(self, cmd_grub_install, prefix_boot, target):
if self.clVars.Get('cl_action') != "system":
self.format_efi()
self.update_efi_fstab()
self.mount_efi_fstab()
efidirs = [x for x in self.clVars.Get('os_install_disk_mount')
if x.startswith('/boot/efi')]
if len(efidirs) > 1:
labels = ["calculate%d" % i for i in range(1, len(efidirs) + 1)]
else:
labels = ["calculate"]
for efiname, efidir in reversed(list(zip(labels, efidirs))):
self._install_grub_uefi(cmd_grub_install, prefix_boot, target,
efidir, efiname)
# удаляем устаревшие
efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr')
p_efibootmgr = process(efi_boot_mgr, "-v")
data = p_efibootmgr.read()
for num, label in re.findall(r"Boot(\d+).*(calculate\d*)", data):
if label not in labels:
process(efi_boot_mgr, "-b", num, "-B").success()
def _install_grub_uefi(
self, cmd_grub_install, prefix_boot, target, efidir, efiname):
"""
Установить grub с UEFI загрузчиком
"""
chroot_cmd = getProgPath('/usr/bin/chroot')
chroot_dn = target.getDirectory()
if chroot_dn == '/':
chrooting = []
else:
chrooting = [chroot_cmd, chroot_dn]
grub_params = [
"--boot-directory=%s" % pathJoin(
prefix_boot,
target.getBootDirectory()),
"--boot-directory=/%s" % path.relpath(target.getBootDirectory(),
chroot_dn),
"--bootloader-id=%s" % efiname,
"--target=x86_64-efi",
"--efi-directory=%s" %
target.getEfiDirectory(),
"--efi-directory=%s" % efidir,
"--force"]
# проверяем наличие в nv-ram нужной нам записи для исключения повтора
efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr')
efi_disk = self.clVars.Select("os_install_disk_dev",
where="os_install_disk_mount",
eq=efidir, limit=1)
if efi_disk:
efi_uuid = device.udev.get_device_info(
name=efi_disk).get("ID_PART_ENTRY_UUID", "")
if efi_uuid:
p_efibootmgr = process(efi_boot_mgr, "-v")
data = p_efibootmgr.read()
if re.search(r"Boot.*{label}\s.*GPT,{uuid}.*{efipath}".format(
label=efiname,
uuid=efi_uuid,
efipath=r"\\EFI\\%s\\grubx64.efi" % efiname),
data, flags=re.M | re.I):
grub_params.append("--no-nvram")
# в случае установки на usb-hdd EFI загрузчик не прописывается
# в efivars
if self.clVars.Get('os_install_root_type') == 'usb-hdd':
grub_params.append("--removable")
if self.clVars.Get('cl_action') != "system" and \
not isMount('/boot/efi'):
raise DistributiveError(_("Failed to install the bootloader. "
"/boot/efi is not mounted."))
grub_process = process(cmd_grub_install,
*grub_params, stderr=STDOUT,
envdict=os.environ)
if grub_process.failed():
raise DistributiveError(_("Failed to install the bootloader"))
targetdir = target.convertToDirectory()
if not targetdir.hasSystemDirectories():
targetdir.mountSystemDirectories()
try:
grub_process = process(
*traverse([
chrooting,
cmd_grub_install,
grub_params]), stderr=STDOUT,
envdict=os.environ)
if grub_process.failed():
raise DistributiveError(_("Failed to install the bootloader"))
finally:
if targetdir.system_mounted:
targetdir.umountSystemDirectories()
# проверяем успешность создания загрузочной записи
# если среди загрузочных записей отсутствует запись
# calculate и dmesg содержит сообщение об ошибке efivars -
# запись создать не удалось
efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr')
dmesg = getProgPath('/bin/dmesg')
if efi_boot_mgr and dmesg:
if not re.search('Boot.*calculate',
if not re.search('Boot.*%s\s' % efiname,
process(efi_boot_mgr).read(), re.M) and \
re.search('efivars.*set_variable.*failed',
process(dmesg).read(), re.M):
@ -339,40 +519,6 @@ class Install(MethodsInterface):
if grub_process.failed():
raise DistributiveError(_("Failed to install the bootloader"))
def setupOpenGL(self):
"""
Выполнить выбор opengl для текущего видеодрайвера
"""
default_gl = "xorg-x11"
path_gl_modules = path.join(self.clVars.Get('cl_chroot_path'),
'usr/lib/opengl')
open_gl_env = path.join(self.clVars.Get('cl_chroot_path'),
'etc/env.d/03opengl')
open_gl_mods = filter(lambda x: x != "global",
listDirectory(path_gl_modules))
map_gl_drivers = {'fglrx': ("ati" if "ati" in open_gl_mods
else default_gl),
'nvidia': "nvidia" if "nvidia" in open_gl_mods
else default_gl}
x11_driver = self.clVars.Get('os_install_x11_video_drv')
if x11_driver in map_gl_drivers:
new_module_name = map_gl_drivers[x11_driver]
else:
new_module_name = default_gl
current_module_name = map(
lambda x: x.strip().rpartition('=')[-1].strip('"\''),
filter(lambda x: x.startswith("OPENGL_PROFILE="),
readLinesFile(open_gl_env)))
if current_module_name:
current_module_name = current_module_name[-1]
else:
current_module_name = ""
if current_module_name == new_module_name:
return True
return process('/usr/bin/eselect', 'opengl', 'set',
new_module_name).success()
def checkVideoDriver(self):
"""
Проверить видео драйвер, и если это nvidia, то
@ -385,13 +531,14 @@ class Install(MethodsInterface):
# если package.mask является файлом - делаем его директорией
if path.isfile(mask_file):
os.rename(mask_file, mask_file + "2")
os.mkdir(mask_file, mode=0755)
os.mkdir(mask_file, mode=0o755)
os.rename(mask_file + "2", path.join(mask_file, "default"))
current_nvidia_mask = readFile(nvidia_mask_file).strip()
new_nvidia_mask = self.clVars.Get('os_nvidia_mask')
if new_nvidia_mask == current_nvidia_mask:
return True
open(nvidia_mask_file, 'w').write(new_nvidia_mask)
with open(nvidia_mask_file, 'w') as f:
f.write(new_nvidia_mask)
return True
def changeScheduler(self, scheduler):
@ -402,28 +549,89 @@ class Install(MethodsInterface):
where='os_disk_mount',
eq='/', limit=1)
try:
scheduler_path = (
"/sys%s/queue/scheduler" %
(getUdevDeviceInfo(name=root_dev).get('DEVPATH', '')))
if path.exists(scheduler_path):
open(scheduler_path, 'w').write(scheduler)
sysname = device.udev.get_syspath(name=root_dev)
if device.sysfs.exists(sysname, device.sysfs.Path.BlockScheduler):
device.sysfs.write(
sysname, device.sysfs.Path.BlockScheduler, scheduler)
except Exception:
raise InstallError(_("Unable to change the I/O scheduler"))
return True
def autopartition(self, table, devices, data, lvm, lvm_vgname, bios_grub,
bios_grub_size):
def clearLvm(self, devices):
dv = self.clVars
def get_vgs():
for pv, vg, pvbase in dv.ZipVars('os_lvm_pvname',
'os_lvm_vgname',
'os_lvm_pvname_parent'):
if (pv in devices or
any(x in devices for x in pvbase.split(','))):
yield vg
remove_vgs = set(get_vgs())
remove_pvs = set(self.clVars.select('os_lvm_pvname',
os_lvm_vgname__in=remove_vgs))
remove_lvs = set(self.clVars.select('os_lvm_vgname', 'os_lvm_lvname',
os_lvm_vgname__in=remove_vgs))
failed = False
for vg, lv in sorted(remove_lvs):
failed |= not device.lvm.remove_lv(vg, lv)
for vg in sorted(remove_vgs):
failed |= not device.lvm.remove_vg(vg)
for pv in sorted(remove_pvs):
failed |= not device.lvm.remove_pv(pv)
return not failed
def clearRaid(self, devices):
dv = self.clVars
def generate_remove_raids():
for raid, parents in dv.select('os_device_dev', 'os_device_parent',
os_device_type__startswith="raid"):
parents = parents.split(',')
if any(x in devices for x in parents):
yield raid, set(parents)
remove_raids = deque(generate_remove_raids())
failed = False
while remove_raids:
raid, parents = remove_raids.popleft()
# если среди прочих удаляемых RAID есть те, которые используют
# текущий - откладываем его в конец
if any(raid in _parents for _raid, _parents in remove_raids):
remove_raids.append((raid, parents))
else:
failed |= not device.raid.remove_raid(raid)
return not failed
def wait_devices(self, disks):
"""
Ожидание одного из указанных устройств
"""
for waittime in (0.1, 0.2, 0.5, 1, 2, 4):
disks = [x for x in disks if x and not path.exists(x)]
if not disks:
break
else:
sleep(waittime)
if disks:
raise InstallError(
_("Failed to found partition %s after creating "
"the partition table")
% ",".join(disks))
def autopartition(self, scheme_builder, devices, disks):
"""
Авторазметка диска с таблицей разделов 'table', диски указываются
'device', параметры таблицы 'data', 'lvm' использование LVM,
'lvm_vgname' название группы томов LVM, bios_grub - создавать
bios_grub раздел, bios_grub_size - раздел bios grub раздела в байтах
Авторазметка диска входящая переменная - SchemeBuilder
"""
ap = AutoPartition()
ap.clearLvm(devices, self.clVars)
ap.clearRaid(devices, self.clVars)
ap.recreateSpace(table, devices, data, lvm,
lvm_vgname, bios_grub, bios_grub_size)
self.clearLvm(devices)
self.clearRaid(devices)
scheme_builder.process(DiskFactory())
self.wait_devices(disks)
return True
def format(self, target):
@ -453,10 +661,10 @@ class Install(MethodsInterface):
"""
target_dir = target.getDirectory()
source_dir = source.getDirectory()
for f in filter(lambda x: x.endswith('.clt'),
chain(*map(lambda x: find(pathJoin(source_dir, x),
filetype="f"),
cltpath))):
for f in (x for x
in chain(*[find(pathJoin(source_dir, y), filetype="f") for y
in cltpath])
if x.endswith('.clt')):
copyWithPath(f, target_dir, prefix=source_dir)
return True
@ -464,14 +672,14 @@ class Install(MethodsInterface):
"""
Скопировать прочие настройки из текущей системы в новую
"""
file_mask = re.compile("(/etc/ssh/ssh_host_.*|"
"/root/.ssh/(id_.*|known_hosts))")
file_mask = re.compile("(/etc/ssh/ssh_host_.*|/etc/machine-id|"
"/root/.ssh/(id_.*|known_hosts))(?!\.old)")
target_dir = target.getDirectory()
source_dir = source.getDirectory()
for f in filter(file_mask.search,
chain(*map(lambda x: find(pathJoin(source_dir, x),
filetype="f"),
["/etc", "/root/.ssh"]))):
for f in (x for x
in chain(*(find(pathJoin(source_dir, y), filetype="f") for y
in ["/etc", "/root/.ssh"]))
if file_mask.search(x)):
copyWithPath(f, target_dir, prefix=source_dir)
return True
@ -481,7 +689,7 @@ class Install(MethodsInterface):
"""
"""Get random string with len 8 char"""
return "".join([choice(string.ascii_letters + string.digits)
for i in xrange(0, 8)])
for i in range(0, 8)])
def _getFreeDirectory(self, directory):
"""
@ -533,7 +741,9 @@ class Install(MethodsInterface):
установка пароля пользователя root
"""
migrator = migrate(target.getDirectory())
if not migrator.migrate(migrate_data, root_pwd, [], [], ):
if not migrator.migrate([[x[0],x[2],x[3]] for x in migrate_data if x],
root_pwd, [], [], ):
raise InstallError(_("Failed to migrate users onto the new system"))
return True
@ -543,3 +753,36 @@ class Install(MethodsInterface):
"""
distr.close()
return True
def drop_xorg_logs(self):
"""
Сбросить логи загрузки xorg сервера
"""
for fn in glob.glob("/var/log/Xorg.*.log"):
new_name = "%s.old" % fn
if path.exists(new_name):
os.unlink(new_name)
shutil.move(fn, new_name)
return True
def update_admin_ini(self):
"""
Обновить список локальных администраторов при установке
"""
aliases = {
'update': 'system_update',
}
install_admin = Admins(self.clVars, chroot=True)
install_admin.clear()
for k,v in self.clVars.select('install.cl_migrate_user',
'install.cl_migrate_admin',
install_cl_migrate_admin__ne=""):
install_admin[k] = aliases.get(v,v)
install_admin.save()
return True
def init_themes(self):
self.clVars.Get('cl_splash_image_hash')
self.clVars.Get('cl_grub_image_hash')
return True

@ -17,9 +17,10 @@
import os, sys, re, time
from calculate.lib.encrypt import encrypt
from os import path
from calculate.lib.utils.files import pathJoin
from calculate.lib.utils.files import pathJoin, FilePermission
from calculate.lib.cl_lang import setLocalTranslate, _
from functools import reduce
setLocalTranslate('cl_install3', sys.modules[__name__])
@ -28,16 +29,17 @@ class MigrationError(Exception):
pass
class _shareData(object):
class _shareData():
"""Share class"""
_reNumb = re.compile("^\d+$")
def getDataInFile(self, fileName='', lenData=7):
"""Get data list from file"""
return map(lambda x: x[:lenData],
filter(lambda x: len(x) >= lenData,
map(lambda x: x.rstrip().split(":"),
open(fileName))))
with open(fileName) as f:
return [x[:lenData] for x
in (y.rstrip().split(":") for y
in f)
if len(x) >= lenData]
class migrateGroups(_shareData):
@ -57,46 +59,39 @@ class migrateGroups(_shareData):
def getThisData(self):
"""Get data migrate groups in this system"""
return filter(lambda x: \
self._reNumb.match(x[2]) and self.minGid <= int(
x[2]) <= self.maxGid,
self.getData())
return [x for x in self.getData()
if self._reNumb.match(x[2]) and self.minGid <= int(x[2]) <= self.maxGid]
def getNewData(self):
"""Get data migrate groups in new system"""
fileName = pathJoin(self.prefixNewSystem, self.fileGroups)
return filter(lambda x: \
self._reNumb.match(x[2]) and self.minGid <= int(
x[2]) <= self.maxGid,
self.getData(fileName=fileName))
return [x for x in self.getData(fileName=fileName)
if self._reNumb.match(x[2]) and self.minGid <= int(x[2]) <= self.maxGid]
def getNewDataSystemGroups(self):
"""Get data system groups in new system"""
fileName = pathJoin(self.prefixNewSystem, self.fileGroups)
return filter(lambda x: \
self._reNumb.match(x[2]) and \
(int(x[2]) > self.maxGid or int(x[2]) < self.minGid),
self.getData(fileName=fileName))
return [x for x in self.getData(fileName=fileName)
if self._reNumb.match(x[2]) and (int(x[2]) > self.maxGid or int(x[2]) < self.minGid)]
def getNewProcessedData(self):
"""Get processed data migrate groups in new system"""
# data this Group no users
dataThisGroupsNoUsers = map(lambda x: x[:3] + [""], self.getThisData())
dataThisGroupsNoUsers = [x[:3] + [""] for x in self.getThisData()]
dataNewGroups = self.getNewData()
namesNewGroups = map(lambda x: x[0], dataNewGroups)
gidsNewGroups = map(lambda x: x[2], dataNewGroups)
namesNewGroups = [x[0] for x in dataNewGroups]
gidsNewGroups = [x[2] for x in dataNewGroups]
for data in dataThisGroupsNoUsers:
nameGroup = data[0]
gid = data[2]
if nameGroup in namesNewGroups:
dataNewGroups = filter(lambda x: x[0] != nameGroup,
dataNewGroups)
namesNewGroups = map(lambda x: x[0], dataNewGroups)
gidsNewGroups = map(lambda x: x[2], dataNewGroups)
dataNewGroups = [x for x in dataNewGroups if x[0] != nameGroup]
namesNewGroups = [x[0] for x in dataNewGroups]
gidsNewGroups = [x[2] for x in dataNewGroups]
if gid in gidsNewGroups:
dataNewGroups = filter(lambda x: x[2] != gid, dataNewGroups)
namesNewGroups = map(lambda x: x[0], dataNewGroups)
gidsNewGroups = map(lambda x: x[2], dataNewGroups)
dataNewGroups = [x for x in dataNewGroups if x[2] != gid]
namesNewGroups = [x[0] for x in dataNewGroups]
gidsNewGroups = [x[2] for x in dataNewGroups]
systemGroupsNewData = self.getNewDataSystemGroups()
return systemGroupsNewData, dataNewGroups, dataThisGroupsNoUsers
@ -118,81 +113,67 @@ class migrateUsers(_shareData):
def getThisData(self):
"""Get data migrate users in this system"""
return filter(lambda x: \
self._reNumb.match(x[2]) and self.minId <= int(
x[2]) <= self.maxId,
self.getData())
return [x for x in self.getData()
if self._reNumb.match(x[2]) and self.minId <= int(x[2]) <= self.maxId]
def getNewData(self):
"""Get data migrate users in new system"""
fileName = pathJoin(self.prefixNewSystem, self.filePasswd)
return filter(lambda x: \
self._reNumb.match(x[2]) and self.minId <= int(
x[2]) <= self.maxId,
self.getData(fileName=fileName))
return [x for x in self.getData(fileName=fileName)
if self._reNumb.match(x[2]) and self.minId <= int(x[2]) <= self.maxId]
def getNewDataSystemUsers(self):
"""Get data system users in new system"""
fileName = pathJoin(self.prefixNewSystem, self.filePasswd)
return filter(lambda x: \
self._reNumb.match(x[2]) and \
(int(x[2] > self.maxId) or int(x[2]) < self.minId),
self.getData(fileName=fileName))
return [x for x in self.getData(fileName=fileName)
if self._reNumb.match(x[2]) and (int(x[2]) > self.maxId or int(x[2]) < self.minId)]
def getThisDataSystemUsers(self):
"""Get data system users in this system"""
fileName = self.filePasswd
return filter(lambda x: \
self._reNumb.match(x[2]) and \
(int(x[2] > self.maxId) or int(x[2]) < self.minId),
self.getData(fileName=fileName))
return [x for x in self.getData(fileName=fileName)
if self._reNumb.match(x[2]) and (int(x[2]) > self.maxId or int(x[2]) < self.minId)]
def getNewProcessedData(self, migrateUsers=()):
"""Get processed data migrate users in new system"""
dataThisUsers = self.getThisData()
if migrateUsers:
dataThisUsers = filter(lambda x: x[0] in migrateUsers,
dataThisUsers)
dataThisUsers = [x for x in dataThisUsers if x[0] in migrateUsers]
dataNewUsers = self.getNewData()
namesNewUsers = map(lambda x: x[0], dataNewUsers)
uidsNewUsers = map(lambda x: x[2], dataNewUsers)
namesNewUsers = [x[0] for x in dataNewUsers]
uidsNewUsers = [x[2] for x in dataNewUsers]
for data in dataThisUsers:
nameUser = data[0]
uid = data[2]
if nameUser in namesNewUsers:
dataNewUsers = filter(lambda x: x[0] != nameUser, dataNewUsers)
namesNewUsers = map(lambda x: x[0], dataNewUsers)
uidsNewUsers = map(lambda x: x[2], dataNewUsers)
dataNewUsers = [x for x in dataNewUsers if x[0] != nameUser]
namesNewUsers = [x[0] for x in dataNewUsers]
uidsNewUsers = [x[2] for x in dataNewUsers]
if uid in uidsNewUsers:
dataNewUsers = filter(lambda x: x[2] != uid, dataNewUsers)
namesNewUsers = map(lambda x: x[0], dataNewUsers)
uidsNewUsers = map(lambda x: x[2], dataNewUsers)
dataNewUsers = [x for x in dataNewUsers if x[2] != uid]
namesNewUsers = [x[0] for x in dataNewUsers]
uidsNewUsers = [x[2] for x in dataNewUsers]
systemUsersNewData = self.getNewDataSystemUsers()
systemUsersNewNames = map(lambda x: x[0], systemUsersNewData)
systemUsersNewUids = map(lambda x: x[2], systemUsersNewData)
systemUsersNewNames = [x[0] for x in systemUsersNewData]
systemUsersNewUids = [x[2] for x in systemUsersNewData]
systemUsersThisData = []
if migrateUsers:
# this users < minId
systemUsersThisData = filter(lambda x: int(x[2]) < self.minId and \
x[0] in migrateUsers,
self.getThisDataSystemUsers())
systemUsersThisData = [x for x in self.getThisDataSystemUsers()
if int(x[2]) < self.minId and x[0] in migrateUsers]
for data in systemUsersThisData:
nameUser = data[0]
uid = data[2]
if nameUser in systemUsersNewNames:
systemUsersNewData = filter(lambda x: x[0] != nameUser,
systemUsersNewData)
systemUsersNewNames = map(lambda x: x[0],
systemUsersNewData)
systemUsersNewUids = map(lambda x: x[2],
systemUsersNewData)
systemUsersNewData = [x for x in systemUsersNewData
if x[0] != nameUser]
systemUsersNewNames = [x[0] for x in systemUsersNewData]
systemUsersNewUids = [x[2] for x in systemUsersNewData]
if uid in systemUsersNewUids:
systemUsersNewData = filter(lambda x: x[2] != uid,
systemUsersNewData)
systemUsersNewNames = map(lambda x: x[0],
systemUsersNewData)
systemUsersNewUids = map(lambda x: x[2],
systemUsersNewData)
systemUsersNewData = [x for x in systemUsersNewData
if x[2] != uid]
systemUsersNewNames = [x[0] for x in systemUsersNewData]
systemUsersNewUids = [x[2] for x in systemUsersNewData]
return (systemUsersThisData, systemUsersNewData,
dataNewUsers, dataThisUsers)
@ -218,48 +199,48 @@ class migrateShadow(_shareData):
def getThisData(self):
"""Get data migrate users in this system"""
return filter(lambda x: x[0] in self.thisMigrateUsers, self.getData())
return [x for x in self.getData()
if x[0] in self.thisMigrateUsers]
def getNewData(self):
"""Get data migrate users in new system"""
return filter(lambda x: x[0] in self.newMigrateUsers,
self.getData(fileName=self.newFileName))
return [x for x in self.getData(fileName=self.newFileName)
if x[0] in self.newMigrateUsers]
def getNewDataSystemShadow(self):
"""Get data system users in new system"""
return filter(lambda x: x[0] in self.sysNewMigrateUsers,
self.getData(fileName=self.newFileName))
return [x for x in self.getData(fileName=self.newFileName)
if x[0] in self.sysNewMigrateUsers]
def getThisDataSystemShadow(self):
"""Get data system users in this system"""
return filter(lambda x: x[0] in self.sysThisMigrateUsers,
self.getData())
return [x for x in self.getData() if x[0] in self.sysThisMigrateUsers]
def getNewProcessedData(self):
"""Get processed data migrate shadow in new system"""
dataThisShadow = self.getThisData()
dataNewShadow = self.getNewData()
namesNewShadow = map(lambda x: x[0], dataNewShadow)
namesNewShadow = [x[0] for x in dataNewShadow]
for data in dataThisShadow:
nameUser = data[0]
if nameUser in namesNewShadow:
dataNewShadow = filter(lambda x: x[0] != nameUser,
dataNewShadow)
namesNewShadow = map(lambda x: x[0], dataNewShadow)
dataNewShadow = [x for x in dataNewShadow if x[0] != nameUser]
namesNewShadow = [x[0] for x in dataNewShadow]
systemShadowNewData = self.getNewDataSystemShadow()
systemShadowThisData = self.getThisDataSystemShadow()
systemShadowNewNames = map(lambda x: x[0], systemShadowNewData)
systemShadowNewNames = [x[0] for x in systemShadowNewData]
for data in systemShadowThisData:
nameUser = data[0]
if nameUser in systemShadowNewNames:
systemShadowNewData = filter(lambda x: x[0] != nameUser,
systemShadowNewData)
systemShadowNewNames = map(lambda x: x[0], systemShadowNewData)
systemShadowNewData = [x for x
in systemShadowNewData if x[0] != nameUser]
systemShadowNewNames = [x[0] for x in systemShadowNewData]
return (systemShadowThisData, systemShadowNewData, dataNewShadow,
dataThisShadow)
class migrate(object):
class migrate():
"""Migrate users ang groups to new system"""
templateShadow = "%(user)s:%(hash)s:%(days)s:0:%(maxDays)s:%(warnDays)s:::"
templateUser = "%(user)s:x:%(id)s:%(gid)s::/home/%(user)s:/bin/bash"
@ -273,8 +254,8 @@ class migrate(object):
minGid = 1000
minSysId = 1000
newUserGroups = ["audio", "cdrom", "cdrw", "games", "lp", "plugdev",
"scanner" "usb", "users", "video", "wheel"]
newUserGroups = ["audio", "cdrom", "cdrw", "games", "lp", "lpadmin",
"plugdev", "scanner" "usb", "users", "video", "wheel"]
def __init__(self, prefixNewSystem):
self.prefixNewSystem = prefixNewSystem
@ -284,14 +265,12 @@ class migrate(object):
def addThisUsersToGroups(self, users):
"""Add users to groups"""
thisGroupsData = self.objGroups.getData()
thisGroupsData = map(lambda x: (x[0], x[3].split(',')),
thisGroupsData)
thisGroupsData = [(x[0], x[3].split(',')) for x in thisGroupsData]
dataGroups = []
for data in self.dataGroups:
groupName = data[0]
thisUsersInGroup = map(lambda x: x[1],
filter(lambda x: x[0] == groupName,
thisGroupsData))
thisUsersInGroup = [x[1] for x in thisGroupsData if x[0] == groupName]
#??? whats the point of this?
thisUsersInGroup = reduce(lambda x, y: x + y, thisUsersInGroup, [])
addUsers = list(set(thisUsersInGroup) & set(users))
if addUsers:
@ -299,36 +278,30 @@ class migrate(object):
for user in addUsers:
if not user in newUsersInGroup:
newUsersInGroup.append(user)
data[3] = ','.join(filter(lambda x: x, newUsersInGroup))
data[3] = ','.join((x for x in newUsersInGroup if x))
dataGroups.append(data)
self.dataGroups = dataGroups
return self.dataGroups
def getNextUid(self):
"""get next uid"""
listUid = map(lambda x: int(x[2]),
filter(lambda x: \
self.objUsers._reNumb.match(x[2]) and \
self.minId <= int(x[2]) <= self.maxId,
self.dataUsers))
listUid = [int(x[2]) for x in self.dataUsers
if self.objUsers._reNumb.match(x[2]) and self.minId <= int(x[2]) <= self.maxId]
if listUid:
return max(listUid) + 1
return self.minId
def getNextGid(self):
"""get next gid"""
listGid = map(lambda x: int(x[2]),
filter(lambda x: \
self.objGroups._reNumb.match(x[2]) and \
self.minGid <= int(x[2]) <= self.maxGid,
self.dataGroups))
listGid = [int(x[2]) for x in self.dataGroups
if self.objUsers._reNumb.match(x[2]) and self.minGid <= int(x[2]) <= self.maxGid]
if listGid:
return max(listGid) + 1
return self.minGid
def isSystemUser(self, userName):
if filter(lambda x: x[0] == userName and int(x[2]) <= self.minSysId,
self.dataUsers):
if [x for x in self.dataUsers
if (x[0] == userName and int(x[2]) <= self.minSysId)]:
return True
return False
@ -342,7 +315,7 @@ class migrate(object):
usersInGroup = data[3].split(',')
if not userName in usersInGroup:
usersInGroup.append(userName)
data[3] = ','.join(filter(lambda x: x, usersInGroup))
data[3] = ','.join((x for x in usersInGroup if x))
dataGroups.append(data)
self.dataGroups = dataGroups
return self.dataGroups
@ -352,7 +325,7 @@ class migrate(object):
return self.addUserToGroups(userName, self.newUserGroups)
def changePassword(self, userName, pwdHash, maxDays="99999", warnDays="7"):
if not filter(lambda x: x[0] == userName, self.dataUsers):
if not [x for x in self.dataUsers if x[0] == userName]:
raise MigrationError(_("User %s not found") % userName)
indexFoundUser = False
for i, data in enumerate(self.dataShadow):
@ -379,14 +352,14 @@ class migrate(object):
def addUser(self, userName, userGroups, pwdHash):
"""Add user"""
# find user
if filter(lambda x: x[0] == userName, self.dataUsers):
if [x for x in self.dataUsers if x[0] == userName]:
return "EXISTS"
else:
strUid = str(self.getNextUid())
strGid = str(self.getNextGid())
groupName = userName
dataExistGroup = filter(lambda x: x[0] == groupName,
self.dataGroups)
dataExistGroup = [x for x in self.dataGroups
if x[0] == groupName]
if dataExistGroup:
strGid = dataExistGroup[0][2]
else:
@ -411,27 +384,25 @@ class migrate(object):
"""Check permission files"""
checkThisFiles = [migrateGroups.fileGroups, migrateUsers.filePasswd,
migrateShadow.fileShadow]
checkNewFiles = map(lambda x: pathJoin(self.prefixNewSystem, x),
checkThisFiles)
checkNewFiles = [pathJoin(self.prefixNewSystem, x) for x in checkThisFiles]
parentDir = lambda x: "".join(os.path.split(x)[:-1])
notRead = lambda x: not os.access(x, os.R_OK)
notWrite = lambda x: not os.access(x, os.W_OK)
filesNotRead = filter(notRead, checkThisFiles)
filesNotRead = [x for x in checkThisFiles if notRead(x)]
if filesNotRead:
raise MigrationError(_("Failed to read files") + _(": ") +
", ".join(filesNotRead))
filesNotWrite = filter(notWrite, checkNewFiles)
filesNotWrite = [x for x in checkNewFiles if notWrite(x)]
if filesNotWrite:
raise MigrationError(_("Failed to write to files") + _(": ") +
", ".join(filesNotWrite))
# Check permissions backup files
checkNewBackupFiles = map(
lambda x: pathJoin(self.prefixNewSystem, x + "-"),
checkThisFiles)
checkNewBackupFiles = (pathJoin(self.prefixNewSystem, x + "-") for x
in checkThisFiles)
notWriteBackup = lambda x: not os.access(x, os.W_OK) and \
(os.path.exists(x) or
not os.access(os.path.dirname(x), os.W_OK))
filesNotWrite = filter(notWriteBackup, checkNewBackupFiles)
filesNotWrite = [x for x in checkNewBackupFiles if notWriteBackup(x)]
if filesNotWrite:
raise MigrationError(_("Failed to write to files") + _(": ") +
", ".join(filesNotWrite))
@ -442,20 +413,20 @@ class migrate(object):
listFilesThisSystem = [migrateGroups.fileGroups,
migrateUsers.filePasswd,
migrateShadow.fileShadow]
listFiles = map(lambda x: (pathJoin(self.prefixNewSystem, x),
pathJoin(self.prefixNewSystem, x + "-")),
listFilesThisSystem)
listFiles = [(pathJoin(self.prefixNewSystem, x),
pathJoin(self.prefixNewSystem, x + "-")) for x
in listFilesThisSystem]
listData = [self.dataGroups, self.dataUsers, self.dataShadow]
allData = zip(listFiles, listData)
for fileNames, data in allData:
buff = "\n".join(map(lambda x: ":".join(x), data)) + "\n"
buff = "\n".join((":".join(x) for x in data)) + "\n"
for fileName in fileNames:
FD = open(fileName, "w+")
FD.write(buff)
FD.close()
def createUserGuest(self):
if filter(lambda x: int(x[2]) >= self.minSysId, self.dataUsers):
if [x for x in self.dataUsers if int(x[2]) >= self.minSysId]:
return True
else:
# add user guest
@ -472,17 +443,17 @@ class migrate(object):
"""Create home directories for all migreate users"""
def createHome(userdata):
perms = FilePermission.UserAll
if not userdata[5].startswith('/dev/'):
homedir = pathJoin(self.prefixNewSystem, userdata[5])
if not path.exists(homedir):
os.mkdir(homedir)
os.chown(homedir, int(userdata[2]), int(userdata[3]))
users = list(
set(map(lambda x: x[0],
addUsersList) + existsMigrateUsers) - {"root"})
os.chmod(homedir, perms)
users = list(set([x[0] for x in addUsersList] + existsMigrateUsers) - {"root"})
try:
map(createHome, filter(lambda x: x[0] in users, self.dataUsers))
# map(createHome, (x for x in self.dataUsers if x[0] in users))
[createHome(x) for x in self.dataUsers if x[0] in users]
except Exception as e:
raise MigrationError(
_("Failed to create the user's home directory"))
@ -500,8 +471,9 @@ class migrate(object):
existsMigrateUsers = []
if not self.checkPermFiles():
return False
migrateUsers = (["root"] +
map(lambda x: x[0], addUsersList + pwdUsersList))
migrateUsers = (["root"] + [x[0] for x in addUsersList + pwdUsersList])
for existMigrUser in existsMigrateUsers:
if existMigrUser not in migrateUsers:
migrateUsers.append(existMigrUser)
@ -509,7 +481,7 @@ class migrate(object):
dataUsers = self.objUsers.getNewProcessedData(migrateUsers)
dataGroups = self.objGroups.getNewProcessedData()
thisSystemUsers, newSystemUsers, newUsers, thisUsers = \
map(lambda x: map(lambda y: y[0], x), dataUsers)
[[y[0] for y in x] for x in dataUsers]
objShadow = migrateShadow(thisSystemUsers, newSystemUsers, newUsers,
thisUsers, self.prefixNewSystem)
dataShadow = objShadow.getNewProcessedData()
@ -545,7 +517,7 @@ class currentUsers(migrate):
"""Current users"""
def __init__(self):
super(currentUsers, self).__init__('/')
super().__init__('/')
def addUsers(self, *users_passwd):
"""Added users and groups to current system"""
@ -572,7 +544,5 @@ class currentUsers(migrate):
if not self.checkPermFiles():
return False
getDataInFile = _shareData().getDataInFile
self.dataUsers = map(lambda x: x[0],
getDataInFile(fileName=migrateUsers.filePasswd,
lenData=7))
self.dataUsers = [x[0] for x in getDataInFile(fileName=migrateUsers.filePasswd,lenData=7)]
return set(self.dataUsers) >= set(users)

@ -16,13 +16,14 @@
import sys
from calculate.core.server.func import Action, Tasks
from calculate.install.distr import DistributiveError
from calculate.install.migrate_users import MigrationError
from calculate.install.variables.autopartition import AutopartitionError
from ..distr import DistributiveError
from ..migrate_users import MigrationError
from ..variables.autopartition import AutopartitionError
from calculate.lib.utils.partition import VolumesError
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.files import FilesError
from calculate.install.install import InstallError
from ..install import InstallError
setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
@ -33,7 +34,7 @@ class ClInstallAction(Action):
Установка системы
"""
# ошибки, которые отображаются без подробностей
native_error = (FilesError, MigrationError, TemplatesError,
native_error = (FilesError, MigrationError, TemplatesError, VolumesError,
InstallError, AutopartitionError, DistributiveError)
successMessage = None
failedMessage = None
@ -44,11 +45,9 @@ class ClInstallAction(Action):
# авторазметка диска
{'name': 'autopartition',
'message': __("Creating a new partition table"),
'method': "Install.autopartition(cl_autopartition_table,"
"cl_autopartition_device,cl_autopartition_disk_data,"
"cl_autopartition_lvm_set,cl_autopartition_lvm_vgname,"
"cl_autopartition_bios_grub_set,"
"cl_autopartition_bios_grub_size)",
'method': "Install.autopartition(cl_autopartition_scheme_builder,"
"cl_autopartition_device,"
"cl_autopartition_disk_dev)",
'condition': lambda dv: dv.Get('cl_autopartition_set') == 'on'},
# форматирование разделов на которые устанавливается дистрибутив
{'name': 'format',
@ -115,6 +114,10 @@ class ClInstallAction(Action):
'method': 'Install.userMigrate(cl_target,cl_migrate_data,'
'cl_migrate_root_pwd)',
},
# прописывание локальных администраторов
{'name': 'hdd:write_admins',
'method': 'Install.update_admin_ini()',
},
# подготовка загрузчика
{'name': 'prepare_boot',
'message': __("Preparing the system for reboot"),

@ -16,14 +16,14 @@
import sys
from calculate.core.server.func import Action
from calculate.install.distr import DistributiveError
from calculate.install.migrate_users import MigrationError
from ..distr import DistributiveError
from ..migrate_users import MigrationError
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.files import FilesError
from calculate.lib.utils.portage import isPkgInstalled
from calculate.install.install import InstallError
from calculate.install.variables.autopartition import AutopartitionError
from ..install import InstallError
from ..variables.autopartition import AutopartitionError
setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
@ -42,18 +42,22 @@ class ClSetupVideoAction(Action):
failedMessage = __("Failed to configure the video settings!")
interruptMessage = __("Configuration manually interrupted")
addon_tasks = [
prev_tasks = [
# проверить и настроить параметры для nvidia драйвера
{'name': 'drop_xorg_log',
'method': 'Install.drop_xorg_logs()',
'condition': lambda Get: (
Get('os_install_x11_video_drv_prev')
!= Get('os_install_x11_video_drv'))
},
]
addon_tasks = [
{'name': 'check_video',
'message': __("Checking the video driver"),
'method': 'Install.checkVideoDriver()',
'condition': lambda: isPkgInstalled('xorg-server')
},
{'name': 'setup_opengl',
'message': __("Configuring OpenGL"),
'method': 'Install.setupOpenGL()',
'condition': lambda: isPkgInstalled('xorg-server')
},
{'name': 'setupvideo',
'condition': lambda Get: Get('cl_setup') == 'video'
},
@ -81,7 +85,7 @@ class ClSetupVideoAction(Action):
def __init__(self):
# список задач для действия
self.tasks = [
self.tasks = self.prev_tasks + [
{'name': 'apply_templates',
'message': self.templateTaskMessage,
# наложить шаблоны на текущий дистрибутив, включая clt шаблоны
@ -98,6 +102,7 @@ class ClSetupSystemAction(ClSetupVideoAction):
"""
Объект настройки всех параметров системы
"""
prev_tasks = []
templateTaskMessage = __("The system is being configured")
successMessage = __("System configured!")
failedMessage = __("Failed to configure the system!")
@ -108,16 +113,33 @@ class ClSetupAudioAction(ClSetupSystemAction):
Действие для настройки аудио параметров
"""
addon_tasks = []
prev_tasks = []
templateTaskMessage = __("The audio settings are being configured")
successMessage = __("Audio settings configured!")
failedMessage = __("Failed to configure the audio parameters!")
class ClSetupThemesAction(ClSetupSystemAction):
"""
Действие для настройки тем
"""
addon_tasks = []
prev_tasks = [
{'name': 'init_themes',
'method': 'Install.init_themes()'
},
]
templateTaskMessage = __("The themes are being configured")
successMessage = __("Themes configured!")
failedMessage = __("Theme configuration failed!")
class ClSetupLocaleAction(ClSetupSystemAction):
"""
Действие для настройки языковых параметров
"""
addon_tasks = []
prev_tasks = []
templateTaskMessage = \
__("The localization and time options are being configured")
successMessage = __("System configured!")
@ -152,6 +174,7 @@ class ClSetupBootAction(ClSetupSystemAction):
successMessage = __("Boot parameters configured!")
failedMessage = __("Failed to configure the boot parameters!")
prev_tasks = []
addon_tasks = [
# установить загрузчик
{'name': 'prepare_bootloader',
@ -166,13 +189,4 @@ class ClSetupBootAction(ClSetupSystemAction):
'warning': _("The builder mode is no longer supported"),
'condition': lambda Get: Get('os_install_scratch') == 'on'
},
# изменить IO планировщик
{'name': 'change_ioscheduler',
'message': _("Changing the I/O scheduler"),
'method': 'Install.changeScheduler(os_install_kernel_scheduler)',
'condition': (lambda dv: dv.Get('os_root_type') != 'livecd' and
dv.Select('os_disk_parent',
where='os_disk_mount',
eq='/', limit=1))
},
]

@ -18,9 +18,13 @@ import os
import sys
import re
from os import path
import hashlib
import glob
from calculate.lib.datavars import Variable, VariableError, ReadonlyVariable
from calculate.lib.utils.portage import isPkgInstalled
from calculate.lib.utils.files import readFile
from calculate.lib.utils.files import readFile, readFileEx
from calculate.lib.utils.tools import get_best_nearest_resolution
import calculate.lib.utils.device as device
from calculate.lib.utils.common import (getVideoFromXorgLog,
getVideoFromXorgConf,
getVideoFromCmdLine,
@ -29,7 +33,8 @@ from calculate.lib.utils.common import (getVideoFromXorgLog,
getVideoFromModules,
getVideoFromVendor, getInstalledVideo,
CmdlineParams)
from calculate.install.distr import DistributiveError
from calculate.lib.utils.video import get_edid_data, EdidInfoError, EdidInfo
from ..distr import DistributiveError
import fcntl
import struct
from collections import OrderedDict
@ -46,14 +51,14 @@ class VideoVariable(Variable):
xorg_need = True
default_video = "default"
driver_names = OrderedDict([
('default', _("X.Org Server auto detection")),
('default', _("Auto detection")),
('radeon', _("AMD Radeon (radeon)")),
('amdgpu', _("AMD AMDGPU (amdgpu)")),
('fglrx', _("AMD Catalyst (fglrx)")),
('modesetting', _("Framebuffer device (modesetting)")),
('vesa', _("Generic VESA (vesa)")),
('intel', _("Intel (intel)")),
('nouveau', _("Nvidia Nouveau (nouveau)")),
('nvidia', _("Nvidia Graphics Driver (nvidia)")),
('vesa', _("Generic VESA (vesa)")),
])
def uncompatible(self):
@ -85,8 +90,7 @@ class ResolutionVariable(VideoVariable):
"1600x900", "1600x1200", "2048x1152", "2560x1440",
"2560x1600"]
if self.fbres:
return map(lambda x: "%s-32" % x,
resolutions)
return ["%s-32" % x for x in resolutions]
else:
return resolutions
@ -101,7 +105,7 @@ class ResolutionVariable(VideoVariable):
example="(%s:%s)" % (_("Example"), "1024x768")))
class VariableOsInstallX11Resolution(ResolutionVariable):
class VariableOsInstallX11ResolutionPreferred(ResolutionVariable):
"""
X.org resolution
"""
@ -110,7 +114,7 @@ class VariableOsInstallX11Resolution(ResolutionVariable):
metavalue = "<width>x<height>"
# разрешение по умолчанию пустое - это нужно для livecd
# для автоопределения разрешения xorg сервером
fallback_resolution = ""
preferred_resolution = ""
def init(self):
self.help = _("set the Xorg resolution")
@ -119,12 +123,37 @@ class VariableOsInstallX11Resolution(ResolutionVariable):
def get(self):
# get resolution from xorg.log
res = self.Get('os_x11_resolution')
if res or self.Get('install.os_install_root_type') in (
'livecd', 'usb-hdd'):
return res or self.fallback_resolution
if res:
return res
else:
return self.fallback_resolution
return self.preferred_resolution
class VariableOsInstallX11Resolution(ResolutionVariable):
"""
X.org resolution
"""
fallback_resolution = "1024x768"
FBIOGET_VSCREENINFO = 0x4600
def framebuffer_resolution(self):
try:
fbdev = os.open('/dev/fb0', os.O_RDONLY)
data = fcntl.ioctl(fbdev, self.FBIOGET_VSCREENINFO, " " * 8)
res = struct.unpack("II", data)
return "%sx%s" % (res[0], res[1])
except (IOError, OSError):
pass
return ""
def get(self):
# get resolution from xorg.log
res = self.Get('install.os_install_x11_resolution_preferred')
if res:
return res
res = self.framebuffer_resolution()
if res:
return res
return self.fallback_resolution
class VariableOsInstallX11VideoAvailable(VideoVariable):
"""
@ -132,7 +161,8 @@ class VariableOsInstallX11VideoAvailable(VideoVariable):
"""
type = "list"
# supported = ["nvidia", "fglrx", "amdgpu", "nouveau", "intel", "radeon"]
supported = ["nvidia", "fglrx", "amdgpu", "nouveau", "intel", "radeon"]
supported = ["nvidia", "amdgpu","modesetting",
"nouveau", "intel", "radeon", "vesa"]
def get(self):
image = self.Get('cl_image')
@ -150,7 +180,7 @@ class VariableOsInstallX11VideoAvailable(VideoVariable):
return []
def humanReadable(self):
return map(lambda x: self.driver_names.get(x, x), self.Get())
return [self.driver_names.get(x, x) for x in self.Get()]
class VariableOsX11KmsVideoDrv(ReadonlyVariable):
@ -158,7 +188,7 @@ class VariableOsX11KmsVideoDrv(ReadonlyVariable):
Список KMS драйверов
"""
type = "list"
value = ["radeon", "intel", "nouveau", "amdgpu"]
value = ["radeon", "intel", "nouveau", "amdgpu", "modesetting"]
class VariableOsInstallX11VideoDrv(VideoVariable):
@ -173,14 +203,22 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
self.help = _("set the video driver")
self.label = _("Video driver")
def nox_video_drivers(self):
values = self.Get('os_x11_kms_video_drv')
for drv, drvinfo in self.pkgDrvMap.items():
_, pkgdrv = drvinfo
if isPkgInstalled(pkgdrv, prefix=self.Get('cl_chroot_path')):
values.append(drv)
return [self.default_video] + list(sorted(values))
def choice(self):
"""Get available (already installed or installable drivers"""
if self.Get('os_install_x11_server_set') == 'on':
values = self.Get('os_install_x11_video_available')
else:
values = self.Get('os_x11_kms_video_drv') + [self.default_video]
return map(lambda x: (x, self.driver_names.get(x, x)),
(x for x in self.driver_names.keys() if x in values))
values = self.nox_video_drivers()
return [(x, self.driver_names.get(x, x)) for x
in [y for y in self.driver_names.keys() if y in values]]
def get(self):
if self.Get('os_install_x11_server_set') == 'on':
@ -198,8 +236,8 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
# test current video driver for install system
methods = ((getVideoFromXorgLog, ('/', list_video)),
(getVideoFromXorgConf, ('/',)),
(getVideoFromModules, ()),
(getVideoFromCmdLine, ()),
(getVideoFromModules, ()),
(getVideoFromVendor,
(self.Get('hr_video'), list_video)))
for func, args in methods:
@ -208,9 +246,9 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
return drv
return self.default_video
else:
for drv in map(lambda x: x[0], self.choice()):
videoSysPath = path.join("/sys/module", drv, "refcnt")
refcnt = readFile(videoSysPath).strip()
for drv in (x[0] for x in self.choice()):
refcnt = device.sysfs.read(
device.sysfs.Path.Module, drv, "refcnt").strip()
if refcnt.isdigit() and int(refcnt) > 0:
return {'i915': 'intel'}.get(drv, drv)
else:
@ -237,8 +275,7 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
error += "\n" + ("emerge %s" % self.pkgDrvMap[value][1])
raise VariableError(error)
else:
availDrivers = self.Get('os_x11_kms_video_drv') + [
self.default_video]
availDrivers = self.nox_video_drivers()
if not value in availDrivers:
raise VariableError("Only %s drivers are available" %
",".join(availDrivers))
@ -253,6 +290,12 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
return ""
class VariableOsInstallX11VideoDrvPrev(VariableOsInstallX11VideoDrv):
"""
Предыдущее значение os_install_x11_videodrv
"""
class VariableHrVideoId(ReadonlyVariable):
"""
BusID of video card
@ -274,7 +317,8 @@ class VariableOsInstallX11Composite(VideoVariable):
def get(self):
"""On/off composite"""
defaultCompositeOn = ("nvidia", "intel", "fglrx", # "amdgpu",
defaultCompositeOn = ("nvidia", "intel", "fglrx", "amdgpu",
"modesetting",
"nouveau", "radeon", "default")
composite = getValueFromCmdLine(CmdlineParams.Calculate,
CmdlineParams.Composite)
@ -300,6 +344,30 @@ class VariableOsInstallX11Composite(VideoVariable):
state = None
return composite or state or defaultComposite
class VariableOsInstallFbResolutionPreferred(ResolutionVariable):
"""
Framebuffer resolution
"""
type = 'choiceedit'
opt = ['--fb']
metavalue = "<width>x<height>"
xorg_need = False
fbres = True
value = "auto"
def init(self):
self.help = _("set the framebuffer resolution")
self.label = _("Framebuffer resolution")
def choice(self):
yield ("auto", _("Auto"))
for i in ResolutionVariable.choice(self):
yield (i,i)
def check(self, value):
if value == "auto":
return
ResolutionVariable.check(self, value)
class VariableOsInstallFbResolution(ResolutionVariable):
"""
@ -310,20 +378,174 @@ class VariableOsInstallFbResolution(ResolutionVariable):
metavalue = "<width>x<height>"
xorg_need = False
fbres = True
fallback_resolution = "1024x768"
def init(self):
self.help = _("set the framebuffer resolution")
self.label = _("Framebuffer resolution")
FBIOGET_VSCREENINFO = 0x4600
def using_kms(self):
drv = self.Get('install.os_install_x11_video_drv')
kms = self.Get('install.os_x11_kms_video_drv')
return drv in kms
def using_uefi(self):
return self.GetBool('install.os_install_uefi_set')
def get(self):
"""Get current framebuffer resolution"""
custom = self.Get('os_install_fb_resolution_preferred')
if custom != "auto":
return custom
x11res = self.Get('os_install_x11_resolution')
if self.using_kms() or self.using_uefi():
return x11res
hwinfo = device.Hwinfo()
try:
fbdev = os.open('/dev/fb0', os.O_RDONLY)
data = fcntl.ioctl(fbdev, self.FBIOGET_VSCREENINFO, " " * 8)
res = struct.unpack("II", data)
return "%sx%s" % (res[0], res[1])
except (IOError, OSError):
return get_best_nearest_resolution(
x11res, hwinfo.resolutions()) or self.fallback_resolution
except (ZeroDivisionError, device.HwinfoError):
return self.fallback_resolution
class VariableClGrubImageHash(ReadonlyVariable):
"""
Контрольная сумма изображения для grub
"""
grub_image = "/boot/grub/grub-calculate.png"
theme_data = "/etc/grub.d/05_theme"
def get_image_md5(self, source):
return hashlib.md5(readFile(source, binary=True)).hexdigest()
def get_config_md5(selfself, source):
return hashlib.md5(readFileEx(source, grab=True)).hexdigest()
def get_checksum(self):
data = []
if path.exists(self.grub_image):
data.append(self.get_image_md5(self.grub_image))
else:
data.append("-")
if path.exists(self.theme_data):
data.append(self.get_config_md5(self.theme_data))
else:
data.append("-")
return "".join(data)
def get(self):
if self.Get('cl_setup') == 'themes':
return self.get_checksum()
return ""
class VariableClGrubImageUpdateSet(VariableClGrubImageHash):
"""
Изображение для grub обновлилось
"""
def get(self):
if self.Get('cl_setup') == 'themes':
newmd5 = self.get_checksum()
return "on" if newmd5 != self.Get('cl_grub_image_hash') else "off"
return "off"
class VariableClSplashImageHash(ReadonlyVariable):
"""
Контрольные суммы изображений для splashutils
"""
hash_files = ("/etc/splash/calculate/images/verbose.md5",
"/etc/splash/calculate/images/silent.md5",
"/usr/share/plymouth/themes/calculate/boot.md5",
"/usr/share/plymouth/themes/calculate/boot/md5sum",
"/usr/share/plymouth/themes/calculate/calculate.plymouth")
cfg_files = "/etc/splash/calculate/*.cfg"
def get_config_md5(selfself, source):
return hashlib.md5(readFileEx(source, grab=True)).hexdigest()
def get_hash_data(self, sources):
data = []
for fn in sources:
data.append(self.get_config_md5(fn))
for fn in glob.glob(self.cfg_files):
data.append(self.get_config_md5(fn))
break
return "".join(data)
def get(self):
if self.Get('cl_setup') == 'themes':
return self.get_hash_data(self.hash_files)
return ""
class VariableClSplashImageUpdateSet(VariableClSplashImageHash):
"""
Изображение для splash dracut обновлилось
"""
def get(self):
if self.Get('cl_setup') == 'themes':
newmd5 = self.get_hash_data(self.hash_files)
return "on" if newmd5 != self.Get('cl_splash_image_hash') else "off"
return "off"
class VariableClInstallEdidData(ReadonlyVariable):
type = Variable.Types.Object
def get(self):
edid_data = get_edid_data()
if not edid_data:
return {}
try:
ei = EdidInfo()
ei.set_data(edid_data)
return {
"resolution": ei.resolution,
"ratio": ei.ratio,
"screensize": ei.screensize
}
except EdidInfoError as e:
return {}
class VariableClInstallEdidResolution(ReadonlyVariable):
def get(self):
return self.Get('cl_install_edid_data').get('resolution','')
class VariableClInstallEdidScreensize(ReadonlyVariable):
def get(self):
return self.Get('cl_install_edid_data').get('screensize','')
class VariableClInstallCalculateDpi(Variable):
def get(self):
inch = 25.4
screensize = self.Get('cl_install_edid_screensize')
resolution = self.Get('os_install_x11_resolution')
if screensize and resolution:
cx = screensize.partition("x")[0]
cxres = resolution.partition("x")[0]
if cx.isdigit() and cxres.isdigit():
cx = float(cx)
cxres = float(cxres)
return str(int(inch * cxres / cx))
return ""
class VariableClInstallDpi(Variable):
def get(self):
calculate_dpi = self.Get('cl_install_calculate_dpi')
try:
if calculate_dpi:
calculate_dpi = int(calculate_dpi)
if calculate_dpi > 100:
return "108"
except ValueError:
pass
return "96"
class VariableClInstallScaling(Variable):
def get(self):
dpi = self.Get('cl_install_dpi')
try:
if dpi:
dpi = int(dpi)
if dpi > 100:
return "hi"
except ValueError:
pass
return "1024x768"
return "normal"

@ -14,17 +14,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import action
import disk
import locale
import linux
import distr
import kernel
import net
import system
import X11
import lvm
import autopartition
import audio
from . import action
from . import disk
from . import locale
from . import linux
from . import distr
from . import kernel
from . import net
from . import system
from . import X11
from . import lvm
from . import autopartition
from . import audio
section = "install"

@ -21,6 +21,7 @@ from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3', sys.modules[__name__])
ServerSetup = "server_setup"
class VariableAcInstallMerge(ActionVariable):
"""
@ -33,7 +34,8 @@ class VariableAcInstallMerge(ActionVariable):
self.Get('os_install_root_type') != 'flash' and
self.Get('os_install_pxe') == 'off' and
self.Get('cl_live') == 'off' or
cl_action in ("sync", "domain", "undomain")
cl_action in (ServerSetup, "sync",
"domain", "undomain",)
and self.Get('cl_merge_pkg')):
return "on"
return "off"
@ -51,12 +53,24 @@ class VariableAcInstallLive(ActionVariable):
if (cl_action in ("system", "merge") and
self.Get('os_install_root_type') != 'flash' and
self.Get('os_install_pxe') == 'off' or
cl_action in ("sync", "domain", "undomain")
cl_action in (ServerSetup,
"sync", "domain", "undomain",)
and self.Get('cl_merge_pkg')):
return "on"
return "off"
class VariableAcInstallConfig(ActionVariable):
"""
Action variable which has value "on" for emerge --config
cl-config
"""
def action(self, cl_action):
if cl_action in ("config",):
return "on"
return "off"
class VariableAcInstallDisk(ActionVariable):
"""
Action variable which has value "on" for installation on hdd

@ -19,9 +19,11 @@ import re
from calculate.lib.datavars import (Variable, ReadonlyVariable,
ReadonlyTableVariable, FieldValue,
HumanReadable)
from calculate.lib.utils.common import getValueFromCmdLine, CmdlineParams
from calculate.lib.utils.portage import isPkgInstalled
from calculate.lib.utils.files import readFile
from calculate.install.distr import DistributiveError
from calculate.lib.utils.files import readFile, readLinesFile
from ..distr import DistributiveError
import glob
from calculate.lib.cl_lang import setLocalTranslate, _
@ -41,13 +43,33 @@ class VariableOsAudio(Variable):
self.help = _("set the audio system")
def get(self):
return self.choice()[0][0]
"""
pipewire по умолчанию если доступно или вписано в /etc/asound.conf
"""
avail = [x[0] for x in self.Get('os_audio_available')]
if "pipewire" in avail:
audio = getValueFromCmdLine(CmdlineParams.Calculate,
CmdlineParams.Audio)
def set(self, value):
return {'none': ''}.get(value, value)
if audio and audio == "alsa":
return "alsa"
else:
return "pipewire"
return "alsa"
def choice(self):
return self.Get('os_audio_available') or [('',_('None'))]
return self.Get('os_audio_available')
def uncompatible(self):
"""
Audio setting up unavailable for flash installation
"""
if self.Get('os_install_root_type') == 'flash':
return _("Audio configuration unavailable for Flash install")
if self.Get('os_install_alsa_set') == 'off':
return _("This distribution does not provide the ALSA sound")
return ""
class VariableOsAudioAvailable(Variable):
@ -57,21 +79,32 @@ class VariableOsAudioAvailable(Variable):
type = "list"
def get(self):
mapAudioConf = (('pulseaudio', 'media-sound/pulseaudio',
_("PulseAudio")),
('alsa', 'media-sound/alsa-utils', _('ALSA')))
mapAudioConf = (
('alsa', None, _('ALSA')),
('pipewire', 'media-video/pipewire', _("PipeWire")),
)
image = self.Get('cl_image')
if image:
with image as distr:
try:
distrPath = image.getDirectory()
return map(lambda x:x[0::2],
filter(lambda x: not x[1] or isPkgInstalled(x[1],
prefix=distrPath),
mapAudioConf))
return [x[0::2] for x
in mapAudioConf
if not x[1] or isPkgInstalled(x[1], prefix=distrPath)]
except DistributiveError as e:
pass
return sorted(map(lambda x:x[0::2], mapAudioConf[-1:]), key=lambda x:x[1])
return sorted((x[0::2] for x in mapAudioConf[-1:]), key=lambda x: x[1])
class VariableOsAudioCardMap(ReadonlyVariable):
"""
Соответствие номеров звуковых карт именам
"""
type = Variable.Types.Table
def get(self):
return [(cardid[17:-3], readFile(cardid).strip())
for cardid in glob.glob('/proc/asound/card[0-9]*/id')]
class VariableOsAudioData(ReadonlyTableVariable):
@ -81,11 +114,28 @@ class VariableOsAudioData(ReadonlyTableVariable):
source = ['os_audio_id',
'os_audio_name']
def generate_cards(self, cards):
for card_id, card_name in cards:
for playback_info in glob.glob(
"/proc/asound/card%s/pcm[0-9]p/info" % card_id):
dInfo = (x.partition(":")[::2]
for x in readLinesFile(playback_info))
dInfo = {x.strip(): y.strip() for x, y in dInfo}
if all(x in dInfo for x in ('card', 'device', 'name')):
if card_name == dInfo['name']:
yield ("%s,%s" % (dInfo['card'], dInfo['device']),
"%s" % card_name)
else:
yield ("%s,%s" % (dInfo['card'], dInfo['device']),
"%s, %s" % (card_name, dInfo['name']))
def get(self, hr=HumanReadable.No):
# /proc/asound/card*/pcm*p/info
data = readFile('/proc/asound/cards')
cards = re.findall('^\s*(\d+).*\n\s+(\S.*) at .*$', data, re.M)
cards = re.findall('^\s*(\d+).*\s-\s(.+)\n\s+\S.* at .*$',
data, re.M)
if cards:
return map(list, cards)
return list(self.generate_cards(cards))
else:
return [[]]
@ -110,44 +160,85 @@ class VariableOsAudioName(FieldValue, ReadonlyVariable):
column = 1
class VariableOsAudioDefaultSet(ReadonlyVariable):
class VariableOsAudioCardDefault(Variable):
"""
Force write in config 0
Идентификатор карты по умолчанию
"""
type = "bool"
def get(self):
audio_default = self.Get('os_audio_default')
if audio_default and audio_default != "none":
cardmap = dict(self.Get("os_audio_card_map"))
cardnum = audio_default.split(',')[0]
if cardnum in cardmap:
return cardmap[cardnum]
return "0"
return ""
class VariableOsAudioDeviceDefault(Variable):
"""
Номер устройства по умолчанию
"""
def get(self):
res = self.Select('os_audio_id', where='os_audio_name',
notlike='HDMI', limit=1)
audio_default = self.Get('os_audio_default')
if (audio_default != '0' or
res and res != "0" and audio_default == '0' or
audio_default != self.Get('os_audio_current')):
return 'on'
return 'off'
if audio_default and audio_default != "none":
return self.Get('os_audio_default').split(',')[1]
return ""
class VariableOsAudioCardNameDefault(Variable):
"""
Название карты используемое в настройках KDE
"""
def get(self):
try:
audio_default = self.Get('os_audio_default')
if audio_default and audio_default != "none":
cardnum = int(audio_default.split(',')[0])
audionames = self.Get('os_audio_name')
if cardnum < len(audionames):
return audionames[cardnum].split(',')[0]
except ValueError:
pass
return ""
class VariableOsAudioCurrent(ReadonlyVariable):
class VariableOsAudioHw(Variable):
"""
Current default audio card
"""
def get(self):
def get_deprecated(self):
asound_data = readFile('/etc/asound.conf')
default_card_re = re.compile('defaults.ctl.card\s+(\d+)')
entry = default_card_re.search(readFile('/etc/asound.conf'))
entry = default_card_re.search(asound_data)
if entry and entry.groups()[0] in self.Get('os_audio_id'):
return entry.groups()[0]
res = self.Select('os_audio_id', where='os_audio_name',
notlike='HDMI', limit=1)
return res or '0'
return "%s,0" % entry.groups()[0]
default_card_re = re.compile(
'pcm.!default {[^}]+card\s+(\d+)[^}]+device\s+(\d+)[^}]+}')
entry = default_card_re.search(asound_data)
if entry:
entry = "%s,%s" % entry.groups()
if entry in self.Get('os_audio_id'):
return entry
return ""
def get(self):
cardmap = dict(self.Get("os_audio_card_map"))
value = self.get_deprecated()
if not value:
value = self.Select('os_audio_id', where='os_audio_name',
notlike='HDMI', limit=1) or "0,0"
cardnum, devicenum = value.split(",")
if cardnum in cardmap:
return "{},{}".format(cardmap[cardnum], devicenum)
return ""
class VariableOsAudioDefault(Variable):
"""
Current default audio card
"""
type = "choice"
opt = ['--audio-card']
opt = ['--card']
metavalue = "CARD"
def init(self):
@ -155,13 +246,22 @@ class VariableOsAudioDefault(Variable):
self.help = _("set the default audio")
def get(self):
return self.Get('os_audio_current')
current = self.Get('os_audio_hw')
if current and "," in current:
cardmap = {y:x for x, y in self.Get("os_audio_card_map")}
cardid, devicenum = current.split(",")
if cardid in cardmap:
return "{},{}".format(cardmap[cardid], devicenum)
data = self.Get('os_audio_data')
if data and data[0]:
return "0,0"
return "none"
def choice(self):
data = self.Get('os_audio_data')
if data and data[0]:
return self.Get('os_audio_data')
return []
return [("none", _("Not available"))]
def uncompatible(self):
"""
@ -170,6 +270,5 @@ class VariableOsAudioDefault(Variable):
if self.Get('os_install_root_type') == 'flash':
return _("Audio configuration unavailable for Flash install")
if self.Get('os_install_alsa_set') == 'off':
return \
_("This distribution does not provide the ALSA sound")
return _("This distribution does not provide the ALSA sound")
return ""

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -21,26 +21,30 @@ import re
import operator
from operator import itemgetter
from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
CommonVariableError)
CommonVariableError, BuildAlreadyInstalledError)
from calculate.lib.utils.common import (getSupportArch, getTupleVersion,
cmpVersion)
cmpVersion, cmp)
from calculate.lib.utils.files import listDirectory, pathJoin
from calculate.lib.utils.grub import GrubCommand
from calculate.lib.variables.linux import Linux
from calculate.install.distr import (Distributive, PartitionDistributive,
from ..distr import (Distributive, PartitionDistributive,
DirectoryDistributive, DefaultMountPath,
DistributiveError, FlashDistributive,
ArchiveDistributive,
MultiPartitions, PxeDistributive)
from calculate.lib.cl_lang import setLocalTranslate, _
from calculate.install.fs_manager import FileSystemManager
from ..fs_manager import FileSystemManager
from functools import reduce, cmp_to_key
setLocalTranslate('cl_install3', sys.modules[__name__])
class DistroRepository(Linux):
contentCache = {}
marches = ['i686', 'x86_64']
marches = ['x86_64']
extensiton = ['iso', 'tar.bz2', 'tar.gz', 'tar.7z', 'tar.lzma']
@ -91,11 +95,10 @@ class DistroRepository(Linux):
def _getAvailableShortnames(self, dirs):
"""Get available distributives shortnames"""
distros = filter(lambda x: x,
map(self.reDistName.search,
self._getAvailableDistributives(dirs)))
return sorted(list(set(map(lambda x: x.groupdict()['name'], distros))))
distros = [x for x
in map(self.reDistName.search, self._getAvailableDistributives(dirs))
if x]
return sorted(list(set([x.groupdict()['name'] for x in distros])))
def opcompareByString(self, buf):
if buf:
reOp = re.compile("^(!=|=|==|<=|>=|>|<)?(\d+.*)$")
@ -159,29 +162,27 @@ class DistroRepository(Linux):
return [pathname]
else:
# discard inner directories
return filter(lambda x: not path.isdir(path.join(pathname, x)),
listDirectory(pathname))
return [x for x in listDirectory(pathname) if not path.isdir(path.join(pathname, x))]
# get lists files in directories
allFiles = map(lambda x: map(lambda y: path.join(x, y),
listdistr(x)),
dirs)
allFiles = [[path.join(x, y) for y in listdistr(x)] for x in dirs]
# filter distributives
return filter(distfilter,
# join files lists to one list
reduce(lambda x, y: x + y,
allFiles, []))
# join files lists to one list
return [x for x in reduce(lambda x, y: x + y, allFiles, []) if distfilter(x)]
def extcomparator(self, *exts):
@staticmethod
def extcomparator(ext1, ext2):
"""Compare extensions"""
mapExts = {'iso': 0,
'flash': -1,
'isodir': -2,
'partdir': -3,
'dir': -4}
return cmp(mapExts.get(exts[0], -4), mapExts.get(exts[1], -4))
return cmp(mapExts.get(ext1, -4), mapExts.get(ext2, -4))
def sortdistrfunc(self, x, y):
@staticmethod
def sortdistrfunc(x, y):
"""Func of comparing two distributive"""
ver1, ver2 = x[1].get('os_linux_ver', ""), y[1].get('os_linux_ver', "")
if ver1 and ver2 and ver1 != "0" and ver2 != "0" and ver1 != ver2:
@ -197,7 +198,7 @@ class DistroRepository(Linux):
return cmp(int(ser1), int(ser2))
ext1 = x[1].get('ext', "")
ext2 = y[1].get('ext', "")
return self.extcomparator(ext1, ext2)
return DistroRepository.extcomparator(ext1, ext2)
def getAvailableDristibutives(self, dirs, system=None, shortname=None,
march=None, version=None, build=None,
@ -208,12 +209,10 @@ class DistroRepository(Linux):
availDistrs = self._getAvailableDistributives(dirs, system, shortname,
march, version,
build)
availDistrs = filter(lambda x: x[1] and "ext" in x[1] and
not x[1]["ext"] in discardType,
map(lambda x: (x, self._getDistrInfo(x)),
availDistrs))
return map(lambda x: x[0],
sorted(availDistrs, self.sortdistrfunc, reverse=True))
availDistrs = (x for x
in [(y, self._getDistrInfo(y)) for y in availDistrs]
if x[1] and "ext" in x[1] and not x[1]["ext"] in discardType)
return [x[0] for x in sorted(availDistrs, key=cmp_to_key(DistroRepository.sortdistrfunc), reverse=True)]
def getBestDistributive(self, dirs, system=None, shortname=None, march=None,
version=None, build=None, discardType=()):
@ -229,13 +228,13 @@ class DistroRepository(Linux):
def _findLatestFile(self, dirs, reMatch, keyfunc):
"""Find latest file in dirs, which match by reMatch,
comparable part get by keyfunc"""
existsdirs = filter(path.exists, dirs)
listimgs = reduce(lambda x, y: x + map(
existsdirs = list(filter(path.exists, dirs))
listimgs = reduce(lambda x, y: x + list(map(
lambda x: reMatch.search(
path.join(y, x)),
listDirectory(y)),
listDirectory(y))),
existsdirs, [])
listimgs = filter(lambda x: x, listimgs)
listimgs = [x for x in listimgs if x]
if listimgs:
return max(listimgs, key=keyfunc).group()
return ""
@ -315,11 +314,21 @@ class VariableClImageFilename(DistroRepository, Variable):
"""Set image file"""
if self.Get('cl_action') == 'system' and not isoimage:
raise VariableError(_("You need to select a distribution image"))
try:
d = Distributive.fromFile(isoimage)
if isinstance(d, ArchiveDistributive):
raise VariableError(_("Wrong image file"))
except DistributiveError:
pass
imageData = Distributive().getInfo(isoimage)
if not ("os_linux_shortname" in imageData and
imageData.get('os_linux_build', '') and
"os_arch_machine" in imageData):
raise VariableError(_("Wrong image file"))
if imageData["os_chrootable_set"] == 'off':
raise VariableError(
_("The image is not compatible with the current kernel"))
def humanImageName(self, distroinfo, filepath):
if all(x in distroinfo for x in ("os_linux_shortname",
@ -371,9 +380,7 @@ class VariableClImageFilename(DistroRepository, Variable):
discardType=discardType)
if self.wasSet and not self.value in distros:
distros.append(self.value)
return sorted(map(lambda x: (
x, self.humanImageName(self._getDistrInfo(x), x)), distros),
key=itemgetter(1))
return sorted(((x, self.humanImageName(self._getDistrInfo(x), x)) for x in distros), key=itemgetter(1))
class VariableClImageArchMachine(DistroRepository, Variable):
@ -384,7 +391,7 @@ class VariableClImageArchMachine(DistroRepository, Variable):
type = 'choice'
opt = ['--march']
metavalue = "ARCH"
available_arch = ["i686", "x86_64"]
available_arch = ["x86_64"]
def init(self):
self.label = "%s %s" % (_("Filter"), _("by processor architecture"))
@ -488,21 +495,17 @@ class VariableClImagePath(ReadonlyVariable):
livedistr = ['/run/initramfs/squashfs',
'/run/initramfs/live',
'/mnt/cdrom']
livedistr = filter(listDirectory,
livedistr)[:1]
livedistr = [x for x in livedistr if listDirectory(x)][:1]
else:
livedistr = []
# search all partition for source installation distributive
rootDev = self.Get('os_install_root_dev')
livedistr += \
map(lambda x: x[0],
filter(lambda x: " live" in x[1] and x[0] != rootDev,
zip(self.Get('os_disk_dev'),
self.Get('os_disk_content'))))
livedistr += [x[0] for x
in zip(self.Get('os_disk_dev'), self.Get('os_disk_content'))
if " live" in x[1] and x[0] != rootDev]
# add to standard path
return filter(path.exists,
['/var/calculate/remote/linux',
'/var/calculate/linux'] + livedistr)
return [x for x in ['/var/calculate/remote/linux',
'/var/calculate/linux'] + livedistr if path.exists(x)]
class VariableClSource(ReadonlyVariable):
@ -520,6 +523,7 @@ class VariableClTarget(ReadonlyVariable):
Target distributive
"""
type = "object"
filesystem = "cl_target_fs"
def get(self):
listVars = ['os_install_disk_dev', 'os_install_disk_mount',
@ -533,9 +537,10 @@ class VariableClTarget(ReadonlyVariable):
flashLabel = "{short}-{build}".format(
short="CL", build=self.Get('os_install_linux_build'))
disk = self.Get('os_install_disk_single')
fileSystem = "vfat"
fileSystem = self.Get(self.filesystem) or 'ntfs'
#fileSystem = "vfat"
systemId = FileSystemManager.supportFS.get(
'vfat', {}).get('msdos', '0b')
fileSystem, {}).get('msdos', '0b')
isFormat = self.GetBool('os_install_format_single_set')
partTable = self.select('os_disk_part',
os_disk_dev=disk, limit=1)
@ -564,7 +569,8 @@ class VariableClTarget(ReadonlyVariable):
rootLabel=rootLabel,
isFormat=self.isTrue(isFormat),
systemId=systemId,
partitionTable=partTable)
partitionTable=partTable,
compression=self.Get('os_install_btrfs_compression'))
multiPartition = None
diskData = self.Select(listVars,
where='os_install_disk_mount',
@ -595,6 +601,27 @@ class VariableClTarget(ReadonlyVariable):
return target
class VariableClTargetFs(Variable):
type = 'choice'
opt = ['--fs']
disk = 'os_install_disk_single'
value = 'auto'
metavalue = 'FS_NAME'
def init(self):
self.label = _("File system on flash device")
self.help = _("Create new FS on flash device(formating req)")
def get(self):
if self.value != 'auto':
return self.value
return 'vfat'
def choice(self):
return ['vfat', 'btrfs', 'ntfs', 'ext4',
'ext3', 'ext2', 'xfs']
class VariableClImageNewOnly(Variable):
"""
Distributive image filename
@ -630,10 +657,13 @@ class VariableClImageNewOnly(Variable):
except Exception as e:
raise VariableError(_("Wrong image file"))
if imageData.get('os_linux_build', '') <= \
self.Get('os_linux_build') or \
imageData.get('os_linux_build',
'') <= self.installedBuild():
self.Get('os_linux_build'): #or \
# imageData.get('os_linux_build',
# '') <= self.installedBuild():
raise CommonVariableError(_("The image for update not found"))
if imageData.get('os_linux_build', '') <= self.installedBuild():
raise BuildAlreadyInstalledError(_("Build already installed"))
class VariableClInstallPathFrom(ReadonlyVariable):

@ -24,6 +24,7 @@ from calculate.lib.datavars import (Variable, ReadonlyVariable,
from calculate.lib.utils.files import (readFile,
typeFile, process, listDirectory,
MAGIC_SYMLINK, MAGIC_COMPRESS)
from calculate.lib.utils.kernel import InitrdFile
from calculate.lib.cl_lang import setLocalTranslate
@ -35,7 +36,7 @@ from calculate.lib.utils.files import readLinesFile
from calculate.lib.utils.common import (getKernelUid, getTupleVersion,
getValueFromCmdLine, CmdlineParams)
from itertools import *
from calculate.install.distr import DistributiveError
from ..distr import DistributiveError
class VariableOsInstallKernelScheduler(Variable):
@ -56,10 +57,10 @@ class VariableOsInstallKernelScheduler(Variable):
eq='on')
def get_default(self):
root_dev = self.Select('os_install_disk_parent',
root_devs = self.Select('os_install_disk_parent',
where='os_install_disk_mount',
eq='/', limit=1)
if root_dev:
eq='/', limit=1).split(',')
for root_dev in root_devs:
dev_ssd, dev_virtual = self.Select(['os_device_ssd_set',
'os_device_virtual_set'],
where='os_device_dev',
@ -76,7 +77,7 @@ class VariableOsInstallKernelScheduler(Variable):
else:
currentScheduler = getValueFromCmdLine(
CmdlineParams.IOScheduler)
if currentScheduler in map(lambda x: x[0], self.choice()):
if currentScheduler in (x[0] for x in self.choice()):
return currentScheduler
return self.Get('os_install_kernel_schedule_default')
@ -103,7 +104,7 @@ class VariableOsInstallKernelScheduler(Variable):
return _("I/O scheduler unavailable for Flash install")
class KernelConfig:
class KernelConfig():
def __init__(self, kernel_config):
self.data = readFile(kernel_config).split('\n')
self.config = kernel_config
@ -114,6 +115,9 @@ class KernelConfig:
def __str__(self):
return "kernel config (%s)" % self.config
def __len__(self):
return len(self.data)
def __contains__(self, item):
if "=" in item:
if item.endswith("=n"):
@ -220,9 +224,9 @@ class VariableOsInstallKernelScheduleData(ReadonlyTableVariable):
'CONFIG_IOSCHED_NOOP=y': 'noop',
'CONFIG_IOSCHED_CFQ=y': 'cfq',
'CONFIG_IOSCHED_DEADLINE=y': 'deadline'}
installed = map(schedulers.get,
filter(lambda x: x in schedulers,
self.Get('os_install_kernel_config'))) or ['cfq']
installed = [schedulers.get(x) for x
in self.Get('os_install_kernel_config')
if x in schedulers] or ['cfq']
return [[x, "on" if x in installed else "off"]
for x in sorted(schedulers.values())]
@ -273,25 +277,32 @@ class VariableOsInstallKernelBfqSet(ReadonlyVariable):
return "off"
class VariableOsInstallNomodeset(Variable):
type = "bool"
def get(self):
cmdLine = '/proc/cmdline'
if 'nomodeset' in readFile(cmdLine):
return "on"
return "off"
class VariableOsInstallKernelAttr(Variable):
"""
Install kernel attributes
"""
def get(self):
# on usb-hdd install must be "delay=5"
attr = ""
rdauto = ""
if self.Get('os_install_root_type') == 'usb-hdd':
attr = " scandelay=5"
if self.Get('os_install_mdadm_set') == 'on':
attr += " domdadm"
rdauto = " rd.auto"
if self.Get('os_install_lvm_set') == 'on':
attr += " dolvm"
if not rdauto:
rdauto = " rd.auto"
return attr + rdauto
def generate():
# 5 sec for usb hdd boot
if self.GetBool('os_install_nomodeset'):
yield "nomodeset"
if self.Get('os_install_root_type') == 'usb-hdd':
yield "scandelay=5"
if (self.GetBool('os_install_mdadm_set') or
self.GetBool('os_install_lvm_set')):
yield "rd.auto"
yield "rd.retry=40"
return " ".join(generate())
class VariableOsInstallKernelResume(ReadonlyVariable):
@ -301,14 +312,18 @@ class VariableOsInstallKernelResume(ReadonlyVariable):
def get(self):
"""install kernel resume parameter"""
for dev, install in zip(self.Get('os_install_disk_use'),
self.Get('os_install_disk_mount')):
for dev, partuuid, install in zip(self.Get('os_install_disk_use'),
self.Get('os_install_disk_partuuid'),
self.Get('os_install_disk_mount')):
if install == "swap":
if self.Get('os_install_kernel_tuxonice_set') == 'on':
return "tuxonice tuxonice_resume=%s real_resume=%s" % (
dev, dev)
else:
return "real_resume=%s" % dev
if partuuid:
return "resume=PARTUUID=%s" % partuuid
else:
return "resume=%s" % dev
return ""
@ -321,12 +336,14 @@ class KernelHelper(VariableInterface):
def getFilesByType(self, pathname, descr):
"""Get files from "pathname" has "descr" in descriptions"""
filelist = map(lambda x: path.join(pathname, x), os.listdir(pathname))
filelist = [path.join(pathname, x) for x in os.listdir(pathname)]
ftype = typeFile(magic=MAGIC_COMPRESS | MAGIC_SYMLINK).getMType
filesWithType = map(lambda x: (x, ftype(x)),
filter(path.exists,
filelist))
return filter(lambda x: descr in x[1], filesWithType)
filesWithType = [(x, ftype(x)) for x in filelist if path.exists(x)]
return [x for x in filesWithType if x[1] and descr in x[1]]
def getInitrdFiles(self, pathname):
filelist = [path.join(pathname, x) for x in os.listdir(pathname)]
return [x for x in filelist if path.exists(x) and InitrdFile.is_cpio(x)]
def getInitrd(self, arch, shortname, chroot, kernel, suffix="",
notsuffix=""):
@ -352,15 +369,13 @@ class KernelHelper(VariableInterface):
origKernelVer = resKernelVer.group()
bootdir = path.join(chroot, 'boot')
initramfsFiles = self.getFilesByType(bootdir, "ASCII cpio archive")
initramfsWithVer = \
filter(lambda x: (kernelVersion in x[1] or
origKernelVer in x[1]) and \
x[0].endswith(suffix) and \
(
not notsuffix or not x[0].endswith(notsuffix)),
map(lambda x: (x[0], initrd_version_by_name(x[0])),
initramfsFiles))
initramfsFiles = self.getInitrdFiles(bootdir)
initramfsWithVer = [x for x
in [(y, initrd_version_by_name(y)) for y in initramfsFiles]
if (kernelVersion in x[1] or
origKernelVer in x[1]) and
x[0].endswith(suffix) and
(not notsuffix or not x[0].endswith(notsuffix))]
if initramfsWithVer:
return path.split(min(initramfsWithVer,
key=itemgetter(0))[0])[-1]
@ -378,18 +393,28 @@ class VariableOsInstallKernel(ReadonlyVariable, KernelHelper):
validKernel = listDirectory(modulesdir)
kernelFiles = self.getFilesByType(bootdir, "Linux kernel")
installMarch = self.Get('os_install_arch_machine')
kernelsWithVer = \
map(lambda x: (
x[0], (getTupleVersion("".join(x[1].groups()[0:3:2])),
path.getmtime(x[0]))),
# convert version to tuple( versionTuple, mtime)
# version detect, for this version lib contains moudules
# kernel arch equal install arch
ifilter(lambda x: x[1] and x[1].group() in validKernel and
installMarch in x[0].rpartition('/')[2],
# (filename,version)
imap(lambda x: (x[0], self.reFindVer.search(x[1])),
kernelFiles)))
# kernelsWithVer = \
# list(map(lambda x: (
# x[0], (getTupleVersion("".join(x[1].groups()[0:3:2])),
# path.getmtime(x[0]))),
# # convert version to tuple( versionTuple, mtime)
# # version detect, for this version lib contains moudules
# # kernel arch equal install arch
# filter(lambda x: x[1] and x[1].group() in validKernel and
# installMarch in x[0].rpartition('/')[2],
# # (filename,version)
# map(lambda x: (x[0], self.reFindVer.search(x[1])),
# kernelFiles))))
kernelsWithVer = [(x[0],
(getTupleVersion("".join(x[1].groups()[0:3:2])),
path.getmtime(x[0]))) for x
# convert version to tuple( versionTuple, mtime)
# version detect, for this version lib contains moudules
# kernel arch equal install arch
in [y for y
# (filename,version)
in [(z[0], self.reFindVer.search(z[1])) for z in kernelFiles]
if y[1] and y[1].group() in validKernel and installMarch in y[0].rpartition('/')[2]]]
if kernelsWithVer:
return path.split(max(kernelsWithVer, key=itemgetter(1))[0])[-1]
else:
@ -450,9 +475,8 @@ class VariableOsInstallKernelCpufreq(ReadonlyVariable):
def get(self):
"""Get cpufreq (and other from modules_3= param) from conf.d/modules"""
cpufreqmods = map(lambda x: x.partition('=')[2].strip("\n '\""),
filter(lambda x: x.startswith('modules_3'),
readLinesFile('/etc/conf.d/modules')))
cpufreqmods = [x.partition('=')[2].strip("\n '\"") for x
in readLinesFile('/etc/conf.d/modules') if x.startswith('modules_3')]
if cpufreqmods:
return cpufreqmods[0]
else:
@ -466,3 +490,26 @@ class VariableClInstallKernelUid(ReadonlyVariable):
def get(self):
return getKernelUid(self.Get('os_install_root_dev'))
class VariableClInstallKernelBuild(Variable):
"""
Переменная используемся для GRP дистрибутивов и сборки нескольких ядер
"""
value = ""
class VariableClInstallKernelVersion(VariableOsInstallKernelConfig):
"""
Версия ядра в /usr/src/linux
"""
def get(self):
image = self.Get('cl_image')
if image:
with image:
try:
distrPath = image.getDirectory()
return self.get_kernel_src(distrPath)
except DistributiveError as e:
return ""
return ""

@ -47,6 +47,14 @@ class InstallLinux(Linux, VariableInterface):
"""Get by distroinfo or current info"""
return self.__getFromImageOrCurrent(self.current_variable)
class VariableOsInstallChrootableSet(InstallLinux, ReadonlyVariable):
"""Можно ли выполнить chroot в систему"""
current_variable = "os_chrootable_set"
class VariableOsChrootableSet(ReadonlyVariable):
"""Можно ли выполнить chroot в систему"""
type = "boolean"
value = "on"
class VariableOsInstallLinuxShortname(InstallLinux, ReadonlyVariable):
"""Shortname of system"""

@ -53,27 +53,23 @@ class VariableOsInstallLinguas(LocaleVariable):
def get(self):
def get_linguas(lines):
linguas = map(lambda x: x.strip().rpartition('=')[-1].strip('"\''),
filter(lambda x: x.startswith("LINGUAS="),
lines))
linguas = [x.strip().rpartition('=')[-1].strip('"\'') for x
in lines if x.startswith("LINGUAS=")]
return linguas[-1] if linguas else ""
makeconf = '/etc/make.conf'
emerge_config = self.Get('cl_emerge_config')
if emerge_config and "LINGUAS" in emerge_config:
return emerge_config['LINGUAS'].encode('UTF-8')
return emerge_config['LINGUAS']
infocommand = ['emerge', '--info']
defaultLinguas = "bg en de es fr it pl pt_BR nl ru uk"
# get linguas from make.conf, emerge --info or default
curlanguage = self.Get('os_install_locale_language')
return get_linguas(readLinesFile(makeconf)) or \
" ".join(filter(lambda x: x == "en" or x == curlanguage,
get_linguas(
process(
*infocommand).readlines() or "").split())) or \
defaultLinguas
" ".join((x for x in get_linguas(process(*infocommand).readlines() or "").split() if x == "en" or x == curlanguage)) or defaultLinguas
class VariableOsInstallLocaleConsolefont(LocaleVariable):
@ -82,38 +78,15 @@ class VariableOsInstallLocaleConsolefont(LocaleVariable):
"""
def get(self):
return self.getFieldByKeymap("consolefont",
self.Get('os_install_locale_keymap'))
return self.getConsolefont(self.Get('os_install_locale_keyboard_layout'))
class VariableOsInstallLocaleKeymap(LocaleVariable):
"""
Keymap of locale (used for /etc/conf.d/keymaps)
"""
def fix_keymap(self, value):
"""
Исправить название раскладки в зависимости от версии keymap
"""
kbd_ver = isPkgInstalled("sys-apps/kbd", prefix=self.Get('cl_chroot_path'))
map_names = {}
if kbd_ver:
kbd_ver = kbd_ver[0]["PV"]
if cmpVersion(kbd_ver,"2.0.3") < 0:
map_names = {
'-u ruwin_cplk-UTF-8': '-u ruwin_cplk-utf8',
'fi': 'fi-latin9'}
return map_names.get(value,value)
def get(self):
# get keymap from boot calculate param (keymap specified
# by lang)
keymap = getValueFromCmdLine(CmdlineParams.Calculate,
CmdlineParams.Keymap)
if self.isLangExists(keymap):
return self.fix_keymap(self.getFieldByLang('keymap', keymap))
return self.fix_keymap(self.getFieldByLang("keymap",
self.Get("os_install_locale_lang")))
return self.getKeymap(self.Get('os_install_locale_keyboard_layout'))
class VariableOsInstallLocaleDumpkeys(LocaleVariable):
@ -124,11 +97,12 @@ class VariableOsInstallLocaleDumpkeys(LocaleVariable):
def get(self):
# is specified keymap support by locale hash
if self.Get('os_install_locale_keymap') in self.getFields('keymap'):
return self.getFieldByKeymap("dumpkeys_charset",
self.Get('os_install_locale_keymap'))
return self.getDumpkeys_charset(
self.getKeyboardLayout(
keymap=self.Get('os_install_locale_keymap')))
else:
return self.getFieldByLang("dumpkeys_charset",
self.Get('os_install_locale_lang'))
return self.getDumpkeys_charset(
self.Get('os_install_locale_keyboard_layout'))
class VariableOsInstallLocaleLocale(LocaleVariable):
@ -138,8 +112,7 @@ class VariableOsInstallLocaleLocale(LocaleVariable):
def get(self):
"""locale (example: ru_RU.utf8)"""
return self.getFieldByLang("locale",
self.Get('os_install_locale_lang'))
return self.getLocale(self.Get('os_install_locale_lang'))
class VariableOsInstallLocaleLang(LocaleVariable):
@ -160,8 +133,35 @@ class VariableOsInstallLocaleLang(LocaleVariable):
return self.Get('os_locale_lang')
def choice(self):
return zip(self.Get('os_lang'),
map(str, self.Get('os_lang', humanreadable=True)))
return list(zip(self.Get('os_lang'),
map(str, self.Get('os_lang', humanreadable=True))))
class VariableOsInstallLocaleKeyboardLayout(LocaleVariable):
"""
Full language (at example: ru_RU)
"""
mode = 'w'
metavalue = "KEYMAP"
type = 'choice'
opt = ["--keymap", "-k"]
def init(self):
self.label = _("Keyboard layout")
self.help = _("set the keyboard layout")
def get(self):
"""lang (example: ru_RU)"""
selected_lang = self.Get('os_install_locale_lang')
current_lang = self.Get('os_locale_lang')
if selected_lang != current_lang:
return self.getKeyboardLayout(lang=self.Get('os_install_locale_lang'))
else:
return self.Get('os_locale_keyboard_layout')
def choice(self):
return list(zip(self.Get('os_keyboard_layout'),
map(str, self.Get('os_keyboard_layout', humanreadable=True))))
class VariableOsInstallLocaleLanguage(LocaleVariable):
@ -170,8 +170,7 @@ class VariableOsInstallLocaleLanguage(LocaleVariable):
"""
def get(self):
return self.getFieldByLang("language",
self.Get('os_install_locale_lang'))
return self.getLanguage(self.Get('os_install_locale_lang'))
class VariableOsInstallLocaleXkb(LocaleVariable):
@ -180,8 +179,7 @@ class VariableOsInstallLocaleXkb(LocaleVariable):
"""
def get(self):
return self.getFieldByLang("xkblayout",
self.Get('os_install_locale_lang'))
return self.getXkblayout(self.Get('os_install_locale_keyboard_layout'))
class VariableOsInstallLocaleXkbname(LocaleVariable):
@ -273,6 +271,7 @@ class VariableOsInstallClockTimezone(LocaleVariable):
"Africa/Tunis",
"Europe/Kaliningrad",
"Asia/Amman",
"Europe/Athens",
"Europe/Istanbul",
"Asia/Beirut",
"Europe/Helsinki",
@ -334,11 +333,9 @@ class VariableOsInstallClockTimezone(LocaleVariable):
try:
lang = self.Get(self.locale_varname).split('_')[1]
nativeTZ = map(lambda x: x.encode('utf-8'),
country_timezones[lang])
nativeTZ = [x for x in country_timezones[lang]]
source = nativeTZ + ["---"] + \
sorted(filter(lambda x: not x in nativeTZ, source),
key=sortkey)
sorted([x for x in source if not x in nativeTZ], key=sortkey)
except (KeyError, IndexError) as e:
pass
return list(self.generateComments(source))
@ -350,14 +347,40 @@ class VariableOsInstallClockType(Variable):
"""
mode = 'w'
type = 'choice'
opt = ["--clocktype"]
metavalue = "CLOCKTYPE"
opt = ["--hwclock"]
metavalue = "CLOCK"
fallback_value = "local"
def init(self):
self.label = _("Clock type")
self.label = _("Hardware clock type")
self.help = _("set hardware clock type")
def exclude_value(self):
"""
Исключения
"""
root_type = self.Get('os_root_type')
hr_virtual = self.Get('hr_virtual')
# oracle virtualbox по умолчанию для linux систем выставляет
# использование UTC
if root_type == "livecd" and hr_virtual == "virtualbox":
return "UTC"
return None
def get(self):
"""type of clock (UTC or local)"""
# в первую очередь смотрим на параметры загрузки системы
cmdtype = getValueFromCmdLine(CmdlineParams.Calculate,
CmdlineParams.Clock)
if cmdtype and cmdtype in self.choice():
return cmdtype
# во вторую очередь исключения (например для livecd и virtualbox)
clocktype = self.exclude_value()
if clocktype:
return clocktype
# получаем значение из конфигурационных файлов hwclock
clockTypeFile = ['/etc/conf.d/clock', '/etc/conf.d/hwclock']
for f in clockTypeFile:
clock = getValueFromConfig(f, "clock")
@ -366,7 +389,8 @@ class VariableOsInstallClockType(Variable):
return clock.upper()
elif clock.lower() == 'local':
return clock.lower()
return "local"
# запасное значение
return self.fallback_value
def choice(self):
return ["local", "UTC"]

@ -18,39 +18,38 @@ import sys
from calculate.lib.datavars import (Variable, VariableInterface,
ReadonlyVariable, ReadonlyTableVariable,
FieldValue, HumanReadable)
from calculate.lib.utils.files import (process, checkUtils)
from calculate.lib.utils import device
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3', sys.modules[__name__])
class LvmHelper(VariableInterface):
def getLvmData(self):
"""Get route table, exclude specifed iface"""
pvDisplayProg = checkUtils('/sbin/pvdisplay')
pvDisplay = process(pvDisplayProg, "--noh", "-Co",
"lv_name,vg_name,pv_name")
for line in pvDisplay:
line = line.split()
if len(line) == 3:
yield line
for vg, lv, pv in device.lvm.pvdisplay_full():
yield lv, vg, pv
#######################################################
# Devices variables
#######################################################
class VariableOsLvmData(ReadonlyTableVariable, LvmHelper):
"""
Information about disk devices
Information about LVM
"""
source = ['os_lvm_lvname',
'os_lvm_vgname',
'os_lvm_pvname']
'os_lvm_pvname',
'os_lvm_pvname_parent'
]
def get(self, hr=HumanReadable.No):
"""LVM hash"""
return list(self.getLvmData()) or [[]]
def generator():
for lvname, vgname, pvname in self.getLvmData():
all_base = device.udev.get_all_base_devices(name=pvname)
full_base = ",".join(all_base)
yield lvname, vgname, pvname, full_base
return list(generator()) or [[]]
setValue = Variable.setValue
@ -80,3 +79,11 @@ class VariableOsLvmPvname(FieldValue, ReadonlyVariable):
type = "list"
source_variable = "os_lvm_data"
column = 2
class VariableOsLvmPvnameParent(FieldValue, ReadonlyVariable):
"""
Phisical volumes names
"""
type = "list"
source_variable = "os_lvm_data"
column = 3

@ -22,6 +22,7 @@ from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
VariableInterface, HumanReadable)
from calculate.lib.cl_lang import setLocalTranslate, _
from calculate.lib.variables.system import RootType
setLocalTranslate('cl_install3', sys.modules[__name__])
@ -29,13 +30,14 @@ from calculate.lib.utils.ip import (getInterfaces, getIp, getMask, getMac,
cidrToMask, maskToCidr, getIpNet, isDhcpIp,
checkIp, checkMask, isSlaveInterface,
getOperState, getPlugged)
import calculate.lib.utils.device as device
from calculate.lib.utils.device import lspci
from calculate.lib.utils.files import (listDirectory, readLinesFile)
from calculate.lib.utils import ip
from calculate.lib.utils.portage import isPkgInstalled
from operator import itemgetter
from itertools import *
from calculate.install.distr import DistributiveError
from ..distr import DistributiveError
class NetHelper(VariableInterface):
@ -56,9 +58,58 @@ class NetHelper(VariableInterface):
_notin=('off', 'dhcp'), limit=1):
return _("Network routing configuration is not available if all "
"interfaces are set to DHCP")
if self.Get('cl_network_migrate_set') == 'on':
return _("Network settings unavailable with use settings migration")
return ""
class VariableClNetworkConfigureSet(Variable):
"""
Выполнять ли настройку сети шаблонами
"""
type = "bool"
opt = ["--network"]
def init(self):
self.label = _("Reconfigure network")
self.help = _("reconfigure network")
def get(self):
if self.GetBool("cl_network_migrate_set"):
return "off"
else:
return "on"
class VariableClNetworkMigrateSet(Variable):
"""
Использовать миграцию для переноса настроек
"""
type = "bool"
element = "radio"
def init(self):
self.label = _("Network")
self.help = _("use the network migration")
def choice(self):
return [("on", _("Migrate network settings")),
("off", _("Manually network configuration"))]
def get(self):
for manvar in ("os_install_net_conf",
"os_install_net_data",
"os_install_net_fqdn",
"os_install_ntp",
"os_install_net_dns",
"os_install_net_dns_search",
"os_install_net_route_data"):
if self.is_console_set(manvar):
return "off"
else:
return "on"
class VariableOsInstallNtp(NetHelper, Variable):
"""
NTP server for system
@ -79,6 +130,22 @@ class VariableOsInstallProxy(NetHelper, Variable):
value = ""
class VariableOsInstallNetType(NetHelper, ReadonlyVariable):
"""
Тип сетевого устройства: сейчас eth или wlan
"""
type = "list"
def _getType(self, iface):
if ip.isWireless(iface):
return "wlan"
return "eth"
def get(self):
interfaces = self.Get('os_install_net_interfaces')
return [self._getType(x) for x in interfaces]
class VariableOsInstallNetInterfaces(NetHelper, ReadonlyVariable):
"""
Net interface devices
@ -121,8 +188,7 @@ class VariableOsNetInterfacesInfo(NetHelper, ReadonlyVariable):
else:
listInterfacesInfo.append((interface,
ipaddr if ipaddr else _("Off")))
return ", ".join(map(lambda x: "%s (%s)" % (x[0], x[1]),
listInterfacesInfo))
return ", ".join(("%s (%s)" % (x[0], x[1]) for x in listInterfacesInfo))
class VariableOsInstallNetData(NetHelper, TableVariable):
@ -187,6 +253,8 @@ class VariableOsInstallNetFqdn(NetHelper, Variable):
def check(self, value):
maxfqdn = 254
if " " in value:
raise VariableError(_("Wrong hostname"))
if len(value) > maxfqdn:
raise VariableError(
_("The hostname length should be less than %d") % maxfqdn)
@ -231,8 +299,9 @@ class VariableOsInstallNetName(NetHelper, ReadonlyVariable):
rePci = re.compile(r"(\d\d:\d\d\.\d)(?:/[^/]+){2}$")
def getPci(interface):
pathname = path.realpath(path.join('/sys/class/net',
interface))
pathname = path.realpath(
device.sysfs.syspath(device.sysfs.Path.ClassNet, interface))
pci = rePci.search(pathname)
if pci:
return pci.group(1)
@ -240,11 +309,31 @@ class VariableOsInstallNetName(NetHelper, ReadonlyVariable):
return ""
pciEthernet = lspci(shortInfo=True)
return map(lambda x: "{vendor} {name}".format(**x),
map(lambda x: pciEthernet.get(getPci(x),
{'vendor': _("Unknown"),
'name': _("vendor")}),
self.Get('os_install_net_interfaces')))
return ["{vendor} {name}".format(**x) for x
in [pciEthernet.get(getPci(y), {'vendor': _("Unknown"), 'name': _("vendor")}) for y
in self.Get('os_install_net_interfaces')]]
class VariableOsInstallNetMacType(NetHelper, ReadonlyVariable):
"""
Net devices mac (Example: local/OUI)
"""
type = "list"
reLocal = re.compile("^.[2367abef]:.*$", re.I)
def init(self):
self.label = _("Mac type")
def _mactype(self, mac):
if not mac:
return ""
if not self.reLocal.match(mac):
return "OUI"
else:
return "local"
def get(self):
return [self._mactype(x) for x in self.Get('os_install_net_mac')]
class VariableOsInstallNetMac(NetHelper, ReadonlyVariable):
@ -257,8 +346,7 @@ class VariableOsInstallNetMac(NetHelper, ReadonlyVariable):
self.label = _("MAC")
def get(self):
return map(lambda x: getMac(x).lower(),
self.Get('os_install_net_interfaces'))
return [getMac(x).lower() for x in self.Get('os_install_net_interfaces')]
class VariableOsInstallNetStatus(NetHelper, Variable):
@ -271,8 +359,7 @@ class VariableOsInstallNetStatus(NetHelper, Variable):
self.label = _("IP address")
def get(self):
return map(self.getDefaultValue,
self.Get('os_install_net_interfaces'))
return [self.getDefaultValue(x) for x in self.Get('os_install_net_interfaces')]
def getDefaultValue(self, iface):
def statusValue(ipaddr, dhcp):
@ -295,16 +382,14 @@ class VariableOsInstallNetStatus(NetHelper, Variable):
if rootDevNfs or isDhcpIp(iface) else "off")
def set(self, value):
value = map(lambda x: x.lower() if x else x, value)
value = (x.lower() if x else x for x in value)
ifaces = self.Get('os_install_net_interfaces')
return map(lambda x: self.getDefaultValue(x[1]) \
if x[0] == "auto" else x[0],
zip(value, ifaces))
return [self.getDefaultValue(x[1]) if x[0] == "auto" else x[0] for x
in zip(value, ifaces)]
def check(self, value):
for status in value:
if status not in map(lambda x: x[0], self.choice()) and \
not checkIp(status):
if status not in (x[0] for x in self.choice()) and not checkIp(status):
raise VariableError(_("Wrong IP address %s") % status)
def choice(self):
@ -323,10 +408,10 @@ class VariableOsInstallNetIp(NetHelper, ReadonlyVariable):
self.label = _("IP address")
def get(self):
return map(lambda x: "" if x[1].lower() == "off" else
getIp(x[0]) if x[1].lower() == "dhcp" else x[1],
zip(self.Get('os_install_net_interfaces'),
self.Get('os_install_net_status')))
return ["" if x[1].lower() == "off" else
getIp(x[0]) if x[1].lower() == "dhcp" else x[1] for x
in zip(self.Get('os_install_net_interfaces'),
self.Get('os_install_net_status'))]
# def check(self,value):
# dhcps = self.Get('os_install_net_dhcp_set')
@ -347,9 +432,9 @@ class VariableOsInstallNetNetwork(NetHelper, ReadonlyVariable):
self.label = _("Network")
def get(self):
return map(lambda x: getIpNet(x[0], x[1]) if x[0] and x[1] else "",
zip(self.Get('os_install_net_ip'),
self.Get('os_install_net_mask')))
return [getIpNet(x[0], x[1]) if x[0] and x[1] else "" for x
in zip(self.Get('os_install_net_ip'),
self.Get('os_install_net_mask'))]
class VariableOsInstallNetCidr(NetHelper, ReadonlyVariable):
@ -365,8 +450,7 @@ class VariableOsInstallNetCidr(NetHelper, ReadonlyVariable):
"""
Get CIDR of ip,net (Example: 24)
"""
return map(lambda x: maskToCidr(x) if x else '',
self.Get('os_install_net_mask'))
return [maskToCidr(x) if x else '' for x in self.Get('os_install_net_mask')]
class VariableOsInstallNetMask(NetHelper, Variable):
@ -379,8 +463,8 @@ class VariableOsInstallNetMask(NetHelper, Variable):
self.label = _("Mask")
def get(self):
return map(lambda x: cidrToMask(getMask(x)),
self.Get('os_install_net_interfaces'))
return [cidrToMask(getMask(x)) for x
in self.Get('os_install_net_interfaces')]
def set(self, value):
"""
@ -393,14 +477,13 @@ class VariableOsInstallNetMask(NetHelper, Variable):
else:
return x
res = map(convertCidrToMask, value)
res = [convertCidrToMask(x) for x in value]
return res
def check(self, value):
dhcps = self.Get('os_install_net_status')
wrongMask = filter(lambda x: (x[0] or not x[1] in ("off", "dhcp")) and \
not checkMask(x[0]),
zip(value, dhcps))
wrongMask = [x for x in zip(value, dhcps)
if (x[0] or not x[1] in ("off", "dhcp")) and not checkMask(x[0])]
if wrongMask:
raise VariableError(_("Wrong mask %s") % wrongMask[0][0])
@ -422,8 +505,8 @@ class VariableOsInstallNetDhcpSet(NetHelper, Variable):
self.label = _("DHCP")
def get(self):
return map(lambda x: "on" if x == "dhcp" else "off",
self.Get('os_install_net_status'))
return ["on" if x == "dhcp" else "off" for x
in self.Get('os_install_net_status')]
class VariableOsInstallNetRouteData(NetHelper, TableVariable):
@ -445,26 +528,25 @@ class VariableOsInstallNetRouteData(NetHelper, TableVariable):
self.label = _("Routing")
self.help = \
_("add a routing rule (specified as "
"NETWORK:[GATEWAY][:DEV[:SOURCE]])")
"NETWORK:GATEWAY[:DEV[:SOURCE]])")
def get(self, hr=HumanReadable.No):
"""Routing hash"""
interfaces = self.Get('os_install_net_interfaces')
interfaces_status = self.Get('os_install_net_status')
interfaces_network = self.Get('os_install_net_network')
staticInterface = \
map(itemgetter(0, 2),
filter(lambda x: not x[1] in ("off", "dhcp"),
zip(interfaces, interfaces_status, interfaces_network)))
staticInterface = [itemgetter(0, 2)(x) for x
in zip(interfaces, interfaces_status, interfaces_network)
if not x[1] in ("off", "dhcp")]
route_data = []
if staticInterface:
staticInterface, skipNet = zip(*staticInterface)
return map(lambda x: [x[0],
x[1].get('via', ''),
x[1].get('dev', ''),
x[1].get('src', '')],
ifilter(lambda x: not x[0] in skipNet,
ip.getRouteTable(staticInterface))) or [[]]
staticInterface, skipNet = list(zip(*staticInterface))
return [[x[0],
x[1].get('via', ''),
x[1].get('dev', ''),
x[1].get('src', '')] for x
in ip.getRouteTable(staticInterface)
if not x[0] in skipNet] or [[]]
return [[]]
def getHumanReadableAuto(self):
@ -474,7 +556,13 @@ class VariableOsInstallNetRouteData(NetHelper, TableVariable):
"""
Standard action for set value
"""
self.value = self.set(value)
interfaces = self.Get('os_install_net_interfaces')
if len(interfaces) == 1:
wrapper = lambda x: x if not x else [x[0],x[1],interfaces[0],x[3]]
else:
wrapper = lambda x: x
self.value = self.set([wrapper(x) for x in value])
self.wasSet = True
self.invalid = False
# run check
@ -500,12 +588,11 @@ class VariableOsInstallNetRouteNetwork(NetHelper, FieldValue, Variable):
##########################
# detect duplicate network
##########################
for wrongnet in ifilterfalse(ip.checkNet,
ifilter("default".__ne__,
for wrongnet in filterfalse(ip.checkNet,
filter("default".__ne__,
value)):
raise VariableError(_("Wrong network %s") % wrongnet)
dupNetwork = list(set(filter(lambda x: value.count(x) > 1,
value)))
dupNetwork = list(set([x for x in value if value.count(x) > 1]))
if dupNetwork:
raise VariableError(
_("Network '%s' is used more than once") % dupNetwork[0])
@ -528,19 +615,14 @@ class VariableOsInstallNetRouteGw(NetHelper, FieldValue, Variable):
NET, GW = 0, 1
netsGw = zip(self.Get('os_install_net_route_network'),
value)
nets = filter(lambda x: x and x != "default",
chain(self.Get('os_install_net_route_network'),
self.Get('os_install_net_network')))
nets = [x for x in chain(self.Get('os_install_net_route_network'),
self.Get('os_install_net_network'))
if x and x != "default"]
for wrongip in ifilterfalse(ip.checkIp, value):
for wrongip in filterfalse(ip.checkIp, value):
raise VariableError(_("Wrong gateway IP %s") % wrongip)
wrongGws = map(lambda x: x[GW],
filter(lambda x: not ip.isIpInNet(x[GW],
*(set(nets) - set(
x[NET]))),
filter(lambda x: x[GW],
netsGw)))
wrongGws = [x[GW] for x in [y for y in netsGw if y[GW]]
if not ip.isIpInNet(x[GW], *(set(nets) - set(x[NET])))]
if wrongGws:
raise VariableError(_("Gateways %s are unreachable") %
(",".join(wrongGws)))
@ -576,12 +658,11 @@ class VariableOsInstallNetRouteSrc(NetHelper, FieldValue, Variable):
return [""] + self.Get('os_install_net_ip')
def check(self, value):
for wrongip in ifilterfalse(ip.checkIp,
ifilter(None, value)):
for wrongip in filterfalse(ip.checkIp,
filter(None, value)):
raise VariableError(_("Wrong source IP %s") % wrongip)
ipAddrs = self.Get('os_install_net_ip')
wrongIps = filter(lambda x: x and not x in ipAddrs,
value)
wrongIps = [x for x in value if x and not x in ipAddrs]
if wrongIps:
raise VariableError(
_("Wrong IP address %s in the specified source IP") %
@ -594,19 +675,18 @@ class VariableOsInstallNetRoute(NetHelper, ReadonlyVariable):
"""
def performRouteData(self, performFunc):
routeMatrix = zip(self.Get('os_install_net_route_network'),
routeMatrix = list(zip(self.Get('os_install_net_route_network'),
self.Get('os_install_net_route_gw'),
self.Get('os_install_net_route_dev'),
self.Get('os_install_net_route_src'))
self.Get('os_install_net_route_src')))
DEV, IP, CIDR, NET = 0, 1, 2, 1
return map(lambda x: performFunc(x[DEV], x[NET], routeMatrix),
# union ip and mask to ip/net
map(lambda x: (x[DEV], ip.getIpNet(x[IP], cidr=x[CIDR])) \
if x[IP] and x[CIDR] else (x[DEV], ""),
# filter(lambda x:x[IP] and x[CIDR],
zip(self.Get('os_install_net_interfaces'),
return [performFunc(x[DEV], x[NET], routeMatrix) for x
# ip and mask to ip/net
in [(y[DEV], ip.getIpNet(y[IP], cidr=y[CIDR]))
if y[IP] and y[CIDR] else (y[DEV], "") for y
in zip(self.Get('os_install_net_interfaces'),
self.Get('os_install_net_ip'),
self.Get('os_install_net_cidr'))))
self.Get('os_install_net_cidr'))]]
def get(self):
"""Route info for conf.d/net"""
@ -619,17 +699,25 @@ class VariableOsInstallNetRoute(NetHelper, ReadonlyVariable):
def getRouteForInterfaceConf(interface, net, routeMatrix):
NET, GW, DEV, SRC = 0, 1, 2, 3
return "\n".join(
# build string for route from net,gateway,dev and src
map(lambda x: "{net}{gateway}{src}".format(
net=x[NET],
gateway=" via %s" % x[GW] if x[GW] else "",
src=" src %s" % x[SRC] if x[SRC] else ""),
# filter by interface and discard direct routes
# example: for 192.168.1.5/24 discard 192.168.1.0/24 net
filter(lambda x: (interface == x[DEV] or defaultDev and
interface == defaultDev) \
and net != x[NET], routeMatrix)))
# filter by interface and discard direct routes
# example: for 192.168.1.5/24 discard 192.168.1.0/24 net
route_list = [x for x in routeMatrix
if (interface == x[DEV] or
defaultDev and
interface == defaultDev) and
net != x[NET]]
nets = []
route_list_uniqnet = []
for net, gw, dev, src in route_list:
if net not in nets:
route_list_uniqnet.append([net, gw, dev, src])
nets.append(net)
route_strs = ("{net}{gateway}{src}".format(net=x[NET], gateway=" via %s" % x[GW]
if x[GW] else "", src=" src %s" % x[SRC] if x[SRC] else "") for x
in route_list_uniqnet)
# build string for route from net,gateway,dev and src
return "\n".join(route_strs)
return self.performRouteData(getRouteForInterfaceConf)
@ -651,29 +739,42 @@ class VariableOsInstallNetNmroute(VariableOsInstallNetRoute):
def getRouteForInterfaceNM(interface, net, routeMatrix):
NET, GW, DEV, SRC = 0, 1, 2, 3
defaultGw = map(lambda x: "%s;" % x[GW],
filter(lambda x: interface == x[DEV] and \
x[NET] == "default",
routeMatrix))
return "{0}\n".format(defaultGw[0] if defaultGw else "") + \
"\n".join(
# build string for route from net,gateway,dev and src
map(lambda
x: "routes{num}={ip};{cidr};{gateway};0;".format(
defaultGw = ["%s;" % x[GW] for x in routeMatrix
if interface == x[DEV] and x[NET] == "default"]
# return "{0}\n".format(defaultGw[0] if defaultGw else "") + \
# "\n".join(
# # build string for route from net,gateway,dev and src
# map(lambda
# x: "routes{num}={ip};{cidr};{gateway};0;".format(
# num=x[0] + 1,
# ip=x[1][NET].partition('/')[0],
# cidr=x[1][NET].partition('/')[2],
# gateway=x[1][GW] if x[1][GW] else "0.0.0.0"),
# # filter by interface and discard direct routes
# # example: for 192.168.1.5/24 discard 192.168.1.0/24 net
# enumerate(
# filter(lambda x: (interface == x[
# DEV] or defaultDev and
# interface == defaultDev) and net !=
# x[
# NET] and \
# x[NET] != "default",
# routeMatrix))))
return "{0}\n".format(defaultGw[0] if defaultGw else "") + "\n".join(
# build string for route from net,gateway,dev and src
("routes{num}={ip};{cidr};{gateway};0;".format(
num=x[0] + 1,
ip=x[1][NET].partition('/')[0],
cidr=x[1][NET].partition('/')[2],
gateway=x[1][GW] if x[1][GW] else "0.0.0.0"),
# filter by interface and discard direct routes
# example: for 192.168.1.5/24 discard 192.168.1.0/24 net
enumerate(
filter(lambda x: (interface == x[
DEV] or defaultDev and
interface == defaultDev) and net !=
x[
NET] and \
x[NET] != "default",
routeMatrix))))
gateway=x[1][GW] if x[1][GW] else "0.0.0.0") for x
# filter by interface and discard direct routes
# example: for 192.168.1.5/24 discard 192.168.1.0/24 net
in enumerate((x for x in routeMatrix
if (interface == x[DEV] or
defaultDev and
interface == defaultDev) and
net !=x[NET] and
x[NET] != "default"))))
return self.performRouteData(getRouteForInterfaceNM)
@ -693,10 +794,8 @@ class VariableOsInstallNetConfAvailable(NetHelper, Variable):
with image as distr:
try:
distrPath = image.getDirectory()
return map(itemgetter(0, 2),
filter(lambda x: not x[1] or isPkgInstalled(x[1],
prefix=distrPath),
mapNetConf))
return [itemgetter(0, 2)(x) for x in mapNetConf
if not x[1] or isPkgInstalled(x[1], prefix=distrPath)]
except DistributiveError as e:
pass
return sorted(map(itemgetter(0, 2), mapNetConf[-1:]), key=itemgetter(1))
@ -716,10 +815,9 @@ class VariableOsInstallNetConf(NetHelper, Variable):
def get(self):
"""Net setup (networkmanager or openrc)"""
if filter(lambda x: x.lower() == "networkmanager",
listDirectory('/etc/runlevels/boot') +
listDirectory('/etc/runlevels/default')) \
or self.Get('os_root_type') == "livecd":
if [x for x in listDirectory('/etc/runlevels/boot') +
listDirectory('/etc/runlevels/default')
if x.lower() == "networkmanager"] or self.Get('os_root_type') == "livecd":
nm = "networkmanager"
else:
nm = ""
@ -761,10 +859,9 @@ class VariableOsInstallNetDnsSearch(NetHelper, Variable):
def get(self):
"""Get current name servers"""
dnsSearch = " ".join(
map(lambda x: x.strip().partition("search")[2].strip(),
filter(lambda x: x.lstrip().startswith("search"),
readLinesFile('/etc/resolv.conf'))))
dnsSearch = " ".join((x.strip().partition("search")[2].strip() for x
in readLinesFile('/etc/resolv.conf')
if x.lstrip().startswith("search")))
return "" if self.isDNSByDHCP() else dnsSearch
def humanReadable(self):
@ -788,17 +885,16 @@ class VariableOsInstallNetDns(VariableOsInstallNetDnsSearch):
return " ".join(re.split('[; ,]', value))
def get(self):
dnsIps = filter(ip.checkIp,
map(lambda x: x.strip().partition("nameserver")[
2].strip(),
filter(
lambda x: x.lstrip().startswith("nameserver"),
readLinesFile('/etc/resolv.conf'))))
dnsIps = (x for x
in (y.strip().partition("nameserver")[2].strip() for y
in readLinesFile('/etc/resolv.conf')
if y.lstrip().startswith("nameserver"))
if ip.checkIp(x))
return "" if self.isDNSByDHCP() else " ".join(dnsIps)
def check(self, value):
reIp = re.compile(ip.IP_ADDR)
if any(ifilterfalse(reIp.match, value.split(' '))):
if any(filterfalse(reIp.match, value.split(' '))):
raise VariableError(_("Wrong IP address for DNS"))
def humanReadable(self):
@ -831,10 +927,12 @@ class VariableOsInstallPxeIp(Variable):
self.help = "set IP address for PXE server"
def get(self):
for ipaddr in ifilter(None, self.Get('os_install_net_ip')):
ips = self.Get('os_net_ip').split(',')
for ipaddr in filter(None, ips):
return ipaddr
else:
return ""
def choice(self):
return filter(None, self.Get('os_install_net_ip'))
ips = self.Get('os_net_ip').split(',')
return [x for x in ips if x]

@ -21,20 +21,23 @@ from os import path
from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
TableVariable, PasswordError,
DataVarsError, VariableInterface)
from calculate.install.fs_manager import FileSystemManager
from ..fs_manager import FileSystemManager
from calculate.lib.utils.files import (readFile, getProgPath, process,
readLinesFile)
from calculate.lib.utils.common import getPasswdUsers, getUserGroups, getGroups, \
CmdlineParams
readLinesFile, readFileEx)
from calculate.lib.utils.common import (getPasswdUsers, getUserGroups,
getGroups, CmdlineParams)
from calculate.lib.utils.common import getValueFromConfig, getValueFromCmdLine
from calculate.lib.utils.common import getUserPrimaryGroup
from calculate.lib.utils.portage import isPkgInstalled
from calculate.lib.utils.device import getUdevDeviceInfo
from crypt import crypt
from autopartition import SchemeOpt, SchemeDevices
from calculate.lib.encrypt import encrypt
import calculate.lib.utils.device as device
from calculate.lib.encrypt import sha256_crypt
from calculate.lib.variables.system import RootType
import calculate.lib.variables.env as libenv
from calculate.lib.encrypt import get_shadow_hash, get_grub_hash
from calculate.core.server.admin import Admins
import calculate.lib.cl_ini_parser as cl_ini_parser
from calculate.lib.cl_template import SystemIni
from .distr import DistributiveError
from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_install3', sys.modules[__name__])
@ -45,6 +48,7 @@ class UserHelper(VariableInterface):
Locale variables not using for flash installation
"""
xorg_need = False
stub_hash_value = "{SHA256}"
def uncompatible(self):
"""
@ -57,6 +61,43 @@ class UserHelper(VariableInterface):
return ""
class GrubHelper(VariableInterface):
grub_passwd_file = "/etc/grub.d/07_passwd"
def read_hash_from_passwd(self):
"""
Получить пароль из конфигурационного файла grub
"""
data = readFile(self.grub_passwd_file)
reRootPwd = re.compile("password_pbkdf2 root (\S+)")
pwd = reRootPwd.search(data)
if pwd:
return pwd.group(1)
return ""
class VariableOsInstallLibPath(ReadonlyVariable):
"""
Использовать lib или lib64
"""
def get(self):
if self.Get('os_install_arch_machine') == 'x86_64':
return "lib64"
else:
return "lib"
class VariableOsInstallPython(libenv.VariableOsPython):
"""
Текущий python
"""
def get_root(self):
return self.Get('cl_chroot_path')
def get_usrlib(self):
return "/usr/%s" % self.Get('os_install_lib_path')
class VariableOsInstallScratch(ReadonlyVariable):
"""
Install system in scratch mode
@ -80,7 +121,7 @@ class VariableOsFormatType(ReadonlyVariable):
def get(self):
"""Filesystem format support by calcualte-install"""
return FileSystemManager.supportFS.keys()
return list(FileSystemManager.supportFS.keys())
class VariableOsFormatUse(ReadonlyVariable):
@ -100,10 +141,10 @@ class VariableOsFormatUse(ReadonlyVariable):
return "no"
def get(self):
return map(self.checkFunc, self.Get('os_format_type'))
return [self.checkFunc(x) for x in self.Get('os_format_type')]
class VariableClMigrateRootPwd(UserHelper, Variable):
class VariableClMigrateRootPwdPlain(GrubHelper, UserHelper, Variable):
"""
Root password
"""
@ -111,42 +152,146 @@ class VariableClMigrateRootPwd(UserHelper, Variable):
opt = ["--root-password"]
metavalue = 'PASSWORD'
untrusted = True
check_after = ["cl_grub"]
def get(self):
shadow_pwd = self.Get('cl_migrate_root_shadow_pwd')
if shadow_pwd:
return self.stub_hash_value
return ""
def init(self):
self.help = _("specify the root password")
self.label = _("Root password")
def check(self, value):
if not value and not self.Get('cl_migrate_root_shadow_pwd'):
raise PasswordError(_("Enter password for user %s") % "root")
# если plain пароля нет (есть только хэш), но требуется установить
# пароль на grub (cl_grub_passwd_set), при этом нет 07_passwd
if (value == self.stub_hash_value and
not self.read_hash_from_passwd() and
self.GetBool('cl_grub_passwd_set')):
raise PasswordError(_("Please enter a root password for Grub"))
class VariableClMigrateRootPwd(ReadonlyVariable):
"""
Хэш root пароля
"""
def get(self):
value = self.Get('cl_migrate_root_pwd_plain')
if value and value != UserHelper.stub_hash_value:
return get_shadow_hash().hash(value)
return self.Get('cl_migrate_root_shadow_pwd')
class VariableClMigrateRootShadowPwd(ReadonlyVariable):
"""
Хэш root пароля из файла /etc/shadow. Если пароль root, то
содержит пустую строку
"""
def get(self):
rootPasswd = map(lambda x: x[1],
filter("root".__eq__,
map(lambda x: x.split(':')[0:2],
readLinesFile('/etc/shadow'))))
rootPasswd = [x[1] for x
in [y.split(':')[0:2] for y in readLinesFile('/etc/shadow')]
if "root".__eq__(x)]
if rootPasswd:
rootPasswd = rootPasswd[0]
else:
rootPasswd = ""
# if root password is "root"
enc = get_shadow_hash()
if rootPasswd:
salt = "".join(rootPasswd.rpartition("$")[:1])
if salt and crypt("root", salt) == rootPasswd:
if enc.identify(rootPasswd):
if enc.verify("root", rootPasswd):
rootPasswd = ""
else:
rootPasswd = ""
return rootPasswd or ""
class VariableClGrubPasswdSet(GrubHelper, Variable):
"""
Использовать при установке системы пароль root как пароль для grub
"""
type = 'bool'
opt = ["--grub-passwd"]
def init(self):
self.help = _("use the root password to edit Grub")
self.label = _("Use the root password to edit Grub")
def get(self):
if (self.read_hash_from_passwd() or
self.Get('os_root_type_ext') in RootType.Live):
return Variable.On
else:
return Variable.Off
class VariableClGrubPwd(GrubHelper, Variable):
"""
Хэш пароля на grub
"""
opt = ["--passwd"]
type = "password"
def init(self):
self.help = _("set grub password")
self.label = _("Grub password")
def get(self):
system_action = self.Get('cl_action') == "system"
if self.GetBool('cl_grub_remove_pwd_set'):
return ""
use_grub_passwd = self.GetBool('cl_grub_passwd_set')
passwd_hash = self.read_hash_from_passwd()
if passwd_hash:
if not system_action or use_grub_passwd:
return passwd_hash
if use_grub_passwd:
value = self.Get('cl_migrate_root_pwd_plain')
if value and value != UserHelper.stub_hash_value:
enc = get_grub_hash()
return enc.hash(value)
return ""
def set(self, value):
"""
Encrypt password
Поддержка использвания как шифрованного хэша так и plain
"""
reCheck = re.compile("^\$[^$]+\$[^$]+\$.*$")
encryptObj = encrypt()
if reCheck.match(value) or not value:
enc = get_grub_hash()
# используется hash
if enc.identify(value):
return value
else:
return encryptObj.getHashPasswd(value, "shadow_ssha256")
# отключение
if value in ("", "none"):
return ""
# используется plain
return enc.hash(value)
def check(self, value):
if not value:
raise PasswordError(_("Password for user %s missing") % "root")
if value and self.GetBool('cl_grub_remove_pwd_set'):
raise VariableError(
_("You cannot set a password and remove the "
"existing password at a time"))
class VariableClGrubRemovePwdSet(Variable):
"""
Удалить пароль из grub
"""
type = "bool"
guitype = "hidden"
value = Variable.Off
opt = ["--remove-passwd"]
def init(self):
self.help = _("remove the password protection for editing the Grub menu")
self.label = _("Remove the password protection on Grub")
class VariableClInstallHomeCryptSet(UserHelper, Variable):
@ -174,21 +319,41 @@ class VariableClMigrateData(UserHelper, TableVariable):
"""
type = 'table'
opt = ["--user", "-u"]
metavalue = 'USER[:GROUPS]'
source = ['cl_migrate_user', 'cl_migrate_user_groups',
metavalue = 'USER[:ADMIN[:GROUPS]]'
source = ['cl_migrate_user', 'cl_migrate_admin',
'cl_migrate_user_groups',
'cl_migrate_user_pwd']
untrusted = True
def init(self):
self.help = _("add a user to the installed system")
self.help = _("add a user to the installed system. USER is username. "
"ADMIN is administrator rights ({alllist}, "
"{none_value} by default). "
"GROUPS is list user supplimentary groups "
"(comma delimeter). "
"Use '{none_value}' value to discard user migration").format(
alllist="none, update, all", none_value="none")
self.label = _("Migrating users")
def set(self, value):
value = [
[x[0],
VariableClMigrateAdmin.pre_set(x[1]),
VariableClMigrateUserGroups.pre_set(x[2]),
x[3]]
for x in value
]
if len(value) == 1:
if len(value[0]) > 1 and value[0][0] == 'none':
return [[]]
return value
class VariableClMigrateDataBrief(UserHelper, TableVariable):
"""
User migrate data table for brief view
"""
source = ['cl_migrate_user', 'cl_migrate_user_groups']
source = ['cl_migrate_user', 'cl_migrate_admin', 'cl_migrate_user_groups']
def init(self):
self.label = _("Migrating users")
@ -201,34 +366,116 @@ class VariableClMigrateUser(UserHelper, Variable):
type = 'list'
def init(self):
self.label = _("Users")
self.label = _("User")
def get(self):
"""
Migrating users (users above 1000 uid)
"""
return filter("root".__ne__, getPasswdUsers())
cached_users = getPasswdUsers(
datafile="var/lib/calculate/calculate-client/cache/create_passwd")
return [x for x in getPasswdUsers() if x != "root" and x not in cached_users]
def check(self, value):
"""
Проверка на корректное имя пользователя
"""
if any(not x for x in value):
raise VariableError(_("Username is missing"))
class VariableClMigrateAdmin(UserHelper, Variable):
"""
Migrate users list
"""
type = 'choice-list'
default_value = ""
aliases = {'system_update': 'update'}
def init(self):
self.label = _("Administrator")
def choice(self):
return [
("", ""),
("update", _("System update")),
("all", _("Full access")),
]
@classmethod
def pre_set(cls, value):
return {'none':''}.get(value, value)
def get_alias(self, value):
return self.aliases.get(value, value)
def get(self):
"""
Migrating users (users above 1000 uid)
"""
admins = Admins(self.parent)
return [self.get_alias(admins[x]) or self.default_value
for x in self.Get('cl_migrate_user')]
def set(self, value):
return [x if x else self.default_value for x in value]
class VariableOsAvailableGroups(ReadonlyVariable):
"""
Список доступных в дистрибутиве групп
"""
type = 'list'
def get(self):
image = self.Get('cl_image')
if image:
with image:
try:
distrPath = image.getDirectory()
return getGroups(distrPath)
except DistributiveError:
pass
return getGroups()
class VariableClMigrateUserGroups(UserHelper, Variable):
"""
Migrate users groups
"""
type = 'choice-list-list'
defaultGroupList = ["users", "wheel", "audio", "cdrom", "video",
"cdrw", "usb", "plugdev", "games", "lp", "scanner",
"uucp"]
defaultGroupList = sorted(["users", "audio", "cdrom", "video",
"cdrw", "usb", "plugdev", "games", "lp", "lpadmin",
"scanner", "uucp"])
default_value = "default"
@classmethod
def pre_set(cls, value):
"""
Обработать значение до передачи его из таблицы в поле
"""
if not any(value):
return [cls.default_value]
else:
return value
def getDefaultGroups(self):
return list(set(self.defaultGroupList) & set(getGroups()))
return list(set(self.defaultGroupList) & set(self.Get('os_available_groups')))
def init(self):
self.label = _("Groups")
def process_groups(self, values):
groupslist = list(set(self.defaultGroupList)
& set(self.Get('os_available_groups')))
for value in values:
if value == self.default_value:
for i in groupslist:
yield i
else:
yield value
def set(self, value):
value = map(lambda x: (filter(None, x) if x and any(x)
else self.getDefaultGroups()),
value)
value = [sorted(list(set(self.process_groups(x)))) for x in value]
return value
def getPrimaryGroup(self, username):
@ -242,17 +489,16 @@ class VariableClMigrateUserGroups(UserHelper, Variable):
User groups
"""
passwdList = getPasswdUsers()
return map(lambda x: (self.getPrimaryGroup(x) +
(getUserGroups(x)
if x in passwdList else
self.getDefaultGroups())),
self.Get('cl_migrate_user'))
return [sorted(self.getPrimaryGroup(x) + (getUserGroups(x)
if x in passwdList else self.getDefaultGroups())) for x
in self.Get('cl_migrate_user')]
def choice(self):
"""
Available groups
"""
return [("", _("Default"))] + [(x, x) for x in getGroups()]
return [(self.default_value,
_("Default"))] + sorted([(x, x) for x in getGroups()])
class VariableClMigrateUserPwd(UserHelper, Variable):
@ -274,18 +520,20 @@ class VariableClMigrateUserPwd(UserHelper, Variable):
migrateusers = self.Get("cl_migrate_user")
if migrateusers:
lenData = 9
shadowData = filter(lambda x: len(x) == lenData,
map(lambda x: x.rstrip().split(":"),
open(fileName)))
shadowData = filter(lambda x: x[0] in migrateusers, shadowData)
shadowData = map(lambda x: (x[0], x[1]), shadowData)
shadowUsers = map(lambda x: x[0], shadowData)
with open(fileName) as f:
shadowData = [x for x in [y.rstrip().split(":") for y in f] if len(x) == lenData]
shadowData = [x for x in shadowData if x[0] in migrateusers]
shadowData = [(x[0], x[1]) for x in shadowData]
shadowUsers = [x[0] for x in shadowData]
for userName in migrateusers:
if userName in shadowUsers:
userData = filter(lambda x: x[0] == userName,
shadowData)
userData = [x for x in shadowData if x[0] == userName]
hashPwd = userData[0][1]
retList.append(hashPwd)
if (sha256_crypt.identify(hashPwd) and
sha256_crypt.verify("guest", hashPwd)):
retList.append("")
else:
retList.append(hashPwd)
else:
retList.append("")
return retList
@ -297,18 +545,16 @@ class VariableClMigrateUserPwd(UserHelper, Variable):
for user, pwd in zip(self.Get('cl_migrate_user'), value):
if not pwd:
raise PasswordError(
_("Password for user %s missing") % user)
_("Enter password for user %s") % user)
def set(self, value):
"""
Encrypt passwords
"""
reCheck = re.compile("^\$[^$]+\$[^$]+\$.*$")
encryptObj = encrypt()
shadow_hash = get_shadow_hash()
return map(lambda x: x if reCheck.match(x) or not x else \
encryptObj.getHashPasswd(x, "shadow_ssha256"),
value)
return [x if shadow_hash.identify(x) or not x else shadow_hash.hash(x) for x in value]
class VariableClAutologin(UserHelper, Variable):
@ -335,8 +581,8 @@ class VariableClAutologin(UserHelper, Variable):
if (not cmdDomainSet and
self.Get('os_install_root_type') == "livecd") or \
self.Get('os_install_linux_shortname') == "CMC":
nonRootUsers = filter(lambda x: x != "root",
self.Get('cl_migrate_user'))
nonRootUsers = [x for x in self.Get('cl_migrate_user') if x != "root"]
if nonRootUsers:
return nonRootUsers[0]
else:
@ -442,19 +688,16 @@ class VariableClInstallDevFrom(Variable):
If device in calculate3.env dev_from not exists set ''
"""
if value:
value = getUdevDeviceInfo(name=value).get('DEVNAME', value)
value = device.udev.get_device_info(
name=value).get('DEVNAME', value)
if value in self.Get('os_disk_dev'):
return value
else:
return ""
def get(self):
if (self.Get('cl_autopartition_set') == 'on' and
SchemeOpt.Update in self.Get('cl_autopartition_scheme')):
return self.Select('cl_autopartition_disk_dev',
where='cl_autopartition_disk_scheme',
eq=SchemeDevices.Root2,
limit=1)
if self.Get('cl_autopartition_set') == 'on':
return self.Get('cl_autopartition_factory').dev_from
return ""
@ -463,7 +706,19 @@ class VariableOsNvidiaMask(ReadonlyVariable):
Get nvidia card mask versions
"""
def get(self):
def get_cards_id(self):
category = "0300"
vendor = "10de:"
lsPciProg = getProgPath("/usr/sbin/lspci")
nvidiacards = [x for x in process(lsPciProg, "-d", vendor, "-n")
if " %s: " % category in x]
cardsid = [x.groups()[0] for x
in [re.search("[0-9a-fA-F]{4}:([0-9a-fA-F]{4})", y) for y in nvidiacards] if x]
if not cardsid:
return set()
return set(cardsid)
def get_legacy(self):
image = self.Get('cl_image')
try:
if image:
@ -471,44 +726,60 @@ class VariableOsNvidiaMask(ReadonlyVariable):
chrootPath = image.getDirectory()
else:
chrootPath = self.Get("cl_chroot_path")
nvidiaeclass = path.join(chrootPath,
'usr/portage/eclass/nvidia-driver.eclass')
if os.path.isdir(path.join(self.Get('cl_chroot_path'), 'var/db/repos/gentoo')):
nvidiaeclass = path.join(chrootPath,
'var/db/repos/gentoo/eclass/nvidia-driver.eclass')
else:
nvidiaeclass = path.join(chrootPath,
'usr/portage/eclass/nvidia-driver.eclass')
if not os.access(nvidiaeclass, os.R_OK):
return ""
category = "0300"
vendor = "10de:"
lsPciProg = getProgPath("/usr/sbin/lspci")
nvidiacards = filter(lambda x: " %s: " % category in x,
process(lsPciProg, "-d", vendor, "-n"))
if not nvidiacards:
#TODO investigate
#there used to be a typo - nvidiacards instead of... ?
# (nvidiacards wasn't defined)
# if not nvidiacards:
# return ""
if not nvidiaeclass:
return ""
cardsid = \
map(lambda x: x.groups()[0],
filter(lambda x: x,
map(lambda x: re.search(
"[0-9a-fA-F]{4}:([0-9a-fA-F]{4})", x),
nvidiacards)))
cardsid = self.get_cards_id()
if not cardsid:
return ""
eclassdata = readFile(nvidiaeclass)
drv_categories = re.findall('^drv_([^=]+)="', eclassdata, re.M)
drvs = map(lambda x: (x[0], x[1].replace('\\\n', '').split()),
re.findall(
'\ndrv_(%s)="(.*?)"' % "|".join(drv_categories),
eclassdata, re.S))
mask_categories = re.findall('^mask_([^=]+)="', eclassdata, re.M)
masks = dict(map(lambda x: (x[0], x[1].replace('\\\n', '')),
re.findall('\nmask_(%s)="(.*?)"' % "|".join(
drv_categories),
eclassdata, re.S)))
drvsForCardsid = filter(lambda x: set(x[1]) & set(cardsid), drvs)
if drvsForCardsid and drvsForCardsid[0][0] in masks:
return masks[drvsForCardsid[0][0]]
reBlock = re.compile(
r"if has \$\{nvidia_gpu\}\s+\\([^;]+);\s*then(.*?)fi", re.S)
reMask = re.compile('>=x11-drivers/nvidia-drivers[^"]+')
masks = []
for block in reBlock.findall(eclassdata):
nvidia_ids, mask_data = block
nvidia_ids = nvidia_ids.strip().replace('\\','')
nvidia_ids = {x for x in nvidia_ids.split() if x}
m = reMask.search(mask_data)
if m:
mask_str = m.group()
if cardsid & nvidia_ids:
return mask_str
finally:
if image:
image.close()
return ""
def get_new(self, ini):
cardsid = self.get_cards_id()
for nvidia_serie in ini.getKeys('nvidia'):
nvidia_ids = set(ini.getVar('nvidia', nvidia_serie).split(','))
if cardsid & nvidia_ids:
if nvidia_serie.isdigit():
return ">=x11-drivers/nvidia-drivers-{}".format(int(nvidia_serie)+1)
return ""
def get(self):
ini = SystemIni(self.parent)
if ini.getKeys('nvidia'):
return self.get_new(ini)
else:
return self.get_legacy()
class VariableOsInstallLvmSet(ReadonlyVariable):
"""
@ -560,13 +831,17 @@ class VariableOsGrub2Path(Variable):
def get(self):
# find grub2-install
grubInstall = getProgPath('/usr/sbin/grub2-install')
chroot_path = self.Get('cl_chroot_path')
chroot_cmd = getProgPath('/usr/bin/chroot')
grubInstall = getProgPath('/usr/sbin/grub2-install', prefix=chroot_path)
if grubInstall:
return grubInstall
# find grub-install and check, that this is grub2-install (ver 1.99)
grubInstall = getProgPath('/usr/sbin/grub-install')
if grubInstall and filter(lambda x: "1.99" in x or "2." in x,
process(grubInstall, '--version')):
grubInstall = getProgPath('/usr/sbin/grub-install', prefix=chroot_path)
if grubInstall and [x for x
in process(chroot_cmd, chroot_path, grubInstall, '--version')
if "1.99" in x or "2." in x]:
return grubInstall
return ""
@ -580,7 +855,7 @@ class VariableClSetup(Variable):
def choice(self):
return ["audio", "network", "locale", "video", "boot", "users",
"session", ""]
"session", "themes", ""]
def humanReadable(self):
mapType = {'network': _("network settings"),
@ -588,6 +863,7 @@ class VariableClSetup(Variable):
'video': _("video settings"),
'boot': _("boot parameters"),
'audio': _("audio parameters"),
'themes': _("update themes"),
'session': _("session settings"),
'users': _("user settings")}
return mapType.get(self.Get(), "")
@ -631,13 +907,15 @@ class VariableOsInstallPxe(Variable):
raise VariableError(
_("For PXE install, you need to install package %s")
% pkg)
try:
config = cl_ini_parser.iniParser('/etc/calculate/calculate.env')
val = config.getVar('server', 'sr_dhcp_set')
if val.encode('utf-8') == "on":
return
except Exception:
pass
for env_fn in ('/etc/calculate/calculate.env',
'/var/lib/calculate/calculate.env'):
try:
config = cl_ini_parser.iniParser(env_fn)
val = config.getVar('server', 'sr_dhcp_set')
if val.encode('utf-8') == "on" or val == "on":
return
except Exception:
pass
raise VariableError(
_("PXE install is only available if the DHCP "
"service has been configured first"))
@ -660,68 +938,11 @@ class VariableOsInstallUefiSet(Variable):
"""
Install in UEFI
"""
type = "bool"
opt = ['--uefi']
def init(self):
self.label = _("UEFI boot")
self.help = _("use UEFI boot")
def get(self):
if self.Get('cl_autopartition_set') == 'on':
return self.Get('cl_autopartition_uefi_set')
if self.Get('os_install_uefi'):
return "on"
else:
if self.Get('os_install_disk_efi') or \
"/boot/efi" in self.Get('os_location_dest'):
if self.Get('os_install_arch_machine') == 'x86_64' and \
self.Get('os_install_root_type') != 'flash':
return self.Get('os_uefi_set')
return 'off'
def check(self, value):
if value == 'on':
if self.Get('os_uefi_set') == 'off' and \
self.Get('os_install_root_type') == 'hdd':
raise VariableError(
_("Your system must be loaded in UEFI for using this "
"bootloader"))
if not 'gpt' in self.Get('os_device_table'):
raise VariableError(
_("GPT is needed for using the UEFI bootloader"))
if not (self.Get('os_install_disk_efi') or
"/boot/efi" in self.Get('os_location_dest')):
raise VariableError(
_("A EF00 partition is needed for using "
"the UEFI bootloader"))
if self.Get('os_install_arch_machine') != 'x86_64':
raise VariableError(
_("Architecture of the target system must be x86_64"))
if self.Get('os_install_root_type') == 'flash':
raise VariableError(
_("This option not used for Flash install"))
def uncompatible(self):
"""
Uncompatible with autopartition
"""
if self.Get('cl_autopartition_set') == "on":
return \
_("The layout is not available with autopartitioning")
if self.Get('os_install_root_type') == 'flash':
return \
_("This option not used for Flash install")
return ""
class VariableOsInstallUefiBriefSet(VariableOsInstallUefiSet):
def uncompatible(self):
if self.Get('os_install_root_type') == 'flash':
return _("This option not used for Flash install")
return ""
def get(self):
return self.Get('os_install_uefi_set')
return "off"
class VariableOsInstallGrubTerminal(Variable):
"""
@ -805,6 +1026,21 @@ class VariableOsInstallX11ServerSet(PackageCheckVariable):
package = "x11-base/xorg-server"
class VariableOsInstallSplashSet(Variable):
"""
Переменная отображать splash при загрузки
"""
type = "bool"
value = "on"
class VariableClInstallFs(Variable):
"""
Preferred fs
"""
type = "list"
value = ["btrfs", "ext4", "reiserfs", "ext3"]
class FlashUncompatible(VariableInterface):
def uncompatible(self):
"""
@ -816,6 +1052,35 @@ class FlashUncompatible(VariableInterface):
return ""
class VariableClInstallUpdatePkgSet(Variable):
"""
При установке системы создать сценарии запуска cl-update в конце
первой загрузки
"""
type = "bool"
opt = ["--update-pkg","-K"]
def system_has_ip(self):
return bool(self.Get('os_net_ip'))
def custom_set_has_packages(self):
install_short = self.Get('os_install_linux_shortname')
now_short = self.Get('os_linux_shortname')
setfile = "/etc/portage/sets/custom.{}".format(now_short.lower())
if readFileEx(setfile, grab=True) and install_short == now_short:
return True
return False
def get(self):
if self.system_has_ip() and self.custom_set_has_packages():
return "on"
return "off"
def init(self):
self.help = _("update packages at first boot")
self.label = _("Update packages at first boot")
try:
import calculate.update.variables.update as update

@ -17,20 +17,21 @@
import sys
from calculate.lib.datavars import VariableError, DataVarsError
from calculate.install.distr import DistributiveError
from .distr import DistributiveError
import install
from . import install
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
from calculate.core.server.func import WsdlBase
from calculate.install.utils.cl_install import ClInstallAction
from calculate.install.utils.cl_setup import (
from calculate.lib.utils.partition import VolumesError
from .utils.cl_install import ClInstallAction
from .utils.cl_setup import (
ClSetupLocaleAction, ClSetupVideoAction, ClSetupSystemAction,
ClSetupBootAction, ClSetupNetworkAction, ClSetupAudioAction,
ClSetupSessionAction)
ClSetupSessionAction, ClSetupThemesAction)
class Wsdl(WsdlBase):
@ -56,17 +57,20 @@ class Wsdl(WsdlBase):
'action': ClInstallAction,
# объект переменных
'datavars': "install",
'native_error': (VariableError, DistributiveError,
'native_error': (VariableError, DistributiveError, VolumesError,
DataVarsError, install.InstallError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'system', 'cl_install_type': 'hdd',
'setvars': {'cl_action!': 'system',
'cl_chroot_status!': 'off', 'cl_install_type': 'hdd',
'cl_dispatch_conf': 'usenew'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Language and locale"),
image="welcome",
normal=('os_install_locale_lang',
'os_install_clock_timezone')),
'os_install_clock_timezone'),
expert=('os_install_locale_keyboard_layout',
'os_install_clock_type',)),
lambda group: group(_("Distribution"),
normal=('cl_image_filename',),
hide=('cl_image_linux_shortname',
@ -75,39 +79,51 @@ class Wsdl(WsdlBase):
expert=('cl_image_linux_shortname',
'cl_image_arch_machine',
'cl_image_new_only')),
lambda group: group(_("Allocate drive space"),
lambda group: group(_("Installation type"),
normal=('cl_autopartition_set',),
hide=('cl_autopartition_set',),
hide=('cl_autopartition_set',
'cl_autopartition_root_size',
'cl_autopartition_root_format',
'cl_autopartition_calculate_format',
'cl_autopartition_swap_size',),
brief=('cl_autopartition_brief_set',),
expert=('cl_autopartition_scheme',
'cl_autopartition_root_format',
'cl_autopartition_calculate_format',
'cl_autopartition_table',
'cl_autopartition_root_size',
'cl_autopartition_swap_size',
'cl_autopartition_device'),
expert_label=_(
"Click to set up autopartition options")),
lambda group: group(_("Mount points"),
"Click to select partitions to be created")
),
lambda group: group(_("Layout"),
normal=('os_location_data',),
hide=('os_location_data', 'os_install_mbr',
'os_install_uefi_set'),
'os_install_uefi'),
brief_force=('os_location_brief_data',
'os_install_bootloader'),
brief=('os_install_uefi_brief_set',),
brief=('os_install_uefi',),
expert=('cl_uuid_set',
'os_install_mbr',
'os_install_uefi_set',
'os_install_kernel_scheduler')),
'os_install_uefi')),
lambda group: group(_("Network settings"),
normal=(
'os_install_net_conf',
'cl_network_migrate_set',),
expert=('os_install_net_conf',
'os_install_net_data',
'os_install_net_fqdn', 'os_install_ntp'),
expert=('os_install_net_dns',
'os_install_net_dns_search',
'os_install_net_route_data')),
'os_install_net_fqdn', 'os_install_ntp',
'os_install_net_dns',
'os_install_net_dns_search',
'os_install_net_route_data'),
expert_label=_(
"Click to select network settings")
),
lambda group: group(_("Users"),
normal=(
'cl_migrate_root_pwd', 'cl_migrate_data',
'cl_migrate_root_pwd_plain',
'cl_grub_passwd_set',
'cl_migrate_data',
'cl_autologin'),
expert=('cl_install_home_crypt_set',),
hide=('cl_migrate_data',),
@ -118,16 +134,17 @@ class Wsdl(WsdlBase):
lambda group: group(_("Video"),
normal=('os_install_x11_video_drv',
'os_install_x11_composite',
'os_install_x11_resolution',
'os_install_fb_resolution',
'os_install_grub_terminal')),
'os_install_x11_resolution_preferred',
'os_install_grub_terminal'),
expert=('os_install_fb_resolution_preferred',)),
lambda group: group(_("Update"),
normal=('cl_install_autocheck_set',
'cl_install_autocheck_interval',
'cl_install_cleanpkg_set',
'cl_install_other_set'))],
'cl_install_other_set'),
expert=('cl_install_update_pkg_set',))],
# действие выводит информацию перед запуском
'brief': {'next': __("Perform"),
'brief': {'next': __("Run"),
'image': 'finish',
'name': __("Start installing")}},
# установка на Flash
@ -135,7 +152,8 @@ class Wsdl(WsdlBase):
'method_name': "install_flash",
'category': __("Installation"),
'title': __("Flash Install"),
'image': ('drive-removable-media-usb-pendrive,'
'image': ('calculate-install-flash,'
'drive-removable-media-usb-pendrive,'
'drive-removable-media-usb,media-flash'),
'command': 'cl-install-flash',
'gui': True,
@ -143,25 +161,30 @@ class Wsdl(WsdlBase):
'logic': {'Install': install.Install},
'action': ClInstallAction,
'datavars': "install",
'native_error': (VariableError, DistributiveError,
'native_error': (VariableError, DistributiveError, VolumesError,
DataVarsError, install.InstallError),
'setvars': {'cl_action!': 'system', 'cl_install_type': 'flash',
'setvars': {'cl_action!': 'system',
'cl_chroot_status!': 'off',
'cl_install_type': 'flash',
'cl_protect_use_set!': 'off',
'cl_autopartition_set!': 'off',
'cl_dispatch_conf': 'usenew'},
'groups': [
lambda group: group(_("Flash install"),
normal=('cl_image_filename',
'os_install_disk_single',
'cl_target_fs',
'os_install_format_single_set'),
next_label=_("Perform"))],
'brief': {'next': __("Perform"),
next_label=_("Run"))],
'brief': {'next': __("Run"),
'name': __("Start installing")}},
# PXE установка
{
'method_name': "install_pxe",
'category': __("Installation"),
'title': __("PXE Install"),
'image': ('gnome-network-properties,network-server,'
'image': ('calculate-install-pxe,gnome-network-properties,'
'network-server,'
'preferences-desktop-remote-desktop'),
'command': 'cl-install-pxe',
'gui': True,
@ -183,13 +206,13 @@ class Wsdl(WsdlBase):
normal=('cl_image_filename',),
expert=('os_install_pxe_path',
'os_install_pxe_ip'),
next_label=_("Perform"))]},
next_label=_("Run"))]},
# настройка загрузки системы
{
'method_name': "setup_boot",
'category': __("Configuration"),
'title': __("Boot"),
'image': 'stock_save,drive-harddisk',
'image': 'calculate-setup-boot,stock_save,drive-harddisk',
'command': 'cl-setup-boot',
'gui': True,
'rights': ['setupboot'],
@ -203,9 +226,12 @@ class Wsdl(WsdlBase):
'groups': [
lambda group: group(_("Boot"),
normal=(
'os_install_mbr', 'os_install_uefi_set',
'os_install_kernel_scheduler',
'os_install_grub_terminal'),
'os_install_mbr',
'os_install_uefi',
'os_install_grub_terminal',
'cl_grub_pwd',
'cl_grub_remove_pwd_set',
),
expert=(
'cl_templates_locate',
'cl_dispatch_conf',
@ -216,7 +242,7 @@ class Wsdl(WsdlBase):
'method_name': "setup_network",
'category': __("Configuration"),
'title': __("Network"),
'image': 'network-workgroup,'
'image': 'calculate-setup-network,network-workgroup,'
'network-idle,preferences-system-network',
'command': 'cl-setup-network',
'gui': True,
@ -227,6 +253,7 @@ class Wsdl(WsdlBase):
'native_error': (
VariableError, DataVarsError, install.InstallError),
'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'cl_network_migrate_set': 'off',
'cl_merge_set!': "on", 'cl_setup': 'network'},
'groups': [
lambda group: group(_("Network"),
@ -246,7 +273,8 @@ class Wsdl(WsdlBase):
'method_name': "setup_system",
'category': __("Configuration"),
'title': __("System"),
'image': 'run-build,applications-ide,system-run,system,computer',
'image': 'calculate-setup-system,run-build,applications-ide,'
'system-run,system,computer',
'command': 'cl-setup-system',
'gui': True,
'rights': ['setupsystem'],
@ -258,7 +286,8 @@ class Wsdl(WsdlBase):
'setvars': {'cl_action!': 'merge', 'cl_live': 'off'},
'groups': [
lambda group: group(_("Update system settings"),
normal=('cl_live',),
normal=('cl_live',
'cl_network_configure_set'),
expert=(
'cl_templates_locate',
'cl_dispatch_conf',
@ -269,7 +298,8 @@ class Wsdl(WsdlBase):
'method_name': "setup_video",
'category': __("Configuration"),
'title': __("Video"),
'image': 'system-config-display,video-display,gnome-multimedia',
'image': 'calculate-setup-video,system-config-display,'
'video-display,gnome-multimedia',
'command': 'cl-setup-video',
'gui': True,
'rights': ['setupvideo'],
@ -281,22 +311,23 @@ class Wsdl(WsdlBase):
'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'cl_merge_set!': "on", 'cl_setup': 'video'},
'groups': [
lambda group: group(_("Video"),
normal=('os_install_x11_video_drv',
'os_install_x11_resolution',
'os_install_x11_composite',
'os_install_fb_resolution'),
expert=(
'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
lambda group: group(
_("Video"),
normal=('os_install_x11_video_drv',
'os_install_x11_resolution_preferred',
'os_install_x11_composite'),
expert=(
'os_install_fb_resolution_preferred',
'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
{
# настройка звука
'method_name': "setup_audio",
'category': __("Configuration"),
'title': __("Audio"),
'image': 'audio-card',
'image': 'calculate-setup-audio,audio-card',
'command': 'cl-setup-audio',
'gui': True,
'rights': ['setupaudio'],
@ -321,7 +352,7 @@ class Wsdl(WsdlBase):
'method_name': "setup_locale",
'category': __("Configuration"),
'title': __("Locale"),
'image': 'locale,preferences-desktop-locale',
'image': 'calculate-setup-locale,locale,preferences-desktop-locale',
'command': 'cl-setup-locale',
'gui': True,
'rights': ['setuplocale'],
@ -337,6 +368,8 @@ class Wsdl(WsdlBase):
normal=('os_install_locale_lang',
'os_install_clock_timezone'),
expert=(
'os_install_locale_keyboard_layout',
'os_install_clock_type',
'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
@ -346,7 +379,7 @@ class Wsdl(WsdlBase):
'method_name': "setup_session",
'category': __("Configuration"),
'title': __("Session"),
'image': 'system-lock-screen',
'image': 'calculate-setup-session,system-lock-screen',
'command': 'cl-setup-session',
'gui': True,
'rights': ['setupsession'],
@ -361,6 +394,30 @@ class Wsdl(WsdlBase):
lambda group: group(_("Session"),
normal=('cl_autologin',
'cl_install_home_crypt_set'),
expert=(
'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
{
# настройка тем
'method_name': "setup_theme",
'category': None,
'title': __("Themes"),
'image': None,
'command': 'cl-setup-themes',
'gui': True,
'rights': ['setupthemes'],
'logic': {'Install': install.Install},
'action': ClSetupThemesAction,
'datavars': "install",
'native_error': (
VariableError, DataVarsError, install.InstallError),
'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'cl_merge_set!': "on", 'cl_setup': 'themes'},
'groups': [
lambda group: group(_("Session"),
normal=(),
expert=(
'cl_templates_locate',
'cl_dispatch_conf',

@ -72,12 +72,12 @@ class install_data(module_install_data.install_data):
data_files = []
data_files += [('/etc/init.d', [('data/calculate',0755)]),
('/usr/bin',[('bin/xautologin',0755)]),
data_files += [('/etc/init.d', [('data/calculate',0o755)]),
('/usr/bin',[('bin/xautologin',0o755)]),
('/usr/share/calculate/doc', ['data/handbook-en.html',
'data/handbook-ru.html']),
('/usr/libexec/calculate', [('data/cl-video-install', 0755)]),
('/bin',[('bin/bashlogin',0755)])]
('/usr/libexec/calculate', [('data/cl-video-install', 0o755)]),
('/bin',[('bin/bashlogin',0o755)])]
packages = [
"calculate."+str('.'.join(root.split(os.sep)[1:]))

Loading…
Cancel
Save