Refactoring

master3.4 3.4.1.2
Mike Khiretskiy 9 years ago
parent 6f82626d8c
commit 5bdef0490b

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -17,12 +17,13 @@
__app__ = 'calculate-install' __app__ = 'calculate-install'
__version__ = '3.1.8' __version__ = '3.1.8'
import os
import sys import sys
from calculate.lib.datavars import DataVars from calculate.lib.datavars import DataVars
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3',sys.modules[__name__])
setLocalTranslate('cl_install3', sys.modules[__name__])
class DataVarsInstall(DataVars): class DataVarsInstall(DataVars):
"""Variable class for installation""" """Variable class for installation"""

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,158 +14,160 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import re
import sys import sys
import time
import traceback
from os import path from os import path
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3',sys.modules[__name__])
class FileSystemManager: setLocalTranslate('cl_install3', sys.modules[__name__])
class FileSystemManager(object):
"""Convert dict install option""" """Convert dict install option"""
defaultOpt = ['noatime'] defaultOpt = ['noatime']
defaultBindOpts = ['bind'] defaultBindOpts = ['bind']
supportFS = { supportFS = {
'ext2': {'defaultopt': defaultOpt, 'ext2': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext2', 'format': '/sbin/mkfs.ext2',
'formatparam': '{labelparam} {device}', 'formatparam': '{labelparam} {device}',
'gpt': '8300', 'gpt': '8300',
'label': '-L {labelname}', 'label': '-L {labelname}',
'ssd':[], 'ssd': [],
'msdos': '83', 'msdos': '83',
'type':['hdd','usb-hdd']}, 'type': ['hdd', 'usb-hdd']},
'ext3': {'defaultopt': defaultOpt, 'ext3': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext3', 'format': '/sbin/mkfs.ext3',
'formatparam': '{labelparam} {device}', 'formatparam': '{labelparam} {device}',
'gpt': '8300', 'gpt': '8300',
'label': '-L {labelname}', 'label': '-L {labelname}',
'ssd':[], 'ssd': [],
'msdos': '83', 'msdos': '83',
'type':['hdd','usb-hdd']}, 'type': ['hdd', 'usb-hdd']},
'ext4': {'defaultopt': defaultOpt, 'ext4': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext4', 'format': '/sbin/mkfs.ext4',
'formatparam': '{labelparam} {device}', 'formatparam': '{labelparam} {device}',
'gpt': '8300',
'label': '-L {labelname}',
'ssd': ['discard'],
'msdos': '83',
'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', 'gpt': '8300',
'label': '-L {labelname}', 'label': '-L {labelname}',
'ssd':['discard'],
'msdos': '83', 'msdos': '83',
'type':['hdd','usb-hdd']}, 'ssd': ['ssd', 'discard', 'space_cache'],
'reiserfs': {'defaultopt': defaultOpt, 'type': ['hdd', 'usb-hdd']},
'format': '/sbin/mkfs.reiserfs', 'jfs': {'defaultopt': defaultOpt,
'formatparam': '{labelparam} -f {device}', 'format': '/sbin/mkfs.jfs',
'gpt': '8300', 'formatparam': '{labelparam} -f {device}',
'label': '-l {labelname}', 'gpt': '8300',
'msdos': '83', 'label': '-L {labelname}',
'ssd':[], 'msdos': '83',
'type':['hdd','usb-hdd']}, 'ssd': ['discard'],
'btrfs': {'defaultopt': defaultOpt, 'type': ['hdd', 'usb-hdd']},
'format':'/sbin/mkfs.btrfs', 'xfs': {'defaultopt': defaultOpt,
'formatparam': '{labelparam} -f {device}', 'format': '/sbin/mkfs.xfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': ['discard'],
'type': ['hdd', 'usb-hdd']},
'nilfs2': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.nilfs2',
'formatparam': '{labelparam} {device}',
'gpt': '8300', 'gpt': '8300',
'label': '-L {labelname}', 'label': '-L {labelname}',
'msdos': '83', 'msdos': '83',
'ssd':['ssd','discard','space_cache'], 'ssd': [],
'type':['hdd','usb-hdd']}, 'type': ['hdd', 'usb-hdd']},
'jfs': {'defaultopt': defaultOpt, 'swap': {'defaultopt': ['sw'],
'format': '/sbin/mkfs.jfs', 'format': '/sbin/mkswap',
'formatparam': '{labelparam} -f {device}', 'formatparam': '{device}',
'gpt': '8200',
'label': '',
'ssd': [],
'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', 'gpt': '8300',
'label': '-L {labelname}', 'label': '-L {labelname}',
'msdos': '83', 'msdos': '7',
'ssd':['discard'], 'ssd': [],
'type':['hdd','usb-hdd']}, 'compatible': ['ntfs-3g']},
'xfs': {'defaultopt': defaultOpt, 'ntfs-3g': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.xfs', 'format': '/usr/sbin/mkfs.ntfs',
'formatparam': '{labelparam} -f {device}', 'formatparam': '{labelparam} -FQ {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd':['discard'],
'type':['hdd','usb-hdd']},
'nilfs2': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.nilfs2',
'formatparam': '{labelparam} {device}',
'gpt': '8300', 'gpt': '8300',
'label': '-L {labelname}', 'label': '-L {labelname}',
'msdos': '83', 'ssd': [],
'ssd':[], 'msdos': '7',
'type':['hdd','usb-hdd']}, 'compatible': ['ntfs']}}
'swap': {'defaultopt': ['sw'],
'format': '/sbin/mkswap', default_param = {'defaultopt': defaultOpt,
'formatparam': '{device}', 'ssd': []}
'gpt': '8200',
'label': '',
'ssd':[],
'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,
'ssd':[]}
@classmethod @classmethod
def firstAvailable(cls,listFS): def firstAvailable(cls, listFS):
for fs in listFS: for fs in listFS:
if path.exists(cls.supportFS['format']): if path.exists(cls.supportFS['format']):
return fs return fs
else: else:
return "" return ""
defaultFS = {'hdd':"ext4" \ defaultFS = {
if path.exists(supportFS['ext4']['format']) else \ 'hdd': ("ext4"
"reiserfs" \ if path.exists(supportFS['ext4']['format']) else
if path.exists(supportFS['reiserfs']['format']) else \ "reiserfs"
"ext3", if path.exists(supportFS['reiserfs']['format']) else
'flash':"vfat", "ext3"),
'usb-hdd': "ext4" \ 'flash': "vfat",
if path.exists(supportFS['ext4']['format']) else \ 'usb-hdd': ("ext4"
"reiserfs" \ if path.exists(supportFS['ext4']['format']) else
if path.exists(supportFS['reiserfs']['format']) else \ "reiserfs"
"ext3"} if path.exists(supportFS['reiserfs']['format']) else
"ext3")
}
@classmethod @classmethod
def getDefaultOpt(cls,fs, ssd=False): def getDefaultOpt(cls, fs, ssd=False):
return ",".join(cls.supportFS.get(fs,cls.default_param)['defaultopt']+ return ",".join(cls.supportFS.get(fs, cls.default_param)['defaultopt'] +
(cls.supportFS.get(fs,cls.default_param)['ssd'] if ssd else [])) (cls.supportFS.get(fs, cls.default_param)['ssd']
if ssd else []))
@classmethod @classmethod
def checkFSForTypeMount(cls,fs,roottype,mp): def checkFSForTypeMount(cls, fs, roottype, mp):
if mp == '/boot/efi': if mp == '/boot/efi':
if not fs in ('uefi','vfat'): if fs not in ('uefi', 'vfat'):
return False return False
else: else:
return True return True
return roottype in cls.supportFS.get(fs,{}).get('type',[]) return roottype in cls.supportFS.get(fs, {}).get('type', [])

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -19,57 +19,39 @@ import re
import sys import sys
import time import time
from os import path from os import path
from StringIO import StringIO
from random import choice from random import choice
import string import string
from time import sleep from time import sleep
from subprocess import PIPE,STDOUT from calculate.core.server.func import MethodsInterface
from shutil import copy2 from calculate.lib.utils.files import (pathJoin,
from calculate.lib.utils.files import (runOsCommand,pathJoin, isMount, process, listDirectory,
isMount,process,listDirectory,STDOUT, checkUtils, readFile, find, copyWithPath,
checkUtils,readFile,find,copyWithPath, readLinesFile, getProgPath)
readLinesFile)
from calculate.lib.utils.common import (appendProgramToEnvFile,
removeProgramToEnvFile, getTupleVersion,
cmpVersion,getUserPassword,
getSupportArch, getInstalledVideo )
from calculate.lib.utils.device import (detectDeviceForPartition, from calculate.lib.utils.device import (detectDeviceForPartition,
getUdevDeviceInfo, getLvmPartitions, refreshLVM, getUdevDeviceInfo, refreshLVM,
refreshUdev,countPartitions) refreshUdev, countPartitions)
from calculate.lib.cl_vars_share import varsShare from datavars import DataVarsInstall
from calculate.lib import cl_overriding from calculate.install.variables.autopartition import AutoPartition
from calculate.lib.utils import ip
from calculate.lib.datavars import VariableError from distr import DistributiveError
from datavars import DataVarsInstall, __version__,__app__ from subprocess import Popen, PIPE, STDOUT
from calculate.install.variables.autopartition import (AutopartitionError,
AutoPartition)
from calculate.install.fs_manager import FileSystemManager
from calculate.lib.variables.locale import Locale
from calculate.lib.cl_template import Template,TemplatesError,ProgressTemplate
from calculate.lib.datavars import DataVars
from distr import (PartitionDistributive,
DistributiveError, ScratchPartitionDistributive,
MultiPartitions, FlashDistributive,
Distributive)
from calculate.lib.utils.text import tableReport
from calculate.lib.server.utils import dialogYesNo
from subprocess import Popen,PIPE,STDOUT
from itertools import * from itertools import *
class InstallError(Exception): class InstallError(Exception):
"""Installation Error""" """Installation Error"""
from migrate_users import migrate, currentUsers, MigrationError
from calculate.lib.encrypt import encrypt
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate from migrate_users import migrate
setLocalTranslate('cl_install3',sys.modules[__name__])
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
class Install: class Install(MethodsInterface):
"""Primary class for templates appling and system installation""" """Primary class for templates applying and system installation"""
def __init__(self): def __init__(self):
self.clVars = None self.clVars = None
@ -78,7 +60,7 @@ class Install:
# refresh information about device in udevadm info # refresh information about device in udevadm info
refreshUdev() refreshUdev()
def initVars(self,datavars=None): def initVars(self, datavars=None):
"""Primary initialization of variables""" """Primary initialization of variables"""
if not datavars: if not datavars:
self.clVars = DataVarsInstall() self.clVars = DataVarsInstall()
@ -87,275 +69,309 @@ class Install:
else: else:
self.clVars = datavars self.clVars = datavars
def canInstallGrub2(self,target): def canInstallGrub2(self, target):
"""Check that system has grub2 in current and installed system""" """Check that system has grub2 in current and installed system"""
if self.clVars.Get('os_grub2_path'): if self.clVars.Get('os_grub2_path'):
return bool( return bool(
filter(lambda x:x.startswith('grub-1.99') or \ filter(lambda x: (x.startswith('grub-1.99') or
x.startswith('grub-2'), x.startswith('grub-2')),
listDirectory('/var/db/pkg/sys-boot'))) listDirectory('/var/db/pkg/sys-boot')))
return False return False
def prepareBoot(self,targetDistr): def prepareBoot(self, target_distr):
"""Prepare system for boot""" """Prepare system for boot"""
if self.clVars.Get('os_install_root_type') == "flash": if self.clVars.Get('os_install_root_type') == "flash":
self.installSyslinuxBootloader(targetDistr) self.installSyslinuxBootloader(target_distr)
else: else:
if self.canInstallGrub2(targetDistr): if self.canInstallGrub2(target_distr):
self.installGrub2Bootloader(targetDistr) self.installGrub2Bootloader(target_distr)
else: else:
self.installLegacyGrubBootloader(targetDistr) self.installLegacyGrubBootloader(target_distr)
return True return True
def setActivePartition(self,partition): def setActivePartition(self, partition):
""" """
Установка активного раздела для dos и gpt таблицы разделов Установка активного раздела для dos и gpt таблицы разделов
""" """
deviceName = detectDeviceForPartition(partition) device_name = detectDeviceForPartition(partition)
if deviceName is None: if device_name is None:
raise DistributiveError( raise DistributiveError(
_("Failed to determine the parent device for %s")%partition) _("Failed to determine the parent device for %s") % partition)
# device hasn't any partition # device hasn't any partition
elif deviceName == "": elif device_name == "":
return True return True
fdiskProg, gdiskProg, partedProg = checkUtils('/sbin/fdisk', fdisk_cmd, gdisk_cmd, parted_cmd = checkUtils('/sbin/fdisk',
'/usr/sbin/gdisk','/usr/sbin/parted') '/usr/sbin/gdisk',
'/usr/sbin/parted')
disk = self.clVars.Select('os_install_disk_parent', disk = self.clVars.Select('os_install_disk_parent',
where='os_install_disk_dev',eq=partition, where='os_install_disk_dev', eq=partition,
limit=1) limit=1)
parttable = self.clVars.Select('os_device_table',where='os_device_dev', partition_table = self.clVars.Select('os_device_table',
eq=disk,limit=1) where='os_device_dev',
partitionNumber = \ eq=disk, limit=1)
getUdevDeviceInfo(name=partition).get('ID_PART_ENTRY_NUMBER','') or \ partition_number = (
getUdevDeviceInfo(name=partition).get('UDISKS_PARTITION_NUMBER','') getUdevDeviceInfo(name=partition).get('ID_PART_ENTRY_NUMBER', '') or
getUdevDeviceInfo(name=partition).get('UDISKS_PARTITION_NUMBER', '')
devicePartitionCount = countPartitions(deviceName) )
if deviceName and not partitionNumber:
device_partition_count = countPartitions(device_name)
if device_name and not partition_number:
raise DistributiveError( raise DistributiveError(
_("Failed to determine the partition number for %s")%partition) _("Failed to determine the partition number for %s")
bootFlag = "boot" if parttable == "dos" else "legacy_boot" % partition)
if parttable == "dos": boot_flag = "boot" if partition_table == "dos" else "legacy_boot"
fdisk = process(fdiskProg, "-l",deviceName) if partition_table == "dos":
DEVICENUM,AFLAG = 0,1 fdisk = process(fdisk_cmd, "-l", device_name)
changeActive = \ DEVICENUM, AFLAG = 0, 1
map(lambda x:x[DEVICENUM], change_active = map(
filter(lambda x:x[DEVICENUM] != partitionNumber and \ lambda x: x[DEVICENUM],
x[AFLAG] == "*" or \ filter(
x[DEVICENUM] == partitionNumber and \ lambda x: (x[DEVICENUM] != partition_number and
not x[AFLAG] == "*", x[AFLAG] == "*" or
list(map(lambda x:[str(x[0]),x[1][1].strip()], x[DEVICENUM] == partition_number and
# enumerate partitions not x[AFLAG] == "*"),
enumerate(filter(None, list(map(
map(lambda x:x.split()[:2], lambda x: [str(x[0]), x[1][1].strip()],
# drop string before information about partitions # enumerate partitions
dropwhile(lambda x:not x.lstrip().startswith("Device"), enumerate(filter(None, map(
fdisk.readlines()))))))[1:])) lambda x: x.split()[:2],
# drop string before information about partitions
dropwhile(
lambda x: not x.lstrip().startswith(
"Device"),
fdisk.readlines()))))))[1:]))
else: else:
parted = process(partedProg, "-m",deviceName,"print") parted = process(parted_cmd, "-m", device_name, "print")
DEVICENUM,FLAGS = 0,6 DEVICENUM, FLAGS = 0, 6
changeActive = \ change_active = map(
map(lambda x:x[DEVICENUM], lambda x: x[DEVICENUM], filter(
filter(lambda x:x[DEVICENUM] != partitionNumber and \ lambda x: (x[DEVICENUM] != partition_number and
bootFlag in x[FLAGS].strip(';').split(', ') or \ boot_flag in x[FLAGS].strip(';').split(', ') or
x[DEVICENUM] == partitionNumber and \ x[DEVICENUM] == partition_number and
not bootFlag in x[FLAGS].strip(';').split(', '), boot_flag not in
filter(lambda x:len(x)>=7, x[FLAGS].strip(';').split(', ')),
map(lambda x:x.split(':'), filter(lambda x: len(x) >= 7,
parted.readlines()[2:])))) map(lambda x: x.split(':'),
if not changeActive: parted.readlines()[2:]))))
if not change_active:
return True return True
if parttable == "dos": if partition_table == "dos":
pipe = Popen([fdiskProg,deviceName], pipe = Popen([fdisk_cmd, device_name],
stdin=PIPE, stdout=PIPE,stderr=PIPE) stdin=PIPE, stdout=PIPE, stderr=PIPE)
for partnum in changeActive: for part_num in change_active:
pipe.stdin.write("a\n%s\n"%partnum) pipe.stdin.write("a\n%s\n" % part_num)
pipe.stdin.write("w\n") pipe.stdin.write("w\n")
pipe.stdin.close() pipe.stdin.close()
pipe.wait() pipe.wait()
elif parttable == "gpt": elif partition_table == "gpt":
pipe = Popen([gdiskProg,deviceName], pipe = Popen([gdisk_cmd, device_name],
stdin=PIPE, stdout=PIPE,stderr=PIPE) stdin=PIPE, stdout=PIPE, stderr=PIPE)
if devicePartitionCount > 1: if device_partition_count > 1:
pipe.stdin.write("x\n") pipe.stdin.write("x\n")
for partnum in changeActive: for part_num in change_active:
pipe.stdin.write("a\n%s\n2\n\n"%partnum) pipe.stdin.write("a\n%s\n2\n\n" % part_num)
pipe.stdin.write("w\nY\n") pipe.stdin.write("w\nY\n")
else: else:
pipe.stdin.write("x\na\n2\n\nw\nY\n") pipe.stdin.write("x\na\n2\n\nw\nY\n")
pipe.stdin.close() pipe.stdin.close()
pipe.wait() pipe.wait()
for waittime in (0.1,0.2,0.5,1,2,4): for wait_time in (0.1, 0.2, 0.5, 1, 2, 4):
if path.exists(partition): if path.exists(partition):
return True return True
else: else:
sleep(waittime) sleep(wait_time)
raise InstallError( raise InstallError(
_("Failed to find partition %s after changing the activity")% _("Failed to find partition %s after changing the activity") %
partition) partition)
def installSyslinuxBootloader(self,target): def installSyslinuxBootloader(self, target):
""" """
Установить syslinux загрузчик (используется для flash) Установить syslinux загрузчик (используется для flash)
""" """
if not self.clVars.Get('os_install_mbr'): if not self.clVars.Get('os_install_mbr'):
return return
# прописать MBR # прописать MBR
ddProcess = process("/bin/dd","if=/usr/share/syslinux/mbr.bin", dd_process = process("/bin/dd", "if=/usr/share/syslinux/mbr.bin",
"of=%s"%self.clVars.Get('os_install_mbr')[0], "of=%s" % self.clVars.Get('os_install_mbr')[0],
stderr=STDOUT) stderr=STDOUT)
if ddProcess.failed(): if dd_process.failed():
raise DistributiveError( raise DistributiveError(
_("Failed to write the master boot record\n%s")% _("Failed to write the master boot record\n%s") %
ddProcess.read()) dd_process.read())
target.close() target.close()
# выполнить установку syslinux загрузчика # выполнить установку syslinux загрузчика
installRootDev = self.clVars.Get('os_install_root_dev') install_root_dev = self.clVars.Get('os_install_root_dev')
syslinuxProcess = process("/usr/bin/syslinux", syslinux_process = process("/usr/bin/syslinux",
installRootDev, stderr=STDOUT) install_root_dev, stderr=STDOUT)
if syslinuxProcess.failed(): if syslinux_process.failed():
raise DistributiveError(_("Failed to install syslinux\n%s")% raise DistributiveError(_("Failed to install syslinux\n%s") %
syslinuxProcess.read()) syslinux_process.read())
# установить загрузочный раздел активным # установить загрузочный раздел активным
return self.setActivePartition(self.clVars.Get('os_install_root_dev')) return self.setActivePartition(self.clVars.Get('os_install_root_dev'))
def installGrub2Bootloader(self,target): def installGrub2Bootloader(self, target):
""" """
Установка GRUB2 загрузчика Установка GRUB2 загрузчика
""" """
# проверить наличие grub2 # проверить наличие grub2
cmdGrubInstall = self.clVars.Get('os_grub2_path') cmd_grub_install = self.clVars.Get('os_grub2_path')
if not cmdGrubInstall: if not cmd_grub_install:
raise DistributiveError(_("Failed to install the bootloader")) raise DistributiveError(_("Failed to install the bootloader"))
process("sync").success() process("sync").success()
# если установка GRUB2 производится на текущую систему # если установка GRUB2 производится на текущую систему
# загруженную в builder режиме # загруженную в builder режиме
if self.clVars.Get('os_install_scratch') == "on" and \ if (self.clVars.Get('os_install_scratch') == "on" and
self.clVars.Get('cl_action') != "system": self.clVars.Get('cl_action') != "system"):
prefixBoot = "/mnt/scratch" prefix_boot = "/mnt/scratch"
else: else:
prefixBoot = "/" prefix_boot = "/"
# установка UEFI # установка UEFI
if self.clVars.GetBool('os_install_uefi_set'): if self.clVars.GetBool('os_install_uefi_set'):
grubParams = ["--boot-directory=%s"%pathJoin(prefixBoot, self.install_grub_uefi(cmd_grub_install, prefix_boot, target)
target.getBootDirectory()),
"--target=x86_64-efi",
"--efi-directory=%s"%
target.getEfiDirectory(),
"--force"]
# в случае установки на usb-hdd EFI загрузчик не прописывается
# в efivars
if self.clVars.Get('os_install_root_type') == 'usb-hdd':
grubParams.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."))
grubProcess = process(cmdGrubInstall,
*grubParams, stderr=STDOUT,envdict=os.environ)
if grubProcess.failed():
raise DistributiveError(_("Failed to install the bootloader"))
# проверяем успешность создания загрузочной записи
# если среди загрузочных записей отсутствует запись
# calculate и dmesg содержит сообщение об ошибке efivars -
# запись создать не удалось
efiBootMgr = varsShare().getProgPath('/usr/sbin/efibootmgr')
dmesg = varsShare().getProgPath('/bin/dmesg')
if efiBootMgr and dmesg:
if not re.search('Boot.*calculate',
process(efiBootMgr).read(),re.M) and \
re.search('efivars.*set_variable.*failed',
process(dmesg).read(),re.M):
raise DistributiveError(
_("Failed to create the UEFI boot record"))
# не UEFI установка # не UEFI установка
else: else:
# получить загрузочный раздел (если есть /boot, то self.install_grub_biosboot(cmd_grub_install, prefix_boot, target)
# он является загрузочным иначе корень)
for bootPath in ("/boot","/"): def install_grub_biosboot(self, cmd_grub_install, prefix_boot, target):
bootDisk = self.clVars.Select("os_install_disk_dev", """
where="os_install_disk_mount",eq=bootPath,limit=1) Установить GRUB, загрузчик MBR (GPT)
if bootDisk: """
self.setActivePartition(bootDisk) # получить загрузочный раздел (если есть /boot, то
break # он является загрузочным иначе корень)
for boot_path in ("/boot", "/"):
# если GRUB2 версии 2.00 и выше, обычная установка требует boot_disk = self.clVars.Select("os_install_disk_dev",
# параметра --target=i386-pc, иначе GRUB2 может попытаться where="os_install_disk_mount",
# прописать себя как UEFI eq=boot_path, limit=1)
if filter(lambda x:"2." in x, if boot_disk:
process(cmdGrubInstall,'--version')): self.setActivePartition(boot_disk)
platform = ["--target=i386-pc"] break
else:
platform = [] # если GRUB2 версии 2.00 и выше, обычная установка требует
# прописать GRUB2 на все указанные диски # параметра --target=i386-pc, иначе GRUB2 может попытаться
for mbrDisk in self.clVars.Get('os_install_mbr'): # прописать себя как UEFI
grubProcess = process(cmdGrubInstall, if filter(lambda x: "2." in x,
"--boot-directory=%s"%pathJoin(prefixBoot, process(cmd_grub_install, '--version')):
target.getBootDirectory()), platform = ["--target=i386-pc"]
mbrDisk, "--force", *platform, else:
stderr=STDOUT,envdict=os.environ) platform = []
if grubProcess.failed(): # прописать GRUB2 на все указанные диски
raise DistributiveError(_("Failed to install the bootloader")) for mbr_disk in self.clVars.Get('os_install_mbr'):
grub_process = process(cmd_grub_install,
def installLegacyGrubBootloader(self,target): "--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"))
def install_grub_uefi(self, cmd_grub_install, prefix_boot, target):
"""
Установить grub с UEFI загрузчиком
"""
grub_params = [
"--boot-directory=%s" % pathJoin(
prefix_boot,
target.getBootDirectory()),
"--target=x86_64-efi",
"--efi-directory=%s" %
target.getEfiDirectory(),
"--force"]
# в случае установки на 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"))
# проверяем успешность создания загрузочной записи
# если среди загрузочных записей отсутствует запись
# 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',
process(efi_boot_mgr).read(), re.M) and \
re.search('efivars.*set_variable.*failed',
process(dmesg).read(), re.M):
raise DistributiveError(
_("Failed to create the UEFI boot record"))
def installLegacyGrubBootloader(self, target):
""" """
Install legecy grub boot loader Install legecy grub boot loader
Perform grub installation to disk, which has root partition Perform grub installation to disk, which has root partition
""" """
cmdGrub = varsShare().getProgPath('/sbin/grub') cmd_grub = getProgPath('/sbin/grub')
if not cmdGrub: if not cmd_grub:
raise DistributiveError(_("Failed to install the bootloader")) raise DistributiveError(_("Failed to install the bootloader"))
grubProcess = process(cmdGrub, grub_process = process(
"--device-map=%s/boot/grub/device.map"%target.getDirectory(), cmd_grub,
"--batch",stderr=STDOUT) "--device-map=%s/boot/grub/device.map" % target.getDirectory(),
bootDisk = self.Select('os_install_disk_grub', "--batch", stderr=STDOUT)
where='os_install_disk_mount', boot_disk = self.clVars.Select('os_install_disk_grub',
_in=('/','/boot'), where='os_install_disk_mount',
sort='DESC',limit=1) _in=('/', '/boot'),
if not bootDisk: sort='DESC', limit=1)
if not boot_disk:
raise DistributiveError(_("Failed to determine the boot disk")) raise DistributiveError(_("Failed to determine the boot disk"))
self.setActivePartition(bootDisk) self.setActivePartition(boot_disk)
for mbrDisk in self.clVars.Get('os_install_mbr'): for mbr_disk in self.clVars.Get('os_install_mbr'):
mbrDiskNum = self.Select("os_device_map", mbr_disk_num = self.clVars.Select("os_device_map",
where="os_device_dev", where="os_device_dev",
eq=mbrDisk) eq=mbr_disk)
if not mbrDiskNum and mbrDiskNum != 0: if not mbr_disk_num and mbr_disk_num != 0:
raise DistributiveError(_("Failed to determine mbr")) raise DistributiveError(_("Failed to determine mbr"))
for line in ("root (hd%s)"%bootDisk, for line in ("root (hd%s)" % boot_disk,
"setup (hd%d)"%mbrDiskNum, "setup (hd%d)" % mbr_disk_num,
"quit"): "quit"):
grubProcess.write("%s\n"%line) grub_process.write("%s\n" % line)
if grubProcess.failed(): if grub_process.failed():
raise DistributiveError(_("Failed to install the bootloader")) raise DistributiveError(_("Failed to install the bootloader"))
def setupOpenGL(self): def setupOpenGL(self):
""" """
Выполнить выбор opengl для текущего видеодрайвера Выполнить выбор opengl для текущего видеодрайвера
""" """
defaultGL = "xorg-x11" default_gl = "xorg-x11"
pathGlModules = path.join(self.clVars.Get('cl_chroot_path'), path_gl_modules = path.join(self.clVars.Get('cl_chroot_path'),
'usr/lib/opengl') 'usr/lib/opengl')
openGLenv = path.join(self.clVars.Get('cl_chroot_path'), open_gl_env = path.join(self.clVars.Get('cl_chroot_path'),
'etc/env.d/03opengl') 'etc/env.d/03opengl')
openGlMods = filter(lambda x:x != "global", open_gl_mods = filter(lambda x: x != "global",
listDirectory(pathGlModules)) listDirectory(path_gl_modules))
mapGL_drivers = {'fglrx':"ati" if "ati" in openGlMods map_gl_drivers = {'fglrx': ("ati" if "ati" in open_gl_mods
else defaultGL, else default_gl),
'nvidia':"nvidia" if "nvidia" in openGlMods 'nvidia': "nvidia" if "nvidia" in open_gl_mods
else defaultGL} else default_gl}
x11_driver = self.clVars.Get('os_install_x11_video_drv') x11_driver = self.clVars.Get('os_install_x11_video_drv')
if x11_driver in mapGL_drivers: if x11_driver in map_gl_drivers:
newModuleName = mapGL_drivers[x11_driver] 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: else:
newModuleName = defaultGL current_module_name = ""
curModuleName = map(lambda x:x.strip().rpartition('=')[-1].strip('"\''), if current_module_name == new_module_name:
filter(lambda x: x.startswith("OPENGL_PROFILE="),
readLinesFile(openGLenv)))
curModuleName = curModuleName[-1] if curModuleName else ""
if curModuleName == newModuleName:
return True return True
return process('/usr/bin/eselect','opengl','set',newModuleName).success() return process('/usr/bin/eselect', 'opengl', 'set',
new_module_name).success()
def checkVideoDriver(self): def checkVideoDriver(self):
""" """
@ -364,37 +380,38 @@ class Install:
""" """
if self.clVars.Get('hr_video') != 'nvidia': if self.clVars.Get('hr_video') != 'nvidia':
return True return True
maskFile = '/etc/portage/package.mask' mask_file = '/etc/portage/package.mask'
nvidiaMaskFile = path.join(maskFile,'nvidia') nvidia_mask_file = path.join(mask_file, 'nvidia')
# если package.mask является файлом - делаем его директорией # если package.mask является файлом - делаем его директорией
if path.isfile(maskFile): if path.isfile(mask_file):
os.rename(maskFile,maskFile+"2") os.rename(mask_file, mask_file + "2")
os.mkdir(maskFile,mode=0755) os.mkdir(mask_file, mode=0755)
os.rename(maskFile+"2",path.join(maskFile,"default")) os.rename(mask_file + "2", path.join(mask_file, "default"))
curNvidiaMask = readFile(nvidiaMaskFile).strip() current_nvidia_mask = readFile(nvidia_mask_file).strip()
maskNvidia = self.clVars.Get('os_nvidia_mask') new_nvidia_mask = self.clVars.Get('os_nvidia_mask')
if maskNvidia == curNvidiaMask: if new_nvidia_mask == current_nvidia_mask:
return True return True
open(nvidiaMaskFile,'w').write(maskNvidia) open(nvidia_mask_file, 'w').write(new_nvidia_mask)
return True return True
def changeScheduler(self,scheduler): def changeScheduler(self, scheduler):
""" """
Изменить текущий IO планировщик Изменить текущий IO планировщик
""" """
root_dev = self.clVars.Select('os_disk_parent', root_dev = self.clVars.Select('os_disk_parent',
where='os_disk_mount', where='os_disk_mount',
eq='/',limit=1) eq='/', limit=1)
try: try:
schedpath = ("/sys%s/queue/scheduler"% scheduler_path = (
(getUdevDeviceInfo(name=root_dev).get('DEVPATH',''))) "/sys%s/queue/scheduler" %
if path.exists(schedpath): (getUdevDeviceInfo(name=root_dev).get('DEVPATH', '')))
open(schedpath,'w').write(scheduler) if path.exists(scheduler_path):
except: open(scheduler_path, 'w').write(scheduler)
raise InstallError(("Unable to change the I/O scheduler")) except Exception:
raise InstallError(_("Unable to change the I/O scheduler"))
return True return True
def autopartition(self,table,devices,data,lvm,lvm_vgname,bios_grub, def autopartition(self, table, devices, data, lvm, lvm_vgname, bios_grub,
bios_grub_size): bios_grub_size):
""" """
Авторазметка диска с таблицей разделов 'table', диски указываются Авторазметка диска с таблицей разделов 'table', диски указываются
@ -403,76 +420,77 @@ class Install:
bios_grub раздел, bios_grub_size - раздел bios grub раздела в байтах bios_grub раздел, bios_grub_size - раздел bios grub раздела в байтах
""" """
ap = AutoPartition() ap = AutoPartition()
ap.clearLvm(devices,self.clVars) ap.clearLvm(devices, self.clVars)
ap.clearRaid(devices,self.clVars) ap.clearRaid(devices, self.clVars)
ap.recreateSpace(table,devices,data,lvm, ap.recreateSpace(table, devices, data, lvm,
lvm_vgname,bios_grub,bios_grub_size) lvm_vgname, bios_grub, bios_grub_size)
return True return True
def format(self,target): def format(self, target):
""" """
Форматировать разделы для 'target' дистрибутива Форматировать разделы для 'target' дистрибутива
""" """
target.performFormat() target.performFormat()
return True return True
def unpack(self,source,target,filesnum): def unpack(self, source, target, files_num):
""" """
Распаковать 'source' в 'target', 'filesnum' количество копируемых файлов Распаковать 'source' в 'target', 'filesnum' количество копируемых файлов
""" """
self.addProgress() self.addProgress()
if filesnum.isdigit(): if files_num.isdigit():
filesnum = int(filesnum) files_num = int(files_num)
else: else:
filesnum = 0 files_num = 0
target.installFrom(source, callbackProgress=self.setProgress, target.installFrom(source, callbackProgress=self.setProgress,
filesnum=filesnum) filesnum=files_num)
return True return True
def copyClt(self,source,target,cltpath): def copyClt(self, source, target, cltpath):
""" """
Скопировать clt шаблоны из 'cltpath' в 'target' дистрибутив из Скопировать clt шаблоны из 'cltpath' в 'target' дистрибутив из
'source' дистрибутива 'source' дистрибутива
""" """
targetdir = target.getDirectory() target_dir = target.getDirectory()
sourcedir = source.getDirectory() source_dir = source.getDirectory()
for f in filter(lambda x:x.endswith('.clt'), for f in filter(lambda x: x.endswith('.clt'),
chain(*map(lambda x:find(pathJoin(sourcedir,x),filetype="f"), chain(*map(lambda x: find(pathJoin(source_dir, x),
cltpath))): filetype="f"),
copyWithPath(f,targetdir,prefix=sourcedir) cltpath))):
copyWithPath(f, target_dir, prefix=source_dir)
return True return True
def copyOther(self,source,target): def copyOther(self, source, target):
""" """
Скопировать прочие настройки из текущей системы в новую Скопировать прочие настройки из текущей системы в новую
""" """
fileMask = re.compile("(/etc/ssh/ssh_host_.*|" file_mask = re.compile("(/etc/ssh/ssh_host_.*|"
"/root/.ssh/(id_.*|known_hosts))") "/root/.ssh/(id_.*|known_hosts))")
targetdir = target.getDirectory() target_dir = target.getDirectory()
sourcedir = source.getDirectory() source_dir = source.getDirectory()
for f in filter(fileMask.search, for f in filter(file_mask.search,
chain(*map(lambda x:find(pathJoin(sourcedir,x),filetype="f"), chain(*map(lambda x: find(pathJoin(source_dir, x),
["/etc","/root/.ssh"]))): filetype="f"),
copyWithPath(f,targetdir,prefix=sourcedir) ["/etc", "/root/.ssh"]))):
copyWithPath(f, target_dir, prefix=source_dir)
return True return True
def rndString(self): def rndString(self):
""" """
Получить произвольную строку из 8 символов Получить произвольную строку из 8 символов
""" """
"""Get random string with len 8 char""" """Get random string with len 8 char"""
return "".join([choice(string.ascii_letters+string.digits) return "".join([choice(string.ascii_letters + string.digits)
for i in xrange(0,8)]) for i in xrange(0, 8)])
def _getFreeDirectory(self,directory): def _getFreeDirectory(self, directory):
""" """
Получить название директории Получить название директории
""" """
newDirectoryName = directory new_dir_name = directory
while path.exists(newDirectoryName): while path.exists(new_dir_name):
newDirectoryName = "%s.%s"%(directory,self.rndString()) new_dir_name = "%s.%s" % (directory, self.rndString())
return newDirectoryName return new_dir_name
def remountNTFS(self): def remountNTFS(self):
""" """
@ -480,50 +498,48 @@ class Install:
""" """
res = True res = True
for disk in self.clVars.Select('os_disk_dev', for disk in self.clVars.Select('os_disk_dev',
where='os_disk_format',like='ntfs'): where='os_disk_format', like='ntfs'):
mountDir = self._getFreeDirectory('/var/lib/calculate/mount.ntfs') mount_dir = self._getFreeDirectory('/var/lib/calculate/mount.ntfs')
try: try:
os.mkdir(mountDir) os.mkdir(mount_dir)
except: except (OSError, IOError):
continue continue
if process('/bin/mount',disk,mountDir).success(): if process('/bin/mount', disk, mount_dir).success():
for i in (0.2,0.5,1,2,4,5): for i in (0.2, 0.5, 1, 2, 4, 5):
if process('/bin/umount',mountDir).success(): if process('/bin/umount', mount_dir).success():
break break
time.sleep(i) time.sleep(i)
else: else:
self.printWARNING(_("Unable to umount %s")%mountDir) self.printWARNING(_("Unable to umount %s") % mount_dir)
res = False res = False
try: try:
os.rmdir(mountDir) os.rmdir(mount_dir)
except: except (OSError, IOError):
self.printWARNING(_("Unable to remove directory %s")%mountDir) self.printWARNING(
_("Unable to remove directory %s") % mount_dir)
return False return False
return res return res
def mountBind(self,target): def mountBind(self, target):
""" """
Подключить bind точки монтирования у дистрибутива Подключить bind точки монтирования у дистрибутива
""" """
target.postinstallMountBind() target.postinstallMountBind()
return True return True
def userMigrate(self,target,migrate_data,root_pwd): def userMigrate(self, target, migrate_data, root_pwd):
""" """
Перенос текущих пользователей в новую систему, Перенос текущих пользователей в новую систему,
установка пароля пользователя root установка пароля пользователя root
""" """
objMigrate = migrate(target.getDirectory()) migrator = migrate(target.getDirectory())
if not objMigrate.migrate(migrate_data,root_pwd,[],[],): if not migrator.migrate(migrate_data, root_pwd, [], [], ):
raise InstallError(_("Failed to migrate users onto the new system")) raise InstallError(_("Failed to migrate users onto the new system"))
return True return True
def umount(self,distr): def umount(self, distr):
""" """
Отключить дистрибутив Отключить дистрибутив
""" """
distr.close() distr.close()
return True return True
def mytest(self):
return False

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -19,21 +19,25 @@ from calculate.lib.encrypt import encrypt
from os import path from os import path
from calculate.lib.utils.files import pathJoin from calculate.lib.utils.files import pathJoin
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_install3',sys.modules[__name__])
setLocalTranslate('cl_install3', sys.modules[__name__])
class MigrationError(Exception): class MigrationError(Exception):
pass pass
class _shareData:
class _shareData(object):
"""Share class""" """Share class"""
_reNumb = re.compile("^\d+$") _reNumb = re.compile("^\d+$")
def getDataInFile(self, fileName='', lenData=7): def getDataInFile(self, fileName='', lenData=7):
"""Get data list from file""" """Get data list from file"""
return filter(lambda x: len(x)==lenData, return filter(lambda x: len(x) == lenData,
map(lambda x: x.rstrip().split(":"), open(fileName))) map(lambda x: x.rstrip().split(":"), open(fileName)))
class migrateGroups(_shareData): class migrateGroups(_shareData):
"""Migrate group to new system""" """Migrate group to new system"""
@ -51,29 +55,31 @@ class migrateGroups(_shareData):
def getThisData(self): def getThisData(self):
"""Get data migrate groups in this system""" """Get data migrate groups in this system"""
return filter(lambda x:\ return filter(lambda x: \
self._reNumb.match(x[2]) and self.minGid<=int(x[2])<=self.maxGid, self._reNumb.match(x[2]) and self.minGid <= int(
x[2]) <= self.maxGid,
self.getData()) self.getData())
def getNewData(self): def getNewData(self):
"""Get data migrate groups in new system""" """Get data migrate groups in new system"""
fileName = pathJoin(self.prefixNewSystem, self.fileGroups) fileName = pathJoin(self.prefixNewSystem, self.fileGroups)
return filter(lambda x:\ return filter(lambda x: \
self._reNumb.match(x[2]) and self.minGid<=int(x[2])<=self.maxGid, self._reNumb.match(x[2]) and self.minGid <= int(
x[2]) <= self.maxGid,
self.getData(fileName=fileName)) self.getData(fileName=fileName))
def getNewDataSystemGroups(self): def getNewDataSystemGroups(self):
"""Get data system groups in new system""" """Get data system groups in new system"""
fileName = pathJoin(self.prefixNewSystem, self.fileGroups) fileName = pathJoin(self.prefixNewSystem, self.fileGroups)
return filter(lambda x:\ return filter(lambda x: \
self._reNumb.match(x[2]) and\ self._reNumb.match(x[2]) and \
(int(x[2])>self.maxGid or int(x[2])<self.minGid), (int(x[2]) > self.maxGid or int(x[2]) < self.minGid),
self.getData(fileName=fileName)) self.getData(fileName=fileName))
def getNewProcessedData(self): def getNewProcessedData(self):
"""Get processed data migrate groups in new system""" """Get processed data migrate groups in new system"""
# data this Group no users # data this Group no users
dataThisGroupsNoUsers = map(lambda x: x[:3]+[""], self.getThisData()) dataThisGroupsNoUsers = map(lambda x: x[:3] + [""], self.getThisData())
dataNewGroups = self.getNewData() dataNewGroups = self.getNewData()
namesNewGroups = map(lambda x: x[0], dataNewGroups) namesNewGroups = map(lambda x: x[0], dataNewGroups)
gidsNewGroups = map(lambda x: x[2], dataNewGroups) gidsNewGroups = map(lambda x: x[2], dataNewGroups)
@ -81,16 +87,18 @@ class migrateGroups(_shareData):
nameGroup = data[0] nameGroup = data[0]
gid = data[2] gid = data[2]
if nameGroup in namesNewGroups: if nameGroup in namesNewGroups:
dataNewGroups = filter(lambda x: x[0]!=nameGroup,dataNewGroups) dataNewGroups = filter(lambda x: x[0] != nameGroup,
dataNewGroups)
namesNewGroups = map(lambda x: x[0], dataNewGroups) namesNewGroups = map(lambda x: x[0], dataNewGroups)
gidsNewGroups = map(lambda x: x[2], dataNewGroups) gidsNewGroups = map(lambda x: x[2], dataNewGroups)
if gid in gidsNewGroups: if gid in gidsNewGroups:
dataNewGroups = filter(lambda x: x[2]!=gid, dataNewGroups) dataNewGroups = filter(lambda x: x[2] != gid, dataNewGroups)
namesNewGroups = map(lambda x: x[0], dataNewGroups) namesNewGroups = map(lambda x: x[0], dataNewGroups)
gidsNewGroups = map(lambda x: x[2], dataNewGroups) gidsNewGroups = map(lambda x: x[2], dataNewGroups)
systemGroupsNewData = self.getNewDataSystemGroups() systemGroupsNewData = self.getNewDataSystemGroups()
return systemGroupsNewData, dataNewGroups, dataThisGroupsNoUsers return systemGroupsNewData, dataNewGroups, dataThisGroupsNoUsers
class migrateUsers(_shareData): class migrateUsers(_shareData):
"""Migrate users to new system""" """Migrate users to new system"""
@ -108,34 +116,36 @@ class migrateUsers(_shareData):
def getThisData(self): def getThisData(self):
"""Get data migrate users in this system""" """Get data migrate users in this system"""
return filter(lambda x:\ return filter(lambda x: \
self._reNumb.match(x[2]) and self.minId<=int(x[2])<=self.maxId, self._reNumb.match(x[2]) and self.minId <= int(
x[2]) <= self.maxId,
self.getData()) self.getData())
def getNewData(self): def getNewData(self):
"""Get data migrate users in new system""" """Get data migrate users in new system"""
fileName = pathJoin(self.prefixNewSystem, self.filePasswd) fileName = pathJoin(self.prefixNewSystem, self.filePasswd)
return filter(lambda x:\ return filter(lambda x: \
self._reNumb.match(x[2]) and self.minId<=int(x[2])<=self.maxId, self._reNumb.match(x[2]) and self.minId <= int(
x[2]) <= self.maxId,
self.getData(fileName=fileName)) self.getData(fileName=fileName))
def getNewDataSystemUsers(self): def getNewDataSystemUsers(self):
"""Get data system users in new system""" """Get data system users in new system"""
fileName = pathJoin(self.prefixNewSystem, self.filePasswd) fileName = pathJoin(self.prefixNewSystem, self.filePasswd)
return filter(lambda x:\ return filter(lambda x: \
self._reNumb.match(x[2]) and\ self._reNumb.match(x[2]) and \
(int(x[2]>self.maxId) or int(x[2])<self.minId), (int(x[2] > self.maxId) or int(x[2]) < self.minId),
self.getData(fileName=fileName)) self.getData(fileName=fileName))
def getThisDataSystemUsers(self): def getThisDataSystemUsers(self):
"""Get data system users in this system""" """Get data system users in this system"""
fileName = self.filePasswd fileName = self.filePasswd
return filter(lambda x:\ return filter(lambda x: \
self._reNumb.match(x[2]) and\ self._reNumb.match(x[2]) and \
(int(x[2]>self.maxId) or int(x[2])<self.minId), (int(x[2] > self.maxId) or int(x[2]) < self.minId),
self.getData(fileName=fileName)) self.getData(fileName=fileName))
def getNewProcessedData(self, migrateUsers=[]): def getNewProcessedData(self, migrateUsers=()):
"""Get processed data migrate users in new system""" """Get processed data migrate users in new system"""
dataThisUsers = self.getThisData() dataThisUsers = self.getThisData()
if migrateUsers: if migrateUsers:
@ -148,11 +158,11 @@ class migrateUsers(_shareData):
nameUser = data[0] nameUser = data[0]
uid = data[2] uid = data[2]
if nameUser in namesNewUsers: if nameUser in namesNewUsers:
dataNewUsers = filter(lambda x: x[0]!=nameUser, dataNewUsers) dataNewUsers = filter(lambda x: x[0] != nameUser, dataNewUsers)
namesNewUsers = map(lambda x: x[0], dataNewUsers) namesNewUsers = map(lambda x: x[0], dataNewUsers)
uidsNewUsers = map(lambda x: x[2], dataNewUsers) uidsNewUsers = map(lambda x: x[2], dataNewUsers)
if uid in uidsNewUsers: if uid in uidsNewUsers:
dataNewUsers = filter(lambda x: x[2]!=uid, dataNewUsers) dataNewUsers = filter(lambda x: x[2] != uid, dataNewUsers)
namesNewUsers = map(lambda x: x[0], dataNewUsers) namesNewUsers = map(lambda x: x[0], dataNewUsers)
uidsNewUsers = map(lambda x: x[2], dataNewUsers) uidsNewUsers = map(lambda x: x[2], dataNewUsers)
systemUsersNewData = self.getNewDataSystemUsers() systemUsersNewData = self.getNewDataSystemUsers()
@ -161,21 +171,21 @@ class migrateUsers(_shareData):
systemUsersThisData = [] systemUsersThisData = []
if migrateUsers: if migrateUsers:
# this users < minId # this users < minId
systemUsersThisData = filter(lambda x: int(x[2])<self.minId and\ systemUsersThisData = filter(lambda x: int(x[2]) < self.minId and \
x[0] in migrateUsers, x[0] in migrateUsers,
self.getThisDataSystemUsers()) self.getThisDataSystemUsers())
for data in systemUsersThisData: for data in systemUsersThisData:
nameUser = data[0] nameUser = data[0]
uid = data[2] uid = data[2]
if nameUser in systemUsersNewNames: if nameUser in systemUsersNewNames:
systemUsersNewData = filter(lambda x: x[0]!=nameUser, systemUsersNewData = filter(lambda x: x[0] != nameUser,
systemUsersNewData) systemUsersNewData)
systemUsersNewNames = map(lambda x: x[0], systemUsersNewNames = map(lambda x: x[0],
systemUsersNewData) systemUsersNewData)
systemUsersNewUids = map(lambda x: x[2], systemUsersNewUids = map(lambda x: x[2],
systemUsersNewData) systemUsersNewData)
if uid in systemUsersNewUids: if uid in systemUsersNewUids:
systemUsersNewData = filter(lambda x: x[2]!=uid, systemUsersNewData = filter(lambda x: x[2] != uid,
systemUsersNewData) systemUsersNewData)
systemUsersNewNames = map(lambda x: x[0], systemUsersNewNames = map(lambda x: x[0],
systemUsersNewData) systemUsersNewData)
@ -184,6 +194,7 @@ class migrateUsers(_shareData):
return (systemUsersThisData, systemUsersNewData, return (systemUsersThisData, systemUsersNewData,
dataNewUsers, dataThisUsers) dataNewUsers, dataThisUsers)
class migrateShadow(_shareData): class migrateShadow(_shareData):
"""Migrate users to new system""" """Migrate users to new system"""
@ -210,16 +221,17 @@ class migrateShadow(_shareData):
def getNewData(self): def getNewData(self):
"""Get data migrate users in new system""" """Get data migrate users in new system"""
return filter(lambda x: x[0] in self.newMigrateUsers, return filter(lambda x: x[0] in self.newMigrateUsers,
self.getData(fileName=self.newFileName)) self.getData(fileName=self.newFileName))
def getNewDataSystemShadow(self): def getNewDataSystemShadow(self):
"""Get data system users in new system""" """Get data system users in new system"""
return filter(lambda x: x[0] in self.sysNewMigrateUsers, return filter(lambda x: x[0] in self.sysNewMigrateUsers,
self.getData(fileName=self.newFileName)) self.getData(fileName=self.newFileName))
def getThisDataSystemShadow(self): def getThisDataSystemShadow(self):
"""Get data system users in this system""" """Get data system users in this system"""
return filter(lambda x: x[0] in self.sysThisMigrateUsers,self.getData()) return filter(lambda x: x[0] in self.sysThisMigrateUsers,
self.getData())
def getNewProcessedData(self): def getNewProcessedData(self):
"""Get processed data migrate shadow in new system""" """Get processed data migrate shadow in new system"""
@ -229,7 +241,8 @@ class migrateShadow(_shareData):
for data in dataThisShadow: for data in dataThisShadow:
nameUser = data[0] nameUser = data[0]
if nameUser in namesNewShadow: if nameUser in namesNewShadow:
dataNewShadow = filter(lambda x: x[0]!=nameUser, dataNewShadow) dataNewShadow = filter(lambda x: x[0] != nameUser,
dataNewShadow)
namesNewShadow = map(lambda x: x[0], dataNewShadow) namesNewShadow = map(lambda x: x[0], dataNewShadow)
systemShadowNewData = self.getNewDataSystemShadow() systemShadowNewData = self.getNewDataSystemShadow()
systemShadowThisData = self.getThisDataSystemShadow() systemShadowThisData = self.getThisDataSystemShadow()
@ -237,17 +250,18 @@ class migrateShadow(_shareData):
for data in systemShadowThisData: for data in systemShadowThisData:
nameUser = data[0] nameUser = data[0]
if nameUser in systemShadowNewNames: if nameUser in systemShadowNewNames:
systemShadowNewData = filter(lambda x: x[0]!=nameUser, systemShadowNewData = filter(lambda x: x[0] != nameUser,
systemShadowNewData) systemShadowNewData)
systemShadowNewNames = map(lambda x: x[0], systemShadowNewData) systemShadowNewNames = map(lambda x: x[0], systemShadowNewData)
return (systemShadowThisData, systemShadowNewData, dataNewShadow, return (systemShadowThisData, systemShadowNewData, dataNewShadow,
dataThisShadow) dataThisShadow)
class migrate:
class migrate(object):
"""Migrate users ang groups to new system""" """Migrate users ang groups to new system"""
templateShadow = "%(user)s:%(hash)s:%(days)s:0:%(maxDays)s:%(warnDays)s:::" 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" templateUser = "%(user)s:x:%(id)s:%(gid)s::/home/%(user)s:/bin/bash"
templateGroup="%(group)s:x:%(gid)s:" templateGroup = "%(group)s:x:%(gid)s:"
dataUsers = [] dataUsers = []
dataGroups = [] dataGroups = []
dataShadow = [] dataShadow = []
@ -268,21 +282,22 @@ class migrate:
def addThisUsersToGroups(self, users): def addThisUsersToGroups(self, users):
"""Add users to groups""" """Add users to groups"""
thisGroupsData = self.objGroups.getData() thisGroupsData = self.objGroups.getData()
thisGroupsData = map(lambda x: (x[0],x[3].split(',')), thisGroupsData = map(lambda x: (x[0], x[3].split(',')),
thisGroupsData) thisGroupsData)
dataGroups = [] dataGroups = []
for data in self.dataGroups: for data in self.dataGroups:
groupName = data[0] groupName = data[0]
thisUsersInGroup = map(lambda x: x[1], thisUsersInGroup = map(lambda x: x[1],
filter(lambda x: x[0]==groupName, thisGroupsData)) filter(lambda x: x[0] == groupName,
thisUsersInGroup = reduce(lambda x,y: x+y, thisUsersInGroup,[]) thisGroupsData))
addUsers = list(set(thisUsersInGroup)&set(users)) thisUsersInGroup = reduce(lambda x, y: x + y, thisUsersInGroup, [])
addUsers = list(set(thisUsersInGroup) & set(users))
if addUsers: if addUsers:
newUsersInGroup = data[3].split(',') newUsersInGroup = data[3].split(',')
for user in addUsers: for user in addUsers:
if not user in newUsersInGroup: if not user in newUsersInGroup:
newUsersInGroup.append(user) newUsersInGroup.append(user)
data[3] = ','.join(filter(lambda x:x,newUsersInGroup)) data[3] = ','.join(filter(lambda x: x, newUsersInGroup))
dataGroups.append(data) dataGroups.append(data)
self.dataGroups = dataGroups self.dataGroups = dataGroups
return self.dataGroups return self.dataGroups
@ -290,27 +305,27 @@ class migrate:
def getNextUid(self): def getNextUid(self):
"""get next uid""" """get next uid"""
listUid = map(lambda x: int(x[2]), listUid = map(lambda x: int(x[2]),
filter(lambda x:\ filter(lambda x: \
self.objUsers._reNumb.match(x[2]) and\ self.objUsers._reNumb.match(x[2]) and \
self.minId<=int(x[2])<=self.maxId, self.minId <= int(x[2]) <= self.maxId,
self.dataUsers)) self.dataUsers))
if listUid: if listUid:
return max(listUid)+1 return max(listUid) + 1
return self.minId return self.minId
def getNextGid(self): def getNextGid(self):
"""get next gid""" """get next gid"""
listGid = map(lambda x: int(x[2]), listGid = map(lambda x: int(x[2]),
filter(lambda x:\ filter(lambda x: \
self.objGroups._reNumb.match(x[2]) and\ self.objGroups._reNumb.match(x[2]) and \
self.minGid<=int(x[2])<=self.maxGid, self.minGid <= int(x[2]) <= self.maxGid,
self.dataGroups)) self.dataGroups))
if listGid: if listGid:
return max(listGid)+1 return max(listGid) + 1
return self.minGid return self.minGid
def isSystemUser(self, userName): def isSystemUser(self, userName):
if filter(lambda x: x[0]==userName and int(x[2])<=self.minSysId, if filter(lambda x: x[0] == userName and int(x[2]) <= self.minSysId,
self.dataUsers): self.dataUsers):
return True return True
return False return False
@ -325,34 +340,33 @@ class migrate:
usersInGroup = data[3].split(',') usersInGroup = data[3].split(',')
if not userName in usersInGroup: if not userName in usersInGroup:
usersInGroup.append(userName) usersInGroup.append(userName)
data[3] = ','.join(filter(lambda x:x,usersInGroup)) data[3] = ','.join(filter(lambda x: x, usersInGroup))
dataGroups.append(data) dataGroups.append(data)
self.dataGroups = dataGroups self.dataGroups = dataGroups
return self.dataGroups return self.dataGroups
def addUserToDefaultGroups(self, userName): def addUserToDefaultGroups(self, userName):
"""Add users to default groups""" """Add users to default groups"""
return self.addUserToGroups(userName,self.newUserGroups) return self.addUserToGroups(userName, self.newUserGroups)
def changePassword(self, userName, pwdHash, maxDays="99999", warnDays="7"): def changePassword(self, userName, pwdHash, maxDays="99999", warnDays="7"):
if not filter(lambda x: x[0]==userName, self.dataUsers): if not filter(lambda x: x[0] == userName, self.dataUsers):
raise MigrationError(_("User %s not found")%userName) raise MigrationError(_("User %s not found") % userName)
indexFoundUser = False indexFoundUser = False
for i, data in enumerate(self.dataShadow): for i, data in enumerate(self.dataShadow):
if data[0]==userName: if data[0] == userName:
indexFoundUser = i indexFoundUser = i
break break
if callable(pwdHash): if callable(pwdHash):
pwdHash = pwdHash(userName) pwdHash = pwdHash(userName)
if pwdHash is False: if pwdHash is False:
return False return False
shadowDict = {"user":userName, shadowDict = {"user": userName,
"hash":pwdHash, "hash": pwdHash,
"days":str(int(time.time()/86400)), "days": str(int(time.time() / 86400)),
"maxDays":maxDays, "maxDays": maxDays,
"warnDays":warnDays} "warnDays": warnDays}
shadowLine = self.templateShadow %shadowDict shadowLine = self.templateShadow % shadowDict
shadowList = shadowLine.split(":") shadowList = shadowLine.split(":")
if indexFoundUser is False: if indexFoundUser is False:
self.dataShadow.append(shadowList) self.dataShadow.append(shadowList)
@ -363,80 +377,83 @@ class migrate:
def addUser(self, userName, userGroups, pwdHash): def addUser(self, userName, userGroups, pwdHash):
"""Add user""" """Add user"""
# find user # find user
if filter(lambda x: x[0]==userName, self.dataUsers): if filter(lambda x: x[0] == userName, self.dataUsers):
return "EXISTS" return "EXISTS"
else: else:
strUid = str(self.getNextUid()) strUid = str(self.getNextUid())
strGid = str(self.getNextGid()) strGid = str(self.getNextGid())
groupName = userName groupName = userName
dataExistGroup = filter(lambda x: x[0]==groupName, self.dataGroups) dataExistGroup = filter(lambda x: x[0] == groupName,
self.dataGroups)
if dataExistGroup: if dataExistGroup:
strGid = dataExistGroup[0][2] strGid = dataExistGroup[0][2]
else: else:
# add group # add group
groupDict = {"group":groupName,"gid":strGid} groupDict = {"group": groupName, "gid": strGid}
groupLine = self.templateGroup %groupDict groupLine = self.templateGroup % groupDict
groupList = groupLine.split(":") groupList = groupLine.split(":")
self.dataGroups.append(groupList) self.dataGroups.append(groupList)
# add user # add user
userDict = {"user":userName, "id":strUid, "gid":strGid} userDict = {"user": userName, "id": strUid, "gid": strGid}
userline = self.templateUser %userDict userline = self.templateUser % userDict
userList = userline.split(":") userList = userline.split(":")
self.dataUsers.append(userList) self.dataUsers.append(userList)
# add shadow # add shadow
if not self.changePassword(userName, pwdHash): if not self.changePassword(userName, pwdHash):
return False return False
# add user to default groups # add user to default groups
self.addUserToGroups(userName,userGroups) self.addUserToGroups(userName, userGroups)
return True return True
def checkPermFiles(self): def checkPermFiles(self):
"""Check permission files""" """Check permission files"""
checkThisFiles = [migrateGroups.fileGroups, migrateUsers.filePasswd, checkThisFiles = [migrateGroups.fileGroups, migrateUsers.filePasswd,
migrateShadow.fileShadow] migrateShadow.fileShadow]
checkNewFiles = map(lambda x: pathJoin(self.prefixNewSystem,x), checkNewFiles = map(lambda x: pathJoin(self.prefixNewSystem, x),
checkThisFiles) checkThisFiles)
parentDir = lambda x: "".join(os.path.split(x)[:-1]) parentDir = lambda x: "".join(os.path.split(x)[:-1])
notRead = lambda x: not os.access(x, os.R_OK) notRead = lambda x: not os.access(x, os.R_OK)
notWrite = lambda x: not os.access(x, os.W_OK) notWrite = lambda x: not os.access(x, os.W_OK)
filesNotRead = filter(notRead,checkThisFiles) filesNotRead = filter(notRead, checkThisFiles)
if filesNotRead: if filesNotRead:
raise MigrationError(_("Failed to read files") + _(": ") + raise MigrationError(_("Failed to read files") + _(": ") +
", ".join(filesNotRead)) ", ".join(filesNotRead))
filesNotWrite = filter(notWrite,checkNewFiles) filesNotWrite = filter(notWrite, checkNewFiles)
if filesNotWrite: if filesNotWrite:
raise MigrationError(_("Failed to write to files") + _(": ") + raise MigrationError(_("Failed to write to files") + _(": ") +
", ".join(filesNotWrite)) ", ".join(filesNotWrite))
# Check permissions backup files # Check permissions backup files
checkNewBackupFiles = map(lambda x:pathJoin(self.prefixNewSystem,x+"-"), checkNewBackupFiles = map(
checkThisFiles) lambda x: pathJoin(self.prefixNewSystem, x + "-"),
checkThisFiles)
notWriteBackup = lambda x: not os.access(x, os.W_OK) and \ notWriteBackup = lambda x: not os.access(x, os.W_OK) and \
(os.path.exists(x) or \ (os.path.exists(x) or
not os.access(os.path.dirname(x), os.W_OK)) not os.access(os.path.dirname(x), os.W_OK))
filesNotWrite = filter(notWriteBackup, checkNewBackupFiles) filesNotWrite = filter(notWriteBackup, checkNewBackupFiles)
if filesNotWrite: if filesNotWrite:
raise MigrationError(_("Failed to write to files") + _(": ") + raise MigrationError(_("Failed to write to files") + _(": ") +
", ".join(filesNotWrite)) ", ".join(filesNotWrite))
return True return True
def saveNewFiles(self): def saveNewFiles(self):
"""Save /etc/passwd /etc/group /etc/shadow to new system""" """Save /etc/passwd /etc/group /etc/shadow to new system"""
listFilesThisSystem = [migrateGroups.fileGroups,migrateUsers.filePasswd, listFilesThisSystem = [migrateGroups.fileGroups,
migrateUsers.filePasswd,
migrateShadow.fileShadow] migrateShadow.fileShadow]
listFiles = map(lambda x:(pathJoin(self.prefixNewSystem,x), listFiles = map(lambda x: (pathJoin(self.prefixNewSystem, x),
pathJoin(self.prefixNewSystem,x+"-")), pathJoin(self.prefixNewSystem, x + "-")),
listFilesThisSystem) listFilesThisSystem)
listData = [self.dataGroups, self.dataUsers, self.dataShadow] listData = [self.dataGroups, self.dataUsers, self.dataShadow]
allData = zip(listFiles,listData) allData = zip(listFiles, listData)
for fileNames, data in allData: for fileNames, data in allData:
buff = "\n".join(map(lambda x: ":".join(x), data)) + "\n" buff = "\n".join(map(lambda x: ":".join(x), data)) + "\n"
for fileName in fileNames: for fileName in fileNames:
FD = open(fileName, "w+") FD = open(fileName, "w+")
FD.write(buff) FD.write(buff)
FD.close() FD.close()
def createUserGuest(self): def createUserGuest(self):
if filter(lambda x: int(x[2])>=self.minSysId, self.dataUsers): if filter(lambda x: int(x[2]) >= self.minSysId, self.dataUsers):
return True return True
else: else:
# add user guest # add user guest
@ -445,58 +462,67 @@ class migrate:
pwdHash = encryptObj.getHashPasswd(pwd, "shadow_ssha256") pwdHash = encryptObj.getHashPasswd(pwd, "shadow_ssha256")
if pwdHash is False: if pwdHash is False:
return False return False
if not self.addUser("guest", pwdHash): if not self.addUser("guest", "guest", pwdHash):
return False return False
return True return True
def createHomeDirs(self,addUsersList,existsMigrateUsers): def createHomeDirs(self, addUsersList, existsMigrateUsers):
"""Create home directories for all migreate users""" """Create home directories for all migreate users"""
def createHome(userdata): def createHome(userdata):
if not userdata[5].startswith('/dev/'): if not userdata[5].startswith('/dev/'):
homedir = pathJoin(self.prefixNewSystem,userdata[5]) homedir = pathJoin(self.prefixNewSystem, userdata[5])
if not path.exists(homedir): if not path.exists(homedir):
os.mkdir(homedir) os.mkdir(homedir)
os.chown(homedir,int(userdata[2]),int(userdata[3])) os.chown(homedir, int(userdata[2]), int(userdata[3]))
users = list(set(map(lambda x:x[0],addUsersList)+existsMigrateUsers)-\ users = list(
set(["root"])) set(map(lambda x: x[0],
addUsersList) + existsMigrateUsers) - {"root"})
try: try:
map(createHome,filter(lambda x:x[0] in users, self.dataUsers)) map(createHome, filter(lambda x: x[0] in users, self.dataUsers))
except Exception,e: except Exception as e:
raise DistributiveError( raise MigrationError(
_("Failed to create the user's home directory")) _("Failed to create the user's home directory"))
def migrate(self, addUsersList=[], rootPwd="", def migrate(self, addUsersList=None, rootPwd="",
pwdUsersList=[], existsMigrateUsers=[]): pwdUsersList=None, existsMigrateUsers=None):
"""Migrate users ang groups to new system""" """Migrate users ang groups to new system"""
if addUsersList is None:
addUsersList = []
elif not any(addUsersList):
addUsersList = []
if pwdUsersList is None:
pwdUsersList = []
if existsMigrateUsers is None:
existsMigrateUsers = []
if not self.checkPermFiles(): if not self.checkPermFiles():
return False return False
if not any(addUsersList): migrateUsers = (["root"] +
addUsersList = [] map(lambda x: x[0], addUsersList + pwdUsersList))
migrateUsers = ["root"]+\
map(lambda x: x[0], addUsersList + pwdUsersList)
for existMigrUser in existsMigrateUsers: for existMigrUser in existsMigrateUsers:
if not existMigrUser in migrateUsers: if existMigrUser not in migrateUsers:
migrateUsers.append(existMigrUser) migrateUsers.append(existMigrUser)
# add root to migrate users # add root to migrate users
dataUsers = self.objUsers.getNewProcessedData(migrateUsers) dataUsers = self.objUsers.getNewProcessedData(migrateUsers)
dataGroups = self.objGroups.getNewProcessedData() dataGroups = self.objGroups.getNewProcessedData()
thisSystemUsers, newSystemUsers, newUsers, thisUsers =\ thisSystemUsers, newSystemUsers, newUsers, thisUsers = \
map(lambda x: map(lambda y: y[0],x), dataUsers) map(lambda x: map(lambda y: y[0], x), dataUsers)
objShadow = migrateShadow(thisSystemUsers, newSystemUsers, newUsers, objShadow = migrateShadow(thisSystemUsers, newSystemUsers, newUsers,
thisUsers, self.prefixNewSystem) thisUsers, self.prefixNewSystem)
dataShadow = objShadow.getNewProcessedData() dataShadow = objShadow.getNewProcessedData()
self.dataGroups = reduce(lambda x,y: x+y, dataGroups, []) self.dataGroups = reduce(lambda x, y: x + y, dataGroups, [])
self.dataUsers = reduce(lambda x,y: x+y, dataUsers, []) self.dataUsers = reduce(lambda x, y: x + y, dataUsers, [])
self.dataShadow = reduce(lambda x,y: x+y, dataShadow, []) self.dataShadow = reduce(lambda x, y: x + y, dataShadow, [])
self.addThisUsersToGroups(thisUsers) self.addThisUsersToGroups(thisUsers)
for userName, pwdHash, maxDays, warnDays in pwdUsersList: for userName, pwdHash, maxDays, warnDays in pwdUsersList:
if not self.changePassword(userName, pwdHash, if not self.changePassword(userName, pwdHash,
maxDays=maxDays, maxDays=maxDays,
warnDays=warnDays): warnDays=warnDays):
return False return False
for userName, userGroups, pwdHash in [["root",[],rootPwd]]+addUsersList: for userName, userGroups, pwdHash in [
#if self.isSystemUser(userName): ["root", [], rootPwd]] + addUsersList:
# if self.isSystemUser(userName):
# raise MigrationError(_("%s is a system user") %userName) # raise MigrationError(_("%s is a system user") %userName)
ret = self.addUser(userName, userGroups, pwdHash) ret = self.addUser(userName, userGroups, pwdHash)
if not ret: if not ret:
@ -509,17 +535,17 @@ class migrate:
if not self.createUserGuest(): if not self.createUserGuest():
return False return False
self.saveNewFiles() self.saveNewFiles()
self.createHomeDirs(addUsersList,existsMigrateUsers) self.createHomeDirs(addUsersList, existsMigrateUsers)
return True return True
class currentUsers(migrate): class currentUsers(migrate):
"""Current users""" """Current users"""
def __init__(self): def __init__(self):
self.prefixNewSystem = '/' super(currentUsers, self).__init__('/')
self.objGroups = migrateGroups(self.prefixNewSystem)
self.objUsers = migrateUsers(self.prefixNewSystem)
def addUsers(self,*users_passwd): def addUsers(self, *users_passwd):
"""Added users and groups to current system""" """Added users and groups to current system"""
if not self.checkPermFiles(): if not self.checkPermFiles():
return False return False
@ -533,17 +559,18 @@ class currentUsers(migrate):
getHash = encrypt().getHashPasswd getHash = encrypt().getHashPasswd
for userName, pwd in zip(users_passwd[0::2], for userName, pwd in zip(users_passwd[0::2],
users_passwd[1::2]): users_passwd[1::2]):
pwdHash = getHash(pwd,"shadow_ssha256") pwdHash = getHash(pwd, "shadow_ssha256")
if not self.addUser(userName, pwdHash): if not self.addUser(userName, userName, pwdHash):
return False return False
self.saveNewFiles() self.saveNewFiles()
return True return True
def hasUsers(self,*users): def hasUsers(self, *users):
"""Is users in system""" """Is users in system"""
if not self.checkPermFiles(): if not self.checkPermFiles():
return False return False
getDataInFile = _shareData().getDataInFile getDataInFile = _shareData().getDataInFile
self.dataUsers = map(lambda x:x[0], self.dataUsers = map(lambda x: x[0],
getDataInFile(fileName=migrateUsers.filePasswd,lenData=7)) getDataInFile(fileName=migrateUsers.filePasswd,
lenData=7))
return set(self.dataUsers) >= set(users) return set(self.dataUsers) >= set(users)

@ -1,4 +1,4 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org
# #
@ -15,142 +15,148 @@
# limitations under the License. # limitations under the License.
import sys import sys
from calculate.core.server.func import Action,Tasks from calculate.core.server.func import Action, Tasks
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate from calculate.install.distr import DistributiveError
from calculate.install.migrate_users import MigrationError
from calculate.install.variables.autopartition import AutopartitionError
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.files import FilesError
from calculate.install.install import (MigrationError, TemplatesError, from calculate.install.install import InstallError
InstallError,
AutopartitionError, DistributiveError)
setLocalTranslate('cl_install3',sys.modules[__name__]) setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
class ClInstallAction(Action): class ClInstallAction(Action):
""" """
Установка системы Установка системы
""" """
# ошибки, которые отображаются без подробностей # ошибки, которые отображаются без подробностей
native_error = (FilesError,MigrationError, TemplatesError, native_error = (FilesError, MigrationError, TemplatesError,
InstallError, AutopartitionError, DistributiveError) InstallError, AutopartitionError, DistributiveError)
successMessage = None successMessage = None
failedMessage = None failedMessage = None
interruptMessage = None interruptMessage = None
# список задач для действия # список задач для действия
tasks = \ tasks = [
[# авторазметка диска # авторазметка диска
{'name':'autopartition', {'name': 'autopartition',
'message':__("Creating a new partition table"), 'message': __("Creating a new partition table"),
'method':"Install.autopartition(cl_autopartition_table," 'method': "Install.autopartition(cl_autopartition_table,"
"cl_autopartition_device,cl_autopartition_disk_data," "cl_autopartition_device,cl_autopartition_disk_data,"
"cl_autopartition_lvm_set,cl_autopartition_lvm_vgname," "cl_autopartition_lvm_set,cl_autopartition_lvm_vgname,"
"cl_autopartition_bios_grub_set," "cl_autopartition_bios_grub_set,"
"cl_autopartition_bios_grub_size)", "cl_autopartition_bios_grub_size)",
'condition':lambda dv:dv.Get('cl_autopartition_set') == 'on'}, 'condition': lambda dv: dv.Get('cl_autopartition_set') == 'on'},
# форматирование разделов на которые устанавливается дистрибутив # форматирование разделов на которые устанавливается дистрибутив
{'name':'format', {'name': 'format',
'message':__("Formatting the partitions"), 'message': __("Formatting the partitions"),
'method':'Install.format(cl_target)', 'method': 'Install.format(cl_target)',
'condition':lambda dv:dv.Get('cl_target').needFormat}, 'condition': lambda dv: dv.Get('cl_target').needFormat},
# распаковка дистрибутива # распаковка дистрибутива
{'name':'unpack', {'name': 'unpack',
'message':__("Unpacking the system image to the target"), 'message': __("Unpacking the system image to the target"),
'method':'Install.unpack(cl_image,cl_target,os_install_linux_files)', 'method': 'Install.unpack(cl_image,cl_target,os_install_linux_files)',
}, },
# отметка что установка идет на HDD # отметка что установка идет на HDD
{'name':'hdd', {'name': 'hdd',
'condition':lambda dv:dv.Get('os_install_root_type') != 'flash' and \ 'condition': lambda dv: dv.Get(
dv.Get('os_install_pxe') == 'off'}, 'os_install_root_type') != 'flash' and
# копирование clt шаблонов dv.Get('os_install_pxe') == 'off'},
{'name':'hdd:copy_clt', # копирование clt шаблонов
'message':__("Copying clt templates to the new system"), {'name': 'hdd:copy_clt',
'method':'Install.copyClt(cl_source,cl_target,cl_template_clt_path)' 'message': __("Copying clt templates to the new system"),
'method': 'Install.copyClt(cl_source,cl_target,cl_template_clt_path)'
},
# копирование прочих файлов
{'name': 'hdd:copy_other',
'message': __("Copying other settings to the new system"),
'method': 'Install.copyOther(cl_source,cl_target)',
'condition': lambda dv: dv.Get('os_root_type') != "livecd",
},
# перемонтирование ntfs для определения windows
{'name': 'hdd:remount_ntfs',
'method': 'Install.remountNTFS()',
'essential': False,
}, },
# копирование прочих файлов # наложение шаблонов при установке на жесткий диск
{'name':'hdd:copy_other', {'name': 'hdd:apply_templates',
'message':__("Copying other settings to the new system"), 'message': __("Updating the configuration"),
'method':'Install.copyOther(cl_source,cl_target)', # наложить шаблоны в установленный дистрибутив, включая clt шаблоны
'condition':lambda dv:dv.Get('os_root_type') != "livecd", # без использования фильтров по clt шаблонам
'method': 'Install.applyTemplates(cl_target,True,False,None)',
}, },
# перемонтирование ntfs для определения windows # наложение шаблонов при PXE установке
{'name':'hdd:remount_ntfs', {'name': 'apply_templates_pxe',
'method':'Install.remountNTFS()', 'message': __("Configuring PXE install"),
'essential':False, # наложить шаблоны в установленный дистрибутив, исключая clt
# без использования фильтров по clt шаблонам
'method': 'Install.applyTemplates(None,False,False,None)',
'condition': lambda dv: dv.Get('os_install_pxe') == 'on'
}, },
# наложение шаблонов при установке на жесткий диск # наложение шаблонов при установке на flash диск
{'name':'hdd:apply_templates', {'name': 'apply_templates_flash',
'message':__("Updating the configuration"), 'message': __("Configuring Flash install"),
# наложить шаблоны в установленный дистрибутив, включая clt шаблоны # наложить шаблоны в установленный дистрибутив, исключая clt
# без использования фильтров по clt шаблонам # без использования фильтров по clt шаблонам
'method':'Install.applyTemplates(cl_target,True,False,None)', 'method': 'Install.applyTemplates(None,False,False,cl_target)',
'condition': lambda dv: dv.Get('os_install_root_type') == "flash"
}, },
# наложение шаблонов при PXE установке # подключить точки монтирования bind
{'name':'apply_templates_pxe', {'name': 'hdd:mount_bind',
'message':__("Configuring PXE install"), 'message': __("Post-install configuration"),
# наложить шаблоны в установленный дистрибутив, исключая clt 'method': "Install.mountBind(cl_target)",
# без использования фильтров по clt шаблонам
'method':'Install.applyTemplates(None,False,False,None)',
'condition':lambda dv:dv.Get('os_install_pxe') == 'on'
},
# наложение шаблонов при установке на flash диск
{'name':'apply_templates_flash',
'message':__("Configuring Flash install"),
# наложить шаблоны в установленный дистрибутив, исключая clt
# без использования фильтров по clt шаблонам
'method':'Install.applyTemplates(None,False,False,cl_target)',
'condition':lambda dv:dv.Get('os_install_root_type') == "flash"
},
# подключить точки монтирования bind
{'name':'hdd:mount_bind',
'message':__("Post-install configuration"),
'method':"Install.mountBind(cl_target)",
}, },
# перенос пользователей # перенос пользователей
{'name':'hdd:user_migrate', {'name': 'hdd:user_migrate',
'message':__("Migrating users"), 'message': __("Migrating users"),
'method':'Install.userMigrate(cl_target,cl_migrate_data,' 'method': 'Install.userMigrate(cl_target,cl_migrate_data,'
'cl_migrate_root_pwd)', 'cl_migrate_root_pwd)',
}, },
# подготовка загрузчика # подготовка загрузчика
{'name':'prepare_boot', {'name': 'prepare_boot',
'message':__("Preparing the system for reboot"), 'message': __("Preparing the system for reboot"),
'method':'Install.prepareBoot(cl_target)', 'method': 'Install.prepareBoot(cl_target)',
'condition':lambda dv:(dv.Get('os_install_mbr') or \ 'condition': lambda dv: (dv.Get('os_install_mbr') or
dv.Get('os_install_uefi_set') == 'on') and \ dv.Get('os_install_uefi_set') == 'on') and
dv.Get('os_install_pxe') == 'off'}, dv.Get('os_install_pxe') == 'off'},
# отключение исходного дистрибутива # отключение исходного дистрибутива
{'name':'umount_source', {'name': 'umount_source',
'message':__("Letting go the source distribution"), 'message': __("Letting go the source distribution"),
'method':'Install.umount(cl_image)', 'method': 'Install.umount(cl_image)',
'condition':lambda dv:dv.Get('cl_image') and dv.Get('cl_image').childs, 'condition': lambda dv: dv.Get('cl_image') and dv.Get(
'depend': Tasks.has("unpack")}, 'cl_image').childs,
# отключение установленного дистрибутива 'depend': Tasks.has("unpack")},
{'name':'umount_target', # отключение установленного дистрибутива
'message':__("Unmounting the target system volume"), {'name': 'umount_target',
'method':'Install.umount(cl_target)', 'message': __("Unmounting the target system volume"),
'condition':lambda dv:dv.Get('cl_target') and dv.Get('cl_target').childs, 'method': 'Install.umount(cl_target)',
'depend': Tasks.has("unpack")}, 'condition': lambda dv: dv.Get('cl_target') and dv.Get(
# вывести сообщение в случае успеха 'cl_target').childs,
{'name':'success', 'depend': Tasks.has("unpack")},
'message':__("System successfully installed!")}, # вывести сообщение в случае успеха
# вывести сообщение в случае ошибки {'name': 'success',
{'name':'failed', 'message': __("System successfully installed!")},
'message':__("Failed to install the system!"), # вывести сообщение в случае ошибки
'depend': (Tasks.failed() & Tasks.hasnot("interrupt"))}, {'name': 'failed',
# вывести сообщение о том, что установка прервана пользователем 'message': __("Failed to install the system!"),
{'name':'intmessage', 'depend': (Tasks.failed() & Tasks.hasnot("interrupt"))},
'message':__("Installation manually interrupted"), # вывести сообщение о том, что установка прервана пользователем
'depend': Tasks.has("interrupt")}, {'name': 'intmessage',
# подтверждение на перезагрузку 'message': __("Installation manually interrupted"),
{'name':'ask_reboot', 'depend': Tasks.has("interrupt")},
'message':__("Would you like to reboot your computer " # подтверждение на перезагрузку
{'name': 'ask_reboot',
'message': __("Would you like to reboot your computer "
"now to complete the installation?"), "now to complete the installation?"),
'confirm':'no', 'confirm': 'no',
'condition':lambda dv:dv.Get('os_install_pxe') == 'off'}, 'condition': lambda dv: dv.Get('os_install_pxe') == 'off'},
# перезагрузить компьютер # перезагрузить компьютер
{'name':'reboot', {'name': 'reboot',
'message':__("System reboot"), 'message': __("System reboot"),
'command':'/sbin/reboot', 'command': '/sbin/reboot',
'depend':Tasks.result("ask_reboot",eq='yes') 'depend': Tasks.result("ask_reboot", eq='yes')
} }
] ]

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,24 +15,27 @@
# limitations under the License. # limitations under the License.
import sys import sys
from calculate.core.server.func import Action,Tasks from calculate.core.server.func import Action
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate from calculate.install.distr import DistributiveError
from calculate.install.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.files import FilesError
from calculate.lib.utils.portage import isPkgInstalled from calculate.lib.utils.portage import isPkgInstalled
from calculate.install.install import (MigrationError, TemplatesError, from calculate.install.install import InstallError
InstallError, from calculate.install.variables.autopartition import AutopartitionError
AutopartitionError, DistributiveError)
setLocalTranslate('cl_install3',sys.modules[__name__]) setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
class ClSetupVideoAction(Action): class ClSetupVideoAction(Action):
""" """
Действие для настройки параметров видео Действие для настройки параметров видео
""" """
# ошибки, которые отображаются без подробностей # ошибки, которые отображаются без подробностей
native_error = (FilesError,MigrationError, TemplatesError, native_error = (FilesError, MigrationError, TemplatesError,
InstallError, AutopartitionError, DistributiveError) InstallError, AutopartitionError, DistributiveError)
templateTaskMessage = __("Video settings are being configured") templateTaskMessage = __("Video settings are being configured")
successMessage = __("Video settings configured!") successMessage = __("Video settings configured!")
@ -41,50 +44,51 @@ class ClSetupVideoAction(Action):
addon_tasks = [ addon_tasks = [
# проверить и настроить параметры для nvidia драйвера # проверить и настроить параметры для nvidia драйвера
{'name':'check_video', {'name': 'check_video',
'message':__("Checking the video driver"), 'message': __("Checking the video driver"),
'method':'Install.checkVideoDriver()', 'method': 'Install.checkVideoDriver()',
'condition': lambda:isPkgInstalled('xorg-server') 'condition': lambda: isPkgInstalled('xorg-server')
}, },
{'name':'setup_opengl', {'name': 'setup_opengl',
'message':__("Configuring OpenGL"), 'message': __("Configuring OpenGL"),
'method':'Install.setupOpenGL()', 'method': 'Install.setupOpenGL()',
'condition': lambda:isPkgInstalled('xorg-server') 'condition': lambda: isPkgInstalled('xorg-server')
}, },
{'name':'setupvideo', {'name': 'setupvideo',
'condition': lambda Get: Get('cl_setup') == 'video' 'condition': lambda Get: Get('cl_setup') == 'video'
}, },
{'name':'setupvideo:reboot', {'name': 'setupvideo:reboot',
'warning':__("To apply the changes, reboot the system"), 'warning': __("To apply the changes, reboot the system"),
'condition': lambda Get:((Get('os_x11_video_drv') != \ 'condition': lambda Get: ((Get('os_x11_video_drv') !=
Get('os_install_x11_video_drv') and \ Get('os_install_x11_video_drv') and
(Get('os_x11_video_drv') in Get('os_x11_kms_video_drv') \ (Get('os_x11_video_drv') in Get(
or Get('os_install_x11_video_drv') \ 'os_x11_kms_video_drv')
in Get('os_x11_kms_video_drv'))) or Get('os_install_x11_video_drv')
and Get('os_install_root_type') != 'livecd') in Get('os_x11_kms_video_drv')))
}, and Get('os_install_root_type') != 'livecd')
{'name':'setupvideo:restart', },
'warning':__("To apply the changes, restart the X server"), {'name': 'setupvideo:restart',
'condition': lambda Get:((Get('os_x11_video_drv') != 'warning': __("To apply the changes, restart the X server"),
Get('os_install_x11_video_drv') and 'condition': lambda Get: ((Get('os_x11_video_drv') !=
(not Get('os_x11_video_drv') in Get('os_install_x11_video_drv') and
Get('os_x11_kms_video_drv') and (not Get('os_x11_video_drv') in
not Get('os_install_x11_video_drv') Get('os_x11_kms_video_drv') and
in Get('os_x11_kms_video_drv'))) not Get('os_install_x11_video_drv')
and Get('os_install_root_type') != 'livecd') in Get('os_x11_kms_video_drv')))
} and Get('os_install_root_type') != 'livecd')
] }
]
def __init__(self): def __init__(self):
# список задач для действия # список задач для действия
self.tasks = [ self.tasks = [
{'name':'apply_templates', {'name': 'apply_templates',
'message':self.templateTaskMessage, 'message': self.templateTaskMessage,
# наложить шаблоны на текущий дистрибутив, включая clt шаблоны # наложить шаблоны на текущий дистрибутив, включая clt шаблоны
# без использования фильтров по clt шаблонам # без использования фильтров по clt шаблонам
'method':'Install.applyTemplates(cl_source,cl_template_clt_set,'\ 'method': 'Install.applyTemplates(cl_source,cl_template_clt_set,'
'cl_merge_set,None)', 'cl_merge_set,None)',
}] }]
# выполнить дополнительные задачи # выполнить дополнительные задачи
self.tasks.extend(self.addon_tasks) self.tasks.extend(self.addon_tasks)
Action.__init__(self) Action.__init__(self)
@ -98,6 +102,7 @@ class ClSetupSystemAction(ClSetupVideoAction):
successMessage = __("System configured!") successMessage = __("System configured!")
failedMessage = __("Failed to configure the system!") failedMessage = __("Failed to configure the system!")
class ClSetupAudioAction(ClSetupSystemAction): class ClSetupAudioAction(ClSetupSystemAction):
""" """
Действие для настройки аудио параметров Действие для настройки аудио параметров
@ -107,6 +112,7 @@ class ClSetupAudioAction(ClSetupSystemAction):
successMessage = __("Audio settings configured!") successMessage = __("Audio settings configured!")
failedMessage = __("Failed to configure the audio parameters!") failedMessage = __("Failed to configure the audio parameters!")
class ClSetupLocaleAction(ClSetupSystemAction): class ClSetupLocaleAction(ClSetupSystemAction):
""" """
Действие для настройки языковых параметров Действие для настройки языковых параметров
@ -117,6 +123,7 @@ class ClSetupLocaleAction(ClSetupSystemAction):
successMessage = __("System configured!") successMessage = __("System configured!")
failedMessage = __("Failed to configure the system!") failedMessage = __("Failed to configure the system!")
class ClSetupNetworkAction(ClSetupSystemAction): class ClSetupNetworkAction(ClSetupSystemAction):
""" """
Действие для настройки аудио параметров Действие для настройки аудио параметров
@ -126,6 +133,7 @@ class ClSetupNetworkAction(ClSetupSystemAction):
successMessage = __("Network settings configured!") successMessage = __("Network settings configured!")
failedMessage = __("Failed to configure the network settings!") failedMessage = __("Failed to configure the network settings!")
class ClSetupSessionAction(ClSetupSystemAction): class ClSetupSessionAction(ClSetupSystemAction):
""" """
Действие для настройки пользовательских параметров Действие для настройки пользовательских параметров
@ -135,6 +143,7 @@ class ClSetupSessionAction(ClSetupSystemAction):
successMessage = __("Session settings configured!") successMessage = __("Session settings configured!")
failedMessage = __("Failed to configure the session settings!") failedMessage = __("Failed to configure the session settings!")
class ClSetupBootAction(ClSetupSystemAction): class ClSetupBootAction(ClSetupSystemAction):
""" """
Действие для настройки параметров загрузки Действие для настройки параметров загрузки
@ -145,25 +154,25 @@ class ClSetupBootAction(ClSetupSystemAction):
addon_tasks = [ addon_tasks = [
# установить загрузчик # установить загрузчик
{'name':'prepare_bootloader', {'name': 'prepare_bootloader',
'message':_("Installing the bootloader"), 'message': _("Installing the bootloader"),
'method':'Install.prepareBoot(cl_image)', 'method': 'Install.prepareBoot(cl_image)',
'condition':(lambda Get:(Get('os_install_mbr') or 'condition': (lambda Get: (Get('os_install_mbr') or
Get('os_install_uefi_set') == 'on') and Get('os_install_uefi_set') == 'on') and
Get('os_root_type') != 'livecd' and Get('os_root_type') != 'livecd' and
Get('os_install_scratch') == 'off') Get('os_install_scratch') == 'off')
}, },
{'name':'no_scratch', {'name': 'no_scratch',
'warning':_("The builder mode is no longer supported"), 'warning': _("The builder mode is no longer supported"),
'condition':lambda Get:Get('os_install_scratch') == 'on' 'condition': lambda Get: Get('os_install_scratch') == 'on'
}, },
# изменить IO планировщик # изменить IO планировщик
{'name':'change_ioscheduler', {'name': 'change_ioscheduler',
'message':_("Changing the I/O scheduler"), 'message': _("Changing the I/O scheduler"),
'method':'Install.changeScheduler(os_install_kernel_scheduler)', 'method': 'Install.changeScheduler(os_install_kernel_scheduler)',
'condition':(lambda dv:dv.Get('os_root_type') != 'livecd' and 'condition': (lambda dv: dv.Get('os_root_type') != 'livecd' and
dv.Select('os_disk_parent', dv.Select('os_disk_parent',
where='os_disk_mount', where='os_disk_mount',
eq='/',limit=1)) eq='/', limit=1))
}, },
] ]

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -20,18 +20,22 @@ import re
from os import path from os import path
from calculate.lib.datavars import Variable, VariableError, ReadonlyVariable from calculate.lib.datavars import Variable, VariableError, ReadonlyVariable
from calculate.lib.utils.portage import isPkgInstalled from calculate.lib.utils.portage import isPkgInstalled
from calculate.lib.utils.files import process, STDOUT, getProgPath, readFile from calculate.lib.utils.files import readFile
from calculate.lib.utils.common import (getVideoFromXorgLog, from calculate.lib.utils.common import (getVideoFromXorgLog,
getVideoFromXorgConf, getVideoFromCmdLine, getVideoFromXorgConf,
getAvailableVideo, getValueFromCmdLine, getVideoFromCmdLine,
getCompositeFromXorgconf, getVideoFromModules, getAvailableVideo, getValueFromCmdLine,
getVideoFromVendor, getInstalledVideo) getCompositeFromXorgconf,
getVideoFromModules,
getVideoFromVendor, getInstalledVideo)
from calculate.install.distr import DistributiveError from calculate.install.distr import DistributiveError
import fcntl import fcntl
import struct import struct
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_install3',sys.modules[__name__])
setLocalTranslate('cl_install3', sys.modules[__name__])
class VideoVariable(Variable): class VideoVariable(Variable):
""" """
@ -45,7 +49,7 @@ class VideoVariable(Variable):
'radeon': _("ATI open source video driver"), 'radeon': _("ATI open source video driver"),
'nouveau': _("NVidia open source video driver"), 'nouveau': _("NVidia open source video driver"),
'default': _("X.Org Server auto detection") 'default': _("X.Org Server auto detection")
} }
def uncompatible(self): def uncompatible(self):
""" """
@ -59,11 +63,13 @@ class VideoVariable(Variable):
_("This distribution does not provide a Xorg server") _("This distribution does not provide a Xorg server")
return "" return ""
class ResolutionVariable(VideoVariable): class ResolutionVariable(VideoVariable):
""" """
Abstract resolution variable Abstract resolution variable
""" """
fbres = False fbres = False
def choice(self): def choice(self):
resolutions = ["640x480", "800x480", "800x600", "1024x576", "1024x600", resolutions = ["640x480", "800x480", "800x600", "1024x576", "1024x600",
"1024x768", "1200x800", "1280x800", "1280x720", "1024x768", "1200x800", "1280x800", "1280x720",
@ -73,20 +79,21 @@ class ResolutionVariable(VideoVariable):
"1600x900", "1600x1200", "2048x1152", "2560x1440", "1600x900", "1600x1200", "2048x1152", "2560x1440",
"2560x1600"] "2560x1600"]
if self.fbres: if self.fbres:
return map(lambda x:"%s-32"%x, return map(lambda x: "%s-32" % x,
resolutions) resolutions)
else: else:
return resolutions return resolutions
def check(self,value): def check(self, value):
""" """
Check resolution format 1234x567 Check resolution format 1234x567
""" """
if not re.match('^\d+x\d+(-\d+(@\d+)?)?$',value): if not re.match('^\d+x\d+(-\d+(@\d+)?)?$', value):
raise VariableError( raise VariableError(
_("Wrong resolution {resolution} {example}").format( _("Wrong resolution {resolution} {example}").format(
resolution=value, resolution=value,
example="(%s:%s)"%(_("Example"),"1024x768"))) example="(%s:%s)" % (_("Example"), "1024x768")))
class VariableOsInstallX11Resolution(ResolutionVariable): class VariableOsInstallX11Resolution(ResolutionVariable):
""" """
@ -106,11 +113,12 @@ class VariableOsInstallX11Resolution(ResolutionVariable):
def get(self): def get(self):
# get resolution from xorg.log # get resolution from xorg.log
res = self.Get('os_x11_resolution') res = self.Get('os_x11_resolution')
if res or self.Get('os_install_root_type') in ('livecd','usb-hdd'): if res or self.Get('os_install_root_type') in ('livecd', 'usb-hdd'):
return res or self.fallback_resolution return res or self.fallback_resolution
else: else:
return self.fallback_resolution return self.fallback_resolution
class VariableOsInstallX11VideoAvailable(VideoVariable): class VariableOsInstallX11VideoAvailable(VideoVariable):
""" """
Get available (already installed or installable drivers Get available (already installed or installable drivers
@ -121,14 +129,15 @@ class VariableOsInstallX11VideoAvailable(VideoVariable):
def get(self): def get(self):
image = self.Get('cl_image') image = self.Get('cl_image')
if image: if image:
with image as distr: with image:
try: try:
distrPath = image.getDirectory() distrPath = image.getDirectory()
if isPkgInstalled('xorg-server',prefix=distrPath): if isPkgInstalled('xorg-server', prefix=distrPath):
return (sorted(filter(self.supported.__contains__, return (sorted(filter(self.supported.__contains__,
getAvailableVideo(prefix=distrPath))) + getAvailableVideo(
prefix=distrPath))) +
[self.default_video]) [self.default_video])
except DistributiveError as e: except DistributiveError:
pass pass
return [] return []
@ -172,52 +181,55 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
return self.default_video return self.default_video
# if type system is usb-hdd then get detect video driver # if type system is usb-hdd then get detect video driver
if self.Get('os_install_root_type') == 'usb-hdd': if self.Get('os_install_root_type') == 'usb-hdd':
methods = ((getVideoFromModules,()), methods = ((getVideoFromModules, ()),
(getVideoFromCmdLine,()), (getVideoFromCmdLine, ()),
(getVideoFromVendor,(self.Get('hr_video'),list_video))) (getVideoFromVendor,
(self.Get('hr_video'), list_video)))
else: else:
# test current video driver for install system # test current video driver for install system
methods = ((getVideoFromXorgLog,('/',list_video)), methods = ((getVideoFromXorgLog, ('/', list_video)),
(getVideoFromXorgConf,('/',)), (getVideoFromXorgConf, ('/',)),
(getVideoFromModules,()), (getVideoFromModules, ()),
(getVideoFromCmdLine,()), (getVideoFromCmdLine, ()),
(getVideoFromVendor,(self.Get('hr_video'),list_video))) (getVideoFromVendor,
for func,args in methods: (self.Get('hr_video'), list_video)))
for func, args in methods:
drv = func(*args) drv = func(*args)
if drv in list_video: if drv in list_video:
return drv return drv
return self.default_video return self.default_video
else: else:
for drv in map(lambda x:x[0], self.choice()): for drv in map(lambda x: x[0], self.choice()):
videoSysPath = path.join("/sys/module",drv,"refcnt") videoSysPath = path.join("/sys/module", drv, "refcnt")
refcnt = readFile(videoSysPath).strip() refcnt = readFile(videoSysPath).strip()
if refcnt.isdigit() and int(refcnt) > 0: if refcnt.isdigit() and int(refcnt) > 0:
return {'i915':'intel'}.get(drv,drv) return {'i915': 'intel'}.get(drv, drv)
else: else:
return self.default_video return self.default_video
pkgDrvMap = {'nvidia':('NVidia','x11-drivers/nvidia-drivers'), pkgDrvMap = {'nvidia': ('NVidia', 'x11-drivers/nvidia-drivers'),
'fglrx':('ATI','x11-drivers/ati-drivers'), 'fglrx': ('ATI', 'x11-drivers/ati-drivers'),
'vboxdrv':('VirtualBox','x11-drivers/xf86-video-virtualbox')} 'vboxdrv': ('VirtualBox', 'x11-drivers/xf86-video-virtualbox')}
def check(self,value): def check(self, value):
if self.Get('os_install_x11_server_set') == 'on': if self.Get('os_install_x11_server_set') == 'on':
if self.Get('cl_action') == 'system': if self.Get('cl_action') == 'system':
availDrvs = self.Get('os_install_x11_video_available') availDrvs = self.Get('os_install_x11_video_available')
if not value in availDrvs: if not value in availDrvs:
raise VariableError(_("Only %s drivers are available")% raise VariableError(_("Only %s drivers are available") %
",".join(availDrvs)) ",".join(availDrvs))
else: else:
if not value in getInstalledVideo(prefix="/") and \ if not value in getInstalledVideo(prefix="/") and \
not value in ("auto",self.default_video): not value in ("auto", self.default_video):
error =_("video driver %s is unavailable")%value error = _("video driver %s is unavailable") % value
if value in self.pkgDrvMap: if value in self.pkgDrvMap:
error += ". " + (_("Install driver %s with:") error += ". " + (_("Install driver %s with:")
%self.pkgDrvMap[value][0]) % self.pkgDrvMap[value][0])
error += "\n" + ("emerge %s"%self.pkgDrvMap[value][1]) error += "\n" + ("emerge %s" % self.pkgDrvMap[value][1])
raise VariableError(error) raise VariableError(error)
else: else:
availDrivers = self.Get('os_x11_kms_video_drv') + [self.default_video] availDrivers = self.Get('os_x11_kms_video_drv') + [
self.default_video]
if not value in availDrivers: if not value in availDrivers:
raise VariableError("Only %s drivers are available" % raise VariableError("Only %s drivers are available" %
",".join(availDrivers)) ",".join(availDrivers))
@ -231,6 +243,7 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
_("Video configuration unavailable for Flash install") _("Video configuration unavailable for Flash install")
return "" return ""
class VariableHrVideoId(ReadonlyVariable): class VariableHrVideoId(ReadonlyVariable):
""" """
BusID of video card BusID of video card
@ -238,6 +251,7 @@ class VariableHrVideoId(ReadonlyVariable):
""" """
value = "" value = ""
class VariableOsInstallX11Composite(VideoVariable): class VariableOsInstallX11Composite(VideoVariable):
""" """
on/off composite on/off composite
@ -251,15 +265,15 @@ class VariableOsInstallX11Composite(VideoVariable):
def get(self): def get(self):
"""On/off composite""" """On/off composite"""
defaultCompositeOn = ("nvidia","intel","fglrx", defaultCompositeOn = ("nvidia", "intel", "fglrx",
"nouveau","radeon", "default") "nouveau", "radeon", "default")
composite = getValueFromCmdLine("calculate",5) composite = getValueFromCmdLine("calculate", 5)
videodrv = getValueFromCmdLine("calculate",4) videodrv = getValueFromCmdLine("calculate", 4)
if videodrv != "auto": if videodrv != "auto":
composite = {'nocomposite':'off', composite = {'nocomposite': 'off',
'off':'off', 'off': 'off',
'on':'on', 'on': 'on',
'composite':'on'}.get(composite) 'composite': 'on'}.get(composite)
else: else:
composite = None composite = None
@ -275,6 +289,7 @@ class VariableOsInstallX11Composite(VideoVariable):
state = None state = None
return composite or state or defaultComposite return composite or state or defaultComposite
class VariableOsInstallFbResolution(ResolutionVariable): class VariableOsInstallFbResolution(ResolutionVariable):
""" """
Framebuffer resolution Framebuffer resolution
@ -294,10 +309,10 @@ class VariableOsInstallFbResolution(ResolutionVariable):
def get(self): def get(self):
"""Get current framebuffer resolution""" """Get current framebuffer resolution"""
try: try:
fbdev = os.open('/dev/fb0',os.O_RDONLY) fbdev = os.open('/dev/fb0', os.O_RDONLY)
data = fcntl.ioctl(fbdev, self.FBIOGET_VSCREENINFO, " "*8) data = fcntl.ioctl(fbdev, self.FBIOGET_VSCREENINFO, " " * 8)
res = struct.unpack("II",data) res = struct.unpack("II", data)
return "%sx%s"%(res[0],res[1]) return "%sx%s" % (res[0], res[1])
except (IOError,OSError): except (IOError, OSError):
pass pass
return "1024x768" return "1024x768"

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,30 +14,31 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import sys import sys
from os import path from calculate.lib.datavars import ActionVariable
from calculate.lib.datavars import (Variable,VariableError,ReadonlyVariable,
ActionVariable)
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3',sys.modules[__name__])
setLocalTranslate('cl_install3', sys.modules[__name__])
class VariableAcInstallMerge(ActionVariable): class VariableAcInstallMerge(ActionVariable):
""" """
Action variable which has value "on" Action variable which has value "on"
in ebuild phase preinst or reconfigure system in ebuild phase preinst or reconfigure system
""" """
def action(self,cl_action):
if cl_action in ("system","merge") and \ def action(self, cl_action):
self.Get('os_install_root_type') != 'flash' and \ if (cl_action in ("system", "merge") and
self.Get('os_install_pxe') == 'off' and \ self.Get('os_install_root_type') != 'flash' and
self.Get('cl_live') == 'off' or \ self.Get('os_install_pxe') == 'off' and
cl_action in ("sync","domain","undomain") \ self.Get('cl_live') == 'off' or
and self.Get('cl_merge_pkg'): cl_action in ("sync", "domain", "undomain")
and self.Get('cl_merge_pkg')):
return "on" return "on"
return "off" return "off"
class VariableAcInstallLive(ActionVariable): class VariableAcInstallLive(ActionVariable):
""" """
Action variable which has value "on" Action variable which has value "on"
@ -46,72 +47,84 @@ class VariableAcInstallLive(ActionVariable):
""" """
nonchroot = True nonchroot = True
def action(self,cl_action): def action(self, cl_action):
if cl_action in ("system","merge") and \ if (cl_action in ("system", "merge") and
self.Get('os_install_root_type') != 'flash' and \ self.Get('os_install_root_type') != 'flash' and
self.Get('os_install_pxe') == 'off' or \ self.Get('os_install_pxe') == 'off' or
cl_action in ("sync","domain","undomain") \ cl_action in ("sync", "domain", "undomain")
and self.Get('cl_merge_pkg'): and self.Get('cl_merge_pkg')):
return "on" return "on"
return "off" return "off"
class VariableAcInstallDisk(ActionVariable): class VariableAcInstallDisk(ActionVariable):
""" """
Action variable which has value "on" for installation on hdd Action variable which has value "on" for installation on hdd
""" """
def action(self,cl_action):
if cl_action == 'system' and \ def action(self, cl_action):
self.Get('os_install_root_type') != "flash" and \ if (cl_action == 'system' and
self.Get('os_install_pxe') != "on": self.Get('os_install_root_type') != "flash" and
self.Get('os_install_pxe') != "on"):
return "on" return "on"
else: else:
return "off" return "off"
class VariableAcInstallFlash(ActionVariable): class VariableAcInstallFlash(ActionVariable):
""" """
Action variable which has value "on" for USB flash Action variable which has value "on" for USB flash
""" """
def action(self,cl_action):
if cl_action == 'system' \ def action(self, cl_action):
and self.Get('os_install_root_type') == 'flash': if (cl_action == 'system' and
self.Get('os_install_root_type') == 'flash'):
return "on" return "on"
return "off" return "off"
class VariableAcInstallPxe(ActionVariable): class VariableAcInstallPxe(ActionVariable):
""" """
Action variable which has value "on" for PXE installation Action variable which has value "on" for PXE installation
""" """
def action(self,cl_action):
def action(self, cl_action):
if cl_action == 'system' and self.Get('os_install_pxe') == 'on': if cl_action == 'system' and self.Get('os_install_pxe') == 'on':
return "on" return "on"
return "off" return "off"
class VariableAcInstallConfigure(ActionVariable): class VariableAcInstallConfigure(ActionVariable):
""" """
Action variable which has value "up" for configuration Action variable which has value "up" for configuration
""" """
def action(self,cl_action):
clSetup = self.Get('cl_setup') def action(self, cl_action):
if cl_action == "merge" and clSetup: cl_setup = self.Get('cl_setup')
if cl_action == "merge" and cl_setup:
return "on" return "on"
return "off" return "off"
class VariableAcInstallUnmerge(ActionVariable): class VariableAcInstallUnmerge(ActionVariable):
""" """
Action variable which has value "up" on prerm ebuild phase Action variable which has value "up" on prerm ebuild phase
""" """
def action(self,cl_action):
if cl_action == "merge" and \ def action(self, cl_action):
self.Get('cl_ebuild_phase') in ('prerm','postrm'): if (cl_action == "merge" and
self.Get('cl_ebuild_phase') in ('prerm', 'postrm')):
return "on" return "on"
return "off" return "off"
class VariableAcInstallPatch(ActionVariable): class VariableAcInstallPatch(ActionVariable):
""" """
Action variable which has value "on" Action variable which has value "on"
in ebuild phase preinst or reconfigure system in ebuild phase preinst or reconfigure system
""" """
def action(self,cl_action):
def action(self, cl_action):
if cl_action in ("patch",): if cl_action in ("patch",):
return "on" return "on"
return "off" return "off"

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,16 +14,17 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import sys import sys
import re import re
from os import path from calculate.lib.datavars import (Variable, ReadonlyVariable,
from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable, ReadonlyTableVariable, FieldValue,
ReadonlyTableVariable, FieldValue) HumanReadable)
from calculate.lib.utils.files import (readFile, getProgPath, process) from calculate.lib.utils.files import readFile
from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_install3', sys.modules[__name__])
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3',sys.modules[__name__])
class VariableOsAudioData(ReadonlyTableVariable): class VariableOsAudioData(ReadonlyTableVariable):
""" """
@ -32,9 +33,9 @@ class VariableOsAudioData(ReadonlyTableVariable):
source = ['os_audio_id', source = ['os_audio_id',
'os_audio_name'] 'os_audio_name']
def get(self,hr=False): def get(self, hr=HumanReadable.No):
data = readFile('/proc/asound/cards') data = readFile('/proc/asound/cards')
cards = re.findall('^\s*(\d+).*\n\s+(\S.*) at .*$',data,re.M) cards = re.findall('^\s*(\d+).*\n\s+(\S.*) at .*$', data, re.M)
if cards: if cards:
return map(list, cards) return map(list, cards)
else: else:
@ -42,7 +43,8 @@ class VariableOsAudioData(ReadonlyTableVariable):
setValue = Variable.setValue setValue = Variable.setValue
class VariableOsAudioId(FieldValue,ReadonlyVariable):
class VariableOsAudioId(FieldValue, ReadonlyVariable):
""" """
Order Id of audio card Order Id of audio card
""" """
@ -50,7 +52,8 @@ class VariableOsAudioId(FieldValue,ReadonlyVariable):
source_variable = "os_audio_data" source_variable = "os_audio_data"
column = 0 column = 0
class VariableOsAudioName(FieldValue,ReadonlyVariable):
class VariableOsAudioName(FieldValue, ReadonlyVariable):
""" """
Name of audio card Name of audio card
""" """
@ -58,6 +61,7 @@ class VariableOsAudioName(FieldValue,ReadonlyVariable):
source_variable = "os_audio_data" source_variable = "os_audio_data"
column = 1 column = 1
class VariableOsAudioDefaultSet(ReadonlyVariable): class VariableOsAudioDefaultSet(ReadonlyVariable):
""" """
Force write in config 0 Force write in config 0
@ -65,34 +69,36 @@ class VariableOsAudioDefaultSet(ReadonlyVariable):
type = "bool" type = "bool"
def get(self): def get(self):
res = self.Select('os_audio_id',where='os_audio_name', res = self.Select('os_audio_id', where='os_audio_name',
notlike='HDMI',limit=1) notlike='HDMI', limit=1)
audioDefault = self.Get('os_audio_default') audio_default = self.Get('os_audio_default')
if audioDefault != '0' or \ if (audio_default != '0' or
res and res != "0" and audioDefault == '0' or \ res and res != "0" and audio_default == '0' or
audioDefault != self.Get('os_audio_current'): audio_default != self.Get('os_audio_current')):
return 'on' return 'on'
return 'off' return 'off'
class VariableOsAudioCurrent(ReadonlyVariable): class VariableOsAudioCurrent(ReadonlyVariable):
""" """
Current default audio card Current default audio card
""" """
def get(self): def get(self):
defaultCardRe = re.compile('defaults.ctl.card\s+(\d+)') default_card_re = re.compile('defaults.ctl.card\s+(\d+)')
entry = defaultCardRe.search(readFile('/etc/asound.conf')) entry = default_card_re.search(readFile('/etc/asound.conf'))
if entry and entry.groups()[0] in self.Get('os_audio_id'): if entry and entry.groups()[0] in self.Get('os_audio_id'):
return entry.groups()[0] return entry.groups()[0]
res = self.Select('os_audio_id',where='os_audio_name', res = self.Select('os_audio_id', where='os_audio_name',
notlike='HDMI',limit=1) notlike='HDMI', limit=1)
return res or '0' return res or '0'
class VariableOsAudioDefault(Variable): class VariableOsAudioDefault(Variable):
""" """
Current default audio card Current default audio card
""" """
type = "choice" type = "choice"
opt = ['--audio'] opt = ['--audio']
def init(self): def init(self):

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,4 +1,4 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org
# #
@ -20,26 +20,28 @@ from os import path
import re import re
import operator import operator
from operator import itemgetter from operator import itemgetter
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable, \ from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
CommonVariableError CommonVariableError)
from calculate.lib.utils.common import getSupportArch,getTupleVersion, \ from calculate.lib.utils.common import (getSupportArch, getTupleVersion,
cmpVersion cmpVersion)
from calculate.lib.utils.files import readLinesFile, listDirectory, pathJoin from calculate.lib.utils.files import listDirectory, pathJoin
from calculate.lib.variables.linux import Linux from calculate.lib.variables.linux import Linux
from calculate.install.distr import (Distributive,PartitionDistributive, from calculate.install.distr import (Distributive, PartitionDistributive,
DirectoryDistributive, DefaultMountPath, DirectoryDistributive, DefaultMountPath,
ScratchPartitionDistributive,DistributiveError,FlashDistributive, DistributiveError, FlashDistributive,
MultiPartitions,PxeDistributive) MultiPartitions, PxeDistributive)
from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_install3', sys.modules[__name__])
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3',sys.modules[__name__])
class DistroRepository(Linux): class DistroRepository(Linux):
contentCache = {} contentCache = {}
marches = ['i686','x86_64'] marches = ['i686', 'x86_64']
extensiton = ['iso','tar.bz2','tar.gz','tar.7z','tar.lzma'] extensiton = ['iso', 'tar.bz2', 'tar.gz', 'tar.7z', 'tar.lzma']
reDistName = re.compile(""" reDistName = re.compile("""
^.*/(?P<os_linux_shortname>%(name)s) ^.*/(?P<os_linux_shortname>%(name)s)
@ -47,14 +49,14 @@ class DistroRepository(Linux):
(?:-(?P<serial_id>%(ser)s))? (?:-(?P<serial_id>%(ser)s))?
-(?P<os_arch_machine>%(march)s) -(?P<os_arch_machine>%(march)s)
.(?P<ext>%(ext)s)$""" % .(?P<ext>%(ext)s)$""" %
{'name':"[a-z0-9]+", {'name': "[a-z0-9]+",
'ver':r"(\d+\.)*\d+", 'ver': r"(\d+\.)*\d+",
'ser':r"\d+", 'ser': r"\d+",
'march':"|".join(marches), 'march': "|".join(marches),
'ext':"|".join(extensiton) 'ext': "|".join(extensiton)
}, re.X) }, re.X)
def _getDistrInfo(self,filename): def _getDistrInfo(self, filename):
"""Get information by distributive""" """Get information by distributive"""
# if filename is directory # if filename is directory
if not path.isfile(filename): if not path.isfile(filename):
@ -71,8 +73,8 @@ class DistroRepository(Linux):
distdic["os_linux_ver"] = "" distdic["os_linux_ver"] = ""
return distdic return distdic
def getImage(self,scratch,rootType,imagePath,march=None, def getImage(self, scratch, rootType, imagePath, march=None,
shortName=None,linuxVer=None,linuxBuild=None): shortName=None, linuxVer=None, linuxBuild=None):
"""Get image by parameters""" """Get image by parameters"""
# exclude directory distributive for flash and scratch install # exclude directory distributive for flash and scratch install
if scratch == "on" or rootType == "flash": if scratch == "on" or rootType == "flash":
@ -86,40 +88,44 @@ class DistroRepository(Linux):
version=linuxVer, version=linuxVer,
build=linuxBuild) build=linuxBuild)
def _getAvailableShortnames(self,dirs): def _getAvailableShortnames(self, dirs):
"""Get available distributives shortnames""" """Get available distributives shortnames"""
distros = filter(lambda x:x, distros = filter(lambda x: x,
map(self.reDistName.search,self._getAvailableDistributives(dirs))) map(self.reDistName.search,
return sorted(list(set(map(lambda x:x.groupdict()['name'],distros)))) self._getAvailableDistributives(dirs)))
return sorted(list(set(map(lambda x: x.groupdict()['name'], distros))))
def opcompareByString(self,buf): def opcompareByString(self, buf):
if buf: if buf:
reOp = re.compile("^(!=|=|==|<=|>=|>|<)?(\d+.*)$") reOp = re.compile("^(!=|=|==|<=|>=|>|<)?(\d+.*)$")
res = reOp.search(buf) res = reOp.search(buf)
if res: if res:
return ({'!=':operator.ne, return ({'!=': operator.ne,
'=':operator.eq, '=': operator.eq,
'==':operator.eq, '==': operator.eq,
'>=':operator.ge, '>=': operator.ge,
'<=':operator.le, '<=': operator.le,
'<':operator.lt, '<': operator.lt,
'>':operator.gt}.get(res.group(1),operator.eq), '>': operator.gt}.get(res.group(1), operator.eq),
res.group(2)) res.group(2))
else: else:
return operator.eq,buf return operator.eq, buf
return None,None return None, None
def _getAvailableDistributives(self,dirs,system=None,shortname=None, def _getAvailableDistributives(self, dirs, system=None, shortname=None,
march=None,version=None,build=None): march=None, version=None, build=None):
"""Get all distributives by filter""" """Get all distributives by filter"""
def systemByName(name): def systemByName(name):
return self.dictNameSystem.get(name.upper(),"") return self.dictNameSystem.get(name.upper(), "")
verCmp, version = self.opcompareByString(version) verCmp, version = self.opcompareByString(version)
if version: if version:
version = getTupleVersion(version) version = getTupleVersion(version)
buildCmp, build = self.opcompareByString(build) buildCmp, build = self.opcompareByString(build)
if build and build.isdigit(): if build and build.isdigit():
build = int(build) build = int(build)
def distfilter(dist): def distfilter(dist):
d = self._getDistrInfo(dist) d = self._getDistrInfo(dist)
if not d: if not d:
@ -127,123 +133,127 @@ class DistroRepository(Linux):
# check filter conditions # check filter conditions
if system and systemByName(d['os_linux_shortname']) != system: if system and systemByName(d['os_linux_shortname']) != system:
return False return False
if not "os_linux_shortname" in d or not "os_linux_ver" in d: if "os_linux_shortname" not in d or "os_linux_ver" not in d:
return False return False
if shortname and \ if (shortname and
d['os_linux_shortname'].lower() != shortname.lower(): d['os_linux_shortname'].lower() != shortname.lower()):
return False return False
if march and d['os_arch_machine'] != march: if march and d['os_arch_machine'] != march:
return False return False
if version and \ if version and \
not verCmp(getTupleVersion(d['os_linux_ver']), version): not verCmp(getTupleVersion(d['os_linux_ver']), version):
return False return False
if build and "os_linux_build" in d and \ if build and "os_linux_build" in d and \
(not d['os_linux_build'].isdigit() or (not d['os_linux_build'].isdigit() or
not buildCmp(int(d['os_linux_build']),build)): not buildCmp(int(d['os_linux_build']), build)):
return False return False
return True return True
def listdistr(pathname): def listdistr(pathname):
if path.exists(path.join(pathname,'etc/make.profile')) or \ if path.exists(path.join(pathname, 'etc/make.profile')) or \
path.exists(path.join(pathname,'etc/portage/make.profile')) or \ path.exists(
path.exists(path.join(pathname,'livecd')) or \ path.join(pathname, 'etc/portage/make.profile')) or \
pathname.startswith('/dev/'): path.exists(path.join(pathname, 'livecd')) or \
pathname.startswith('/dev/'):
return [pathname] return [pathname]
else: else:
# discard inner directories # discard inner directories
return filter(lambda x:not path.isdir( path.join(pathname,x)), return filter(lambda x: not path.isdir(path.join(pathname, x)),
listDirectory(pathname)) listDirectory(pathname))
# get lists files in directories # get lists files in directories
allFiles = map(lambda x: map(lambda y: path.join(x,y), allFiles = map(lambda x: map(lambda y: path.join(x, y),
listdistr(x)), listdistr(x)),
dirs) dirs)
# filter distributives # filter distributives
return filter(distfilter, return filter(distfilter,
# join files lists to one list # join files lists to one list
reduce(lambda x,y: x + y, reduce(lambda x, y: x + y,
allFiles, [])) allFiles, []))
def extcomparator(self,*exts): def extcomparator(self, *exts):
"""Compare extensions""" """Compare extensions"""
mapExts = {'iso':0, mapExts = {'iso': 0,
'flash':-1, 'flash': -1,
'isodir':-2, 'isodir': -2,
'partdir':-3, 'partdir': -3,
'dir':-4} 'dir': -4}
return cmp(mapExts.get(exts[0],-4),mapExts.get(exts[1],-4)) return cmp(mapExts.get(exts[0], -4), mapExts.get(exts[1], -4))
def sortdistrfunc(self,x,y): def sortdistrfunc(self, x, y):
"""Func of comparing two distributive""" """Func of comparing two distributive"""
ver1, ver2 = x[1].get('os_linux_ver',""), y[1].get('os_linux_ver',"") 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: if ver1 and ver2 and ver1 != "0" and ver2 != "0" and ver1 != ver2:
return cmpVersion(ver1,ver2) return cmpVersion(ver1, ver2)
build1 = getTupleVersion(x[1].get('os_linux_build',"")) build1 = getTupleVersion(x[1].get('os_linux_build', ""))
build2 = getTupleVersion(y[1].get('os_linux_build',"")) build2 = getTupleVersion(y[1].get('os_linux_build', ""))
if build1 != build2: if build1 != build2:
return cmp(build1,build2) return cmp(build1, build2)
else: else:
ser1, ser2 = (x[1].get('serial_id') or "0", ser1, ser2 = (x[1].get('serial_id') or "0",
y[1].get('serial_id') or "0") y[1].get('serial_id') or "0")
if ser1 != ser2: if ser1 != ser2:
return cmp(int(ser1), int(ser2)) return cmp(int(ser1), int(ser2))
ext1 = x[1].get('ext',"") ext1 = x[1].get('ext', "")
ext2 = y[1].get('ext',"") ext2 = y[1].get('ext', "")
return self.extcomparator(ext1,ext2) return self.extcomparator(ext1, ext2)
def getAvailableDristibutives(self,dirs,system=None,shortname=None, def getAvailableDristibutives(self, dirs, system=None, shortname=None,
march=None, version=None, build=None,discardType=[]): march=None, version=None, build=None,
discardType=()):
"""Get list available distributives""" """Get list available distributives"""
if shortname: if shortname:
shortname = shortname.lower() shortname = shortname.lower()
availDistrs = self._getAvailableDistributives(dirs,system,shortname, availDistrs = self._getAvailableDistributives(dirs, system, shortname,
march,version, march, version,
build) build)
availDistrs = filter(lambda x:x[1] and "ext" in x[1] and availDistrs = filter(lambda x: x[1] and "ext" in x[1] and
not x[1]["ext"] in discardType, not x[1]["ext"] in discardType,
map(lambda x:(x,self._getDistrInfo(x)), map(lambda x: (x, self._getDistrInfo(x)),
availDistrs)) availDistrs))
return map(lambda x:x[0], return map(lambda x: x[0],
sorted(availDistrs,self.sortdistrfunc,reverse=True)) sorted(availDistrs, self.sortdistrfunc, reverse=True))
def getBestDistributive(self,dirs,system=None,shortname=None,march=None, def getBestDistributive(self, dirs, system=None, shortname=None, march=None,
version=None, build=None,discardType=[]): version=None, build=None, discardType=()):
"""Get the actualest distributive""" """Get the actualest distributive"""
availDistrs = self.getAvailableDristibutives(dirs,system,shortname, availDistrs = self.getAvailableDristibutives(dirs, system, shortname,
march,version,build,discardType) march, version, build,
discardType)
if availDistrs: if availDistrs:
return availDistrs[0] return availDistrs[0]
else: else:
return None return None
def _findLatestFile(self,dirs,reMatch,keyfunc): def _findLatestFile(self, dirs, reMatch, keyfunc):
"""Find latest file in dirs, which match by reMatch, """Find latest file in dirs, which match by reMatch,
comparable part get by keyfunc""" comparable part get by keyfunc"""
existsdirs = filter(path.exists,dirs) existsdirs = filter(path.exists, dirs)
listimgs = reduce(lambda x,y:x + \ listimgs = reduce(lambda x, y: x + map(
map(lambda x:reMatch.search(path.join(y,x)), lambda x: reMatch.search(
listDirectory(y)), path.join(y, x)),
existsdirs,[]) listDirectory(y)),
listimgs = filter(lambda x:x, listimgs) existsdirs, [])
listimgs = filter(lambda x: x, listimgs)
if listimgs: if listimgs:
return max(listimgs,key=keyfunc).group() return max(listimgs, key=keyfunc).group()
return "" return ""
def getBestStage(self,dirs,march=None,hardened=None): def getBestStage(self, dirs, march=None, hardened=None):
"""Get latest stage by march""" """Get latest stage by march"""
if march: if march:
march = {'x86_64':'amd64'}.get(march,march) march = {'x86_64': 'amd64'}.get(march, march)
else: else:
march = "[^-]+" march = "[^-]+"
if hardened is None: if hardened is None:
hardened = "(?:-hardened)?" hardened = "(?:-hardened)?"
elif hardened == True: elif hardened is True:
hardened = "-hardened" hardened = "-hardened"
elif hardened == False: elif hardened is False:
hardened = "" hardened = ""
reStage = re.compile(r'^.*/stage3-%s%s-(\d+)\.tar\.bz2$'% reStage = re.compile(r'^.*/stage3-%s%s-(\d+)\.tar\.bz2$' %
(march,hardened),re.S) (march, hardened), re.S)
return self._findLatestFile(dirs,reStage,lambda x:x.groups()[0]) return self._findLatestFile(dirs, reStage, lambda x: x.groups()[0])
class VariableClImage(ReadonlyVariable): class VariableClImage(ReadonlyVariable):
@ -271,7 +281,8 @@ class VariableClImage(ReadonlyVariable):
return filename.getType() return filename.getType()
return filename return filename
class VariableClImageFilename(Variable,DistroRepository):
class VariableClImageFilename(DistroRepository, Variable):
""" """
Distributive image filename Distributive image filename
""" """
@ -291,44 +302,45 @@ class VariableClImageFilename(Variable,DistroRepository):
return "" return ""
arch = self.Get('cl_image_arch_machine') or self.Get('os_arch_machine') arch = self.Get('cl_image_arch_machine') or self.Get('os_arch_machine')
shortname = self.Get('cl_image_linux_shortname') or \ shortname = self.Get('cl_image_linux_shortname') or \
self.Get('os_linux_shortname') self.Get('os_linux_shortname')
ver = self.Get('cl_image_linux_ver') or None ver = self.Get('cl_image_linux_ver') or None
build = self.Get('cl_image_linux_build') or None build = self.Get('cl_image_linux_build') or None
return self.getImage(self.Get('os_install_scratch'), return self.getImage(self.Get('os_install_scratch'),
self.Get('os_install_root_type'), self.Get('os_install_root_type'),
self.Get('cl_image_path'), self.Get('cl_image_path'),
arch,shortname,ver,build) or "" arch, shortname, ver, build) or ""
def check(self,isoimage): def check(self, isoimage):
"""Set image file""" """Set image file"""
if self.Get('cl_action') == 'system' and not isoimage: if self.Get('cl_action') == 'system' and not isoimage:
raise VariableError(_("You need to select a distribution image")) raise VariableError(_("You need to select a distribution image"))
imageData = Distributive().getInfo(isoimage) imageData = Distributive().getInfo(isoimage)
if not("os_linux_shortname" in imageData and \ if not ("os_linux_shortname" in imageData and
imageData.get('os_linux_build','') and \ imageData.get('os_linux_build', '') and
"os_arch_machine" in imageData): "os_arch_machine" in imageData):
raise VariableError(_("Wrong image file")) raise VariableError(_("Wrong image file"))
def humanImageName(self,distroinfo,filepath): def humanImageName(self, distroinfo, filepath):
if all(x in distroinfo for x in ("os_linux_shortname", if all(x in distroinfo for x in ("os_linux_shortname",
"os_arch_machine", "os_arch_machine",
"os_linux_build")): "os_linux_build")):
distroinfo['os_linux_shortname'] = \ distroinfo['os_linux_shortname'] = \
distroinfo['os_linux_shortname'].upper() distroinfo['os_linux_shortname'].upper()
fullname = distroinfo.get('os_linux_name', fullname = distroinfo.get('os_linux_name',
Linux.dictLinuxName.get( Linux.dictLinuxName.get(
distroinfo['os_linux_shortname'],"Calculate")) distroinfo['os_linux_shortname'],
"Calculate"))
subname = distroinfo.get('os_linux_subname', subname = distroinfo.get('os_linux_subname',
Linux.dictLinuxSubName.get( Linux.dictLinuxSubName.get(
distroinfo['os_linux_shortname'],"")) distroinfo['os_linux_shortname'], ""))
if subname: if subname:
subname=" %s"%subname subname = " %s" % subname
build = distroinfo['os_linux_build'] or \ build = distroinfo['os_linux_build'] or \
distroinfo.get('os_linux_ver','') distroinfo.get('os_linux_ver', '')
ver = distroinfo.get('os_linux_ver','') ver = distroinfo.get('os_linux_ver', '')
return "{fullname} {os_arch_machine} {build}".format( return "{fullname} {os_arch_machine} {build}".format(
fullname="%s%s"%(fullname,subname),filepath=filepath, fullname="%s%s" % (fullname, subname), filepath=filepath,
build=build,ver=ver,**distroinfo) build=build, ver=ver, **distroinfo)
else: else:
return filepath return filepath
@ -336,34 +348,34 @@ class VariableClImageFilename(Variable,DistroRepository):
fullname = self.Get('os_install_linux_name') fullname = self.Get('os_install_linux_name')
subname = self.Get('os_install_linux_subname') subname = self.Get('os_install_linux_subname')
if subname: if subname:
subname = " %s"%subname subname = " %s" % subname
arch = self.Get('os_install_arch_machine') arch = self.Get('os_install_arch_machine')
build = self.Get('os_install_linux_build') build = self.Get('os_install_linux_build')
ver = self.Get('os_install_linux_ver') ver = self.Get('os_install_linux_ver')
return "{fullname} {ver} {arch} {build}".format( return "{fullname} {ver} {arch} {build}".format(
fullname="%s%s"%(fullname,subname), fullname="%s%s" % (fullname, subname),
build=build,ver=ver,arch=arch) build=build, ver=ver, arch=arch)
def choice(self): def choice(self):
scratch = self.Get('os_install_scratch') scratch = self.Get('os_install_scratch')
rootType = self.Get('os_install_root_type') rootType = self.Get('os_install_root_type')
imagePath = self.Get('cl_image_path') imagePath = self.Get('cl_image_path')
if scratch == "on" or rootType == "flash" or \ if scratch == "on" or rootType == "flash" or \
self.Get('cl_install_type') == 'flash': self.Get('cl_install_type') == 'flash':
discardType = ["dir"] discardType = ["dir"]
else: else:
discardType = [] discardType = []
distros = self.getAvailableDristibutives(imagePath, distros = self.getAvailableDristibutives(imagePath,
discardType=discardType) discardType=discardType)
if self.wasSet and not self.value in distros: if self.wasSet and not self.value in distros:
distros.append(self.value) distros.append(self.value)
return sorted(map(lambda x: ( return sorted(map(lambda x: (
x, self.humanImageName(self._getDistrInfo(x), x)), distros), x, self.humanImageName(self._getDistrInfo(x), x)), distros),
key=itemgetter(1)) key=itemgetter(1))
class VariableClImageArchMachine(Variable,DistroRepository): class VariableClImageArchMachine(DistroRepository, Variable):
""" """
Filter by architecture Filter by architecture
""" """
@ -371,73 +383,77 @@ class VariableClImageArchMachine(Variable,DistroRepository):
type = 'choice' type = 'choice'
opt = ['--march'] opt = ['--march']
metavalue = "ARCH" metavalue = "ARCH"
available_arch = ["i686","x86_64"] available_arch = ["i686", "x86_64"]
def init(self): def init(self):
self.label = "%s %s"%(_("Filter"),_("by processor architecture")) self.label = "%s %s" % (_("Filter"), _("by processor architecture"))
self.help = _("select the processor architecture") self.help = _("select the processor architecture")
def set(self,march): def set(self, march):
if march == "auto": if march == "auto":
march = getSupportArch()[-1] march = getSupportArch()[-1]
return march return march
def choice(self): def choice(self):
return [("",_("Not used"))]+\ return [("", _("Not used"))] + \
[("auto",_("Auto"))] + \ [("auto", _("Auto"))] + \
[(x,x) for x in self.available_arch] [(x, x) for x in self.available_arch]
def humanReadable(self): def humanReadable(self):
return self.Get() or _("Not used") return self.Get() or _("Not used")
class VariableClImageLinuxShortname(Variable,Linux,DistroRepository):
class VariableClImageLinuxShortname(DistroRepository, Variable):
""" """
Filter by shortname Filter by shortname
""" """
value = "" value = ""
type = 'choiceedit' type = 'choiceedit'
metavalue = "SYSTEM" metavalue = "SYSTEM"
opt = ['--os','-s'] opt = ['--os', '-s']
def init(self): def init(self):
self.label = "%s %s"%(_("Filter"),_("by distribution")) self.label = "%s %s" % (_("Filter"), _("by distribution"))
self.help = _("select the operation system") self.help = _("select the operation system")
def choice(self): def choice(self):
return [("",_("Not used"))]+\ return [("", _("Not used"))] + \
sorted(map(lambda x:(x,self.getFullNameByShort(x)), sorted(map(lambda x: (x, self.getFullNameByShort(x)),
self.dictLinuxName.keys()), self.dictLinuxName.keys()),
key=itemgetter(1)) key=itemgetter(1))
def humanReadable(self): def humanReadable(self):
return self.Get() or _("Not used") return self.Get() or _("Not used")
class VariableClImageLinuxVer(Variable,DistroRepository):
class VariableClImageLinuxVer(DistroRepository, Variable):
""" """
Filter by version Filter by version
""" """
value = "" value = ""
def init(self): def init(self):
self.label = "%s %s"%(_("Filter"),_("by version")) self.label = "%s %s" % (_("Filter"), _("by version"))
self.help = _("select the operation system by version") self.help = _("select the operation system by version")
def humanReadable(self): def humanReadable(self):
return self.Get() or _("Not used") return self.Get() or _("Not used")
class VariableClImageLinuxBuild(Variable,DistroRepository):
class VariableClImageLinuxBuild(DistroRepository, Variable):
""" """
Filter by build Filter by build
""" """
value = "" value = ""
def init(self): def init(self):
self.label = "%s %s"%(_("Filter"),_("by build")) self.label = "%s %s" % (_("Filter"), _("by build"))
self.help = _("select the operation system by build") self.help = _("select the operation system by build")
def humanReadable(self): def humanReadable(self):
return self.Get() or _("Not used") return self.Get() or _("Not used")
class VariableClImagePath(ReadonlyVariable): class VariableClImagePath(ReadonlyVariable):
""" """
Image search path Image search path
@ -466,20 +482,20 @@ class VariableClImagePath(ReadonlyVariable):
'/run/initramfs/live', '/run/initramfs/live',
'/mnt/cdrom'] '/mnt/cdrom']
livedistr = filter(listDirectory, livedistr = filter(listDirectory,
livedistr)[:1] livedistr)[:1]
else: else:
livedistr = [] livedistr = []
# search all partition for source installation distributive # search all partition for source installation distributive
rootDev = self.Get('os_install_root_dev') rootDev = self.Get('os_install_root_dev')
livedistr += \ livedistr += \
map(lambda x:x[0], map(lambda x: x[0],
filter(lambda x:" live" in x[1] and x[0] != rootDev, filter(lambda x: " live" in x[1] and x[0] != rootDev,
zip(self.Get('os_disk_dev'), zip(self.Get('os_disk_dev'),
self.Get('os_disk_content')))) self.Get('os_disk_content'))))
# add to standard path # add to standard path
return filter(path.exists, return filter(path.exists,
['/var/calculate/remote/linux', ['/var/calculate/remote/linux',
'/var/calculate/linux'] + livedistr) '/var/calculate/linux'] + livedistr)
class VariableClSource(ReadonlyVariable): class VariableClSource(ReadonlyVariable):
@ -491,6 +507,7 @@ class VariableClSource(ReadonlyVariable):
def get(self): def get(self):
return DirectoryDistributive('/') return DirectoryDistributive('/')
class VariableClTarget(ReadonlyVariable): class VariableClTarget(ReadonlyVariable):
""" """
Target distributive Target distributive
@ -506,23 +523,18 @@ class VariableClTarget(ReadonlyVariable):
ver=self.Get('os_install_linux_ver')) ver=self.Get('os_install_linux_ver'))
osInstallScratch = self.isTrue(self.Get('os_install_scratch')) osInstallScratch = self.isTrue(self.Get('os_install_scratch'))
mapDevId = dict(self.ZipVars('os_disk_dev','os_disk_id')) mapDevId = dict(self.ZipVars('os_disk_dev', 'os_disk_id'))
disk, mount, fileSystem, isFormat, partTable,systemId = \ disk, mount, fileSystem, isFormat, partTable, systemId = \
self.Select(listVars, self.Select(listVars,
where='os_install_disk_mount', where='os_install_disk_mount',
eq='/',limit=1) eq='/', limit=1)
if not systemId or mapDevId.get(disk,'') == systemId: if not systemId or mapDevId.get(disk, '') == systemId:
systemId = None systemId = None
if osInstallScratch: if osInstallScratch:
target = ScratchPartitionDistributive( raise VariableError("Scratch is not supported")
disk, mdirectory=DefaultMountPath.InstallMount, if self.Get('os_install_pxe') == "on":
check=True, fileSystem=fileSystem,
isFormat=self.isTrue(isFormat),
systemId=systemId,
partitionTable=partTable)
elif self.Get('os_install_pxe') == "on":
return PxeDistributive(self.Get('os_install_pxe_path')) return PxeDistributive(self.Get('os_install_pxe_path'))
elif self.Get('os_install_root_type')=="flash": elif self.Get('os_install_root_type') == "flash":
flashLabel = "{short}-{build}".format( flashLabel = "{short}-{build}".format(
short="CL", build=self.Get('os_install_linux_build')) short="CL", build=self.Get('os_install_linux_build'))
return FlashDistributive( return FlashDistributive(
@ -545,41 +557,42 @@ class VariableClTarget(ReadonlyVariable):
ne='/') ne='/')
bindData = self.Select(['os_install_bind_path', bindData = self.Select(['os_install_bind_path',
'os_install_bind_mountpoint'], 'os_install_bind_mountpoint'],
where='os_install_bind_mountpoint', where='os_install_bind_mountpoint',
ne='') ne='')
if diskData or bindData: if diskData or bindData:
multiPartition = MultiPartitions() multiPartition = MultiPartitions()
target.multipartition = multiPartition target.multipartition = multiPartition
for disk,mount,fileSystem,isFormat,partTable,systemId in diskData: for disk, mount, fileSystem, isFormat, partTable, systemId in diskData:
if not systemId or mapDevId.get(disk,'') == systemId: if not systemId or mapDevId.get(disk, '') == systemId:
systemId = None systemId = None
multiPartition.addPartition(dev=disk, multiPartition.addPartition(dev=disk,
mountPoint=mount, mountPoint=mount,
fileSystem=fileSystem, fileSystem=fileSystem,
isFormat=self.isTrue(isFormat), isFormat=self.isTrue(isFormat),
systemId=systemId, systemId=systemId,
partitionTable=partTable) partitionTable=partTable)
for source,dest in bindData: for source, dest in bindData:
multiPartition.addPartition(dev=source, multiPartition.addPartition(dev=source,
mountPoint=dest, mountPoint=dest,
fileSystem='bind', fileSystem='bind',
isFormat=False, isFormat=False,
systemId=None, systemId=None,
partitionTable='') partitionTable='')
return target return target
class VariableClImageNewOnly(Variable): class VariableClImageNewOnly(Variable):
""" """
Distributive image filename Distributive image filename
""" """
type = 'bool' type = 'bool'
opt = ['-U','--update'] opt = ['-U', '--update']
value = "off" value = "off"
def init(self): def init(self):
self.label = _("Install the newer image only") self.label = _("Install the newer image only")
self.help = _("install the newer image only") self.help = _("install the newer image only")
def installedBuild(self): def installedBuild(self):
""" """
Get build already installed system Get build already installed system
@ -590,20 +603,22 @@ class VariableClImageNewOnly(Variable):
return "" return ""
try: try:
imageData = Distributive().getInfo(rootDev) imageData = Distributive().getInfo(rootDev)
return imageData.get('os_linux_build','') return imageData.get('os_linux_build', '')
except: except Exception:
pass pass
return "" return ""
def check(self,value): def check(self, value):
if value == 'on': if value == 'on':
try: try:
imageData = Distributive().getInfo(self.Get('cl_image_filename')) imageData = Distributive().getInfo(
self.Get('cl_image_filename'))
except Exception as e: except Exception as e:
raise VariableError(_("Wrong image file")) raise VariableError(_("Wrong image file"))
if imageData.get('os_linux_build','') <= \ if imageData.get('os_linux_build', '') <= \
self.Get('os_linux_build') or \ self.Get('os_linux_build') or \
imageData.get('os_linux_build','') <= self.installedBuild(): imageData.get('os_linux_build',
'') <= self.installedBuild():
raise CommonVariableError(_("The image for update not found")) raise CommonVariableError(_("The image for update not found"))
@ -611,6 +626,7 @@ class VariableClInstallPathFrom(ReadonlyVariable):
""" """
Путь из устанавливаемой системы до устанавливающий системы Путь из устанавливаемой системы до устанавливающий системы
""" """
def get(self): def get(self):
template_path = pathJoin(self.Get('cl_chroot_path'), template_path = pathJoin(self.Get('cl_chroot_path'),
self.Get('cl_root_path')) self.Get('cl_root_path'))

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -18,23 +18,26 @@ import os
import sys import sys
import re import re
from os import path from os import path
from calculate.lib.datavars import (Variable,VariableError,ReadonlyVariable, from calculate.lib.datavars import (Variable, ReadonlyVariable,
ReadonlyTableVariable, FieldValue) ReadonlyTableVariable, FieldValue,
HumanReadable, VariableInterface)
from calculate.lib.utils.files import (readFile, from calculate.lib.utils.files import (readFile,
typeFile,process,listDirectory,MAGIC_SYMLINK,MAGIC_COMPRESS) typeFile, process, listDirectory,
MAGIC_SYMLINK, MAGIC_COMPRESS)
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3',sys.modules[__name__])
_ = lambda x: x
setLocalTranslate('cl_install3', sys.modules[__name__])
from operator import itemgetter from operator import itemgetter
from calculate.lib.utils.files import readLinesFile,pathJoin from calculate.lib.utils.files import readLinesFile
from calculate.lib.utils.common import (getKernelUid,getTupleVersion, from calculate.lib.utils.common import (getKernelUid, getTupleVersion,
getValueFromCmdLine) getValueFromCmdLine)
from calculate.lib.utils.device import getUdevDeviceInfo
from itertools import * from itertools import *
from contextlib import contextmanager
from calculate.install.distr import DistributiveError from calculate.install.distr import DistributiveError
class VariableOsInstallKernelScheduler(Variable): class VariableOsInstallKernelScheduler(Variable):
""" """
Install scheduler opts (cfq,bfq,none,deadline) Install scheduler opts (cfq,bfq,none,deadline)
@ -49,20 +52,20 @@ class VariableOsInstallKernelScheduler(Variable):
def check_scheduler(self, scheduler): def check_scheduler(self, scheduler):
return scheduler in self.Select('os_install_kernel_schedule_name', return scheduler in self.Select('os_install_kernel_schedule_name',
where='os_install_kernel_schedule_set', where='os_install_kernel_schedule_set',
eq='on') eq='on')
def get_default(self): def get_default(self):
root_dev = self.Select('os_install_disk_parent', root_dev = self.Select('os_install_disk_parent',
where='os_install_disk_mount', where='os_install_disk_mount',
eq='/',limit=1) eq='/', limit=1)
if root_dev: if root_dev:
dev_ssd, dev_virtual = self.Select(['os_device_ssd_set', dev_ssd, dev_virtual = self.Select(['os_device_ssd_set',
'os_device_virtual_set'], 'os_device_virtual_set'],
where='os_device_dev', where='os_device_dev',
eq=root_dev,limit=1) eq=root_dev, limit=1)
if ((dev_ssd == 'on' or dev_virtual == 'on') if ((dev_ssd == 'on' or dev_virtual == 'on') and
and self.check_scheduler("noop")): self.check_scheduler("noop")):
return "noop" return "noop"
return self.Get('os_install_kernel_schedule_default') return self.Get('os_install_kernel_schedule_default')
@ -71,20 +74,20 @@ class VariableOsInstallKernelScheduler(Variable):
if self.Get('os_root_type') == 'livecd': if self.Get('os_root_type') == 'livecd':
return self.get_default() return self.get_default()
else: else:
currentScheduler = getValueFromCmdLine('elevator',0) currentScheduler = getValueFromCmdLine('elevator', 0)
if currentScheduler in map(lambda x:x[0],self.choice()): if currentScheduler in map(lambda x: x[0], self.choice()):
return currentScheduler return currentScheduler
return self.Get('os_install_kernel_schedule_default') return self.Get('os_install_kernel_schedule_default')
def choice(self): def choice(self):
schedulers = {"deadline": "Deadline", schedulers = {"deadline": "Deadline",
"cfq": "CFQ", "cfq": "CFQ",
"noop": "No-op", "noop": "No-op",
"bfq": "BFQ"} "bfq": "BFQ"}
return [(x, schedulers.get(x,x)) return [(x, schedulers.get(x, x))
for x in self.Select('os_install_kernel_schedule_name', for x in self.Select('os_install_kernel_schedule_name',
where='os_install_kernel_schedule_set', where='os_install_kernel_schedule_set',
eq='on')] + [("auto",_("Default"))] eq='on')] + [("auto", _("Default"))]
def set(self, value): def set(self, value):
if value == "auto": if value == "auto":
@ -108,7 +111,7 @@ class KernelConfig:
return iter(self.data) return iter(self.data)
def __str__(self): def __str__(self):
return "kernel config (%s)"%self.config return "kernel config (%s)" % self.config
def __contains__(self, item): def __contains__(self, item):
if "=" in item: if "=" in item:
@ -121,11 +124,11 @@ class KernelConfig:
return any(key in x for x in self) return any(key in x for x in self)
class VariableOsInstallKernelConfig(ReadonlyVariable): class VariableOsInstallKernelConfig(ReadonlyVariable):
""" """
Install config kernel filename Install config kernel filename
""" """
def get_kernel_src(self, distr_path): def get_kernel_src(self, distr_path):
""" """
Get version of kernel from .config Get version of kernel from .config
@ -135,9 +138,9 @@ class VariableOsInstallKernelConfig(ReadonlyVariable):
# get version from Makefile # get version from Makefile
re_makefile = re.compile("^VERSION = (\S+)\n" re_makefile = re.compile("^VERSION = (\S+)\n"
"PATCHLEVEL = (\S+)\n" "PATCHLEVEL = (\S+)\n"
"SUBLEVEL = (\S+)\n" "SUBLEVEL = (\S+)\n"
"EXTRAVERSION = (\S*)\n", re.M) "EXTRAVERSION = (\S*)\n", re.M)
if path.exists(makefile_path): if path.exists(makefile_path):
with open(makefile_path) as f: with open(makefile_path) as f:
match = re_makefile.search(f.read(200)) match = re_makefile.search(f.read(200))
@ -148,23 +151,23 @@ class VariableOsInstallKernelConfig(ReadonlyVariable):
def configs(self, distr_path): def configs(self, distr_path):
src_kernel_ver = self.get_kernel_src(distr_path) src_kernel_ver = self.get_kernel_src(distr_path)
if src_kernel_ver: if src_kernel_ver:
yield path.join("boot", "config-%s"%src_kernel_ver) yield path.join("boot", "config-%s" % src_kernel_ver)
if self.Get('cl_chroot_path') == '/': if self.Get('cl_chroot_path') == '/':
ver = process('/bin/uname','-r').read().strip() ver = process('/bin/uname', '-r').read().strip()
yield path.join("boot", "config-%s"%ver) yield path.join("boot", "config-%s" % ver)
yield 'usr/src/linux/.config' yield 'usr/src/linux/.config'
def get(self): def get(self):
image = self.Get('cl_image') image = self.Get('cl_image')
if image: if image:
with image as distr: with image:
try: try:
distrPath = image.getDirectory() distrPath = image.getDirectory()
for config in self.configs(distrPath): for config in self.configs(distrPath):
config_name = path.join(distrPath, config) config_name = path.join(distrPath, config)
if path.exists(config_name): if path.exists(config_name):
return KernelConfig(config_name) return KernelConfig(config_name)
except DistributiveError as e: except DistributiveError:
return "" return ""
return "" return ""
@ -184,8 +187,8 @@ class VariableOsInstallKernelScheduleDefault(Variable):
def choice(self): def choice(self):
return self.Select('os_install_kernel_schedule_name', return self.Select('os_install_kernel_schedule_name',
where='os_install_kernel_schedule_set', where='os_install_kernel_schedule_set',
eq='on') eq='on')
class VariableOsInstallKernelScheduleData(ReadonlyTableVariable): class VariableOsInstallKernelScheduleData(ReadonlyTableVariable):
@ -195,21 +198,21 @@ class VariableOsInstallKernelScheduleData(ReadonlyTableVariable):
source = ['os_install_kernel_schedule_name', source = ['os_install_kernel_schedule_name',
'os_install_kernel_schedule_set'] 'os_install_kernel_schedule_set']
def get(self,hr=False): def get(self, hr=HumanReadable.No):
installed = ['cfq'] schedulers = {'CONFIG_IOSCHED_BFQ=y': 'bfq',
schedulers = {'CONFIG_IOSCHED_BFQ=y':'bfq', 'CONFIG_IOSCHED_NOOP=y': 'noop',
'CONFIG_IOSCHED_NOOP=y':'noop', 'CONFIG_IOSCHED_CFQ=y': 'cfq',
'CONFIG_IOSCHED_CFQ=y':'cfq', 'CONFIG_IOSCHED_DEADLINE=y': 'deadline'}
'CONFIG_IOSCHED_DEADLINE=y':'deadline'}
installed = map(schedulers.get, installed = map(schedulers.get,
filter(lambda x:x in schedulers, filter(lambda x: x in schedulers,
self.Get('os_install_kernel_config'))) or ['cfq'] self.Get('os_install_kernel_config'))) or ['cfq']
return [[x,"on" if x in installed else "off"] return [[x, "on" if x in installed else "off"]
for x in sorted(schedulers.values())] for x in sorted(schedulers.values())]
setValue = Variable.setValue setValue = Variable.setValue
class VariableOsInstallKernelScheduleName(FieldValue,ReadonlyVariable):
class VariableOsInstallKernelScheduleName(FieldValue, ReadonlyVariable):
""" """
Schedule name Schedule name
""" """
@ -217,7 +220,8 @@ class VariableOsInstallKernelScheduleName(FieldValue,ReadonlyVariable):
source_variable = "os_install_kernel_schedule_data" source_variable = "os_install_kernel_schedule_data"
column = 0 column = 0
class VariableOsInstallKernelScheduleSet(FieldValue,ReadonlyVariable):
class VariableOsInstallKernelScheduleSet(FieldValue, ReadonlyVariable):
""" """
Kernel has schedule Kernel has schedule
""" """
@ -225,6 +229,7 @@ class VariableOsInstallKernelScheduleSet(FieldValue,ReadonlyVariable):
source_variable = "os_install_kernel_schedule_data" source_variable = "os_install_kernel_schedule_data"
column = 1 column = 1
class VariableOsInstallKernelTuxoniceSet(ReadonlyVariable): class VariableOsInstallKernelTuxoniceSet(ReadonlyVariable):
""" """
Available BFQ in kernel Available BFQ in kernel
@ -237,6 +242,7 @@ class VariableOsInstallKernelTuxoniceSet(ReadonlyVariable):
return "on" return "on"
return "off" return "off"
class VariableOsInstallKernelBfqSet(ReadonlyVariable): class VariableOsInstallKernelBfqSet(ReadonlyVariable):
""" """
Available BFQ in kernel Available BFQ in kernel
@ -249,10 +255,12 @@ class VariableOsInstallKernelBfqSet(ReadonlyVariable):
return "on" return "on"
return "off" return "off"
class VariableOsInstallKernelAttr(Variable): class VariableOsInstallKernelAttr(Variable):
""" """
Install kernel attributes Install kernel attributes
""" """
def get(self): def get(self):
# on usb-hdd install must be "delay=5" # on usb-hdd install must be "delay=5"
attr = "" attr = ""
@ -268,102 +276,110 @@ class VariableOsInstallKernelAttr(Variable):
rdauto = " rd.auto" rdauto = " rd.auto"
return attr + rdauto return attr + rdauto
class VariableOsInstallKernelResume(ReadonlyVariable): class VariableOsInstallKernelResume(ReadonlyVariable):
""" """
Install kernel resume Install kernel resume
""" """
def get(self): def get(self):
"""install kernel resume parameter""" """install kernel resume parameter"""
for dev, install in zip(self.Get('os_install_disk_use'), for dev, install in zip(self.Get('os_install_disk_use'),
self.Get('os_install_disk_mount')): self.Get('os_install_disk_mount')):
if install == "swap": if install == "swap":
if self.Get('os_install_kernel_tuxonice_set') == 'on': if self.Get('os_install_kernel_tuxonice_set') == 'on':
return \ return "tuxonice tuxonice_resume=%s real_resume=%s" % (
"tuxonice tuxonice_resume=%s real_resume=%s"%(dev,dev) dev, dev)
else: else:
return "real_resume=%s"%dev return "real_resume=%s" % dev
return "" return ""
class KernelHelper:
class KernelHelper(VariableInterface):
""" """
Helper for kernel variables Helper for kernel variables
""" """
reFindVer = re.compile( reFindVer = re.compile(
"(?<=version )(\d+\.?\d*\.?\d*\.?\d*)([^\d* ])*(\d*)") "(?<=version )(\d+\.?\d*\.?\d*\.?\d*)([^\d* ])*(\d*)")
def getFilesByType(self,pathname,descr): def getFilesByType(self, pathname, descr):
"""Get files from "pathname" has "descr" in descriptions""" """Get files from "pathname" has "descr" in descriptions"""
filelist = map(lambda x:path.join(pathname,x),os.listdir(pathname)) filelist = map(lambda x: path.join(pathname, x), os.listdir(pathname))
ftype = typeFile(magic=MAGIC_COMPRESS|MAGIC_SYMLINK).getMType ftype = typeFile(magic=MAGIC_COMPRESS | MAGIC_SYMLINK).getMType
filesWithType = map(lambda x:(x,ftype(x)), filesWithType = map(lambda x: (x, ftype(x)),
filter(path.exists, filter(path.exists,
filelist)) filelist))
return filter(lambda x:descr in x[1],filesWithType) return filter(lambda x: descr in x[1], filesWithType)
def getInitrd(self,arch,shortname,chroot,kernel,suffix="",notsuffix=""): def getInitrd(self, arch, shortname, chroot, kernel, suffix="",
notsuffix=""):
"""Get initrd for kernel""" """Get initrd for kernel"""
reInitrdVer = re.compile("(initrd|initramfs)-(.+?)(-install)?$",re.S) reInitrdVer = re.compile("(initrd|initramfs)-(.+?)(-install)?$", re.S)
def initrd_version_by_name(filename): def initrd_version_by_name(filename):
resInitrdVer = reInitrdVer.search(filename) resInitrdVer = reInitrdVer.search(filename)
if resInitrdVer: if resInitrdVer:
return resInitrdVer.groups()[1] return resInitrdVer.groups()[1]
return "" return ""
ftype = typeFile(magic=MAGIC_COMPRESS|MAGIC_SYMLINK).getMType ftype = typeFile(magic=MAGIC_COMPRESS | MAGIC_SYMLINK).getMType
kernelfile = path.join(chroot,'boot',kernel) kernelfile = path.join(chroot, 'boot', kernel)
typeKernelFile = ftype(kernelfile) typeKernelFile = ftype(kernelfile)
if typeKernelFile == None: if typeKernelFile is None:
return "" return ""
resKernelVer = self.reFindVer.search(ftype(kernelfile)) resKernelVer = self.reFindVer.search(ftype(kernelfile))
if resKernelVer: if resKernelVer:
kernelVersion = "%s-%s-%s"% \ kernelVersion = "%s-%s-%s" % \
(resKernelVer.group().replace('-calculate',''), (resKernelVer.group().replace('-calculate', ''),
arch, shortname) arch, shortname)
origKernelVer = resKernelVer.group() origKernelVer = resKernelVer.group()
bootdir = path.join(chroot,'boot') bootdir = path.join(chroot, 'boot')
initramfsFiles = self.getFilesByType(bootdir,"ASCII cpio archive") initramfsFiles = self.getFilesByType(bootdir, "ASCII cpio archive")
initramfsWithVer = \ initramfsWithVer = \
filter(lambda x: (kernelVersion in x[1] or filter(lambda x: (kernelVersion in x[1] or
origKernelVer in x[1]) and \ origKernelVer in x[1]) and \
x[0].endswith(suffix) 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])), not notsuffix or not x[0].endswith(notsuffix)),
map(lambda x: (x[0], initrd_version_by_name(x[0])),
initramfsFiles)) initramfsFiles))
if initramfsWithVer: if initramfsWithVer:
return path.split(min(initramfsWithVer, return path.split(min(initramfsWithVer,
key=itemgetter(0))[0])[-1] key=itemgetter(0))[0])[-1]
return "" return ""
class VariableOsInstallKernel(ReadonlyVariable,KernelHelper): class VariableOsInstallKernel(ReadonlyVariable, KernelHelper):
""" """
Kernel filename Kernel filename
""" """
def get(self): def get(self):
bootdir = path.join(self.Get('cl_chroot_path'),'boot') bootdir = path.join(self.Get('cl_chroot_path'), 'boot')
modulesdir = path.join(self.Get('cl_chroot_path'),'lib/modules') modulesdir = path.join(self.Get('cl_chroot_path'), 'lib/modules')
validKernel = listDirectory(modulesdir) validKernel = listDirectory(modulesdir)
kernelFiles = self.getFilesByType(bootdir,"Linux kernel") kernelFiles = self.getFilesByType(bootdir, "Linux kernel")
installMarch = self.Get('os_install_arch_machine') installMarch = self.Get('os_install_arch_machine')
kernelsWithVer = \ kernelsWithVer = \
map(lambda x:(x[0],(getTupleVersion("".join(x[1].groups()[0:3:2])), map(lambda x: (
path.getmtime(x[0]))), x[0], (getTupleVersion("".join(x[1].groups()[0:3:2])),
# convert version to tuple( versionTuple, mtime) path.getmtime(x[0]))),
# version detect, for this version lib contains moudules # convert version to tuple( versionTuple, mtime)
# kernel arch equal install arch # version detect, for this version lib contains moudules
ifilter(lambda x:x[1] and x[1].group() in validKernel and # kernel arch equal install arch
installMarch in x[0].rpartition('/')[2], ifilter(lambda x: x[1] and x[1].group() in validKernel and
# (filename,version) installMarch in x[0].rpartition('/')[2],
imap(lambda x:(x[0],self.reFindVer.search(x[1])), # (filename,version)
kernelFiles))) imap(lambda x: (x[0], self.reFindVer.search(x[1])),
kernelFiles)))
if kernelsWithVer: if kernelsWithVer:
return path.split(max(kernelsWithVer,key=itemgetter(1))[0])[-1] return path.split(max(kernelsWithVer, key=itemgetter(1))[0])[-1]
else: else:
return "vmlinuz" return "vmlinuz"
class VariableOsInstallInitrd(ReadonlyVariable,KernelHelper):
class VariableOsInstallInitrd(ReadonlyVariable, KernelHelper):
""" """
Optimized initramfs filename Optimized initramfs filename
""" """
@ -373,18 +389,20 @@ class VariableOsInstallInitrd(ReadonlyVariable,KernelHelper):
self.Get('os_install_linux_shortname'), self.Get('os_install_linux_shortname'),
self.Get('cl_chroot_path'), self.Get('cl_chroot_path'),
self.Get('os_install_kernel'), self.Get('os_install_kernel'),
suffix="",notsuffix="-install") or \ suffix="", notsuffix="-install") or \
self.getInitrd(self.Get('os_install_arch_machine'), self.getInitrd(self.Get('os_install_arch_machine'),
self.Get('os_install_linux_shortname'), self.Get('os_install_linux_shortname'),
self.Get('cl_chroot_path'), self.Get('cl_chroot_path'),
self.Get('os_install_kernel'), self.Get('os_install_kernel'),
suffix="-install")[:-8] \ suffix="-install")[:-8] \
or "initrd" or "initrd"
class VariableOsInstallInitrdInstall(ReadonlyVariable,KernelHelper): class VariableOsInstallInitrdInstall(ReadonlyVariable, KernelHelper):
""" """
Install initramfs filename Install initramfs filename
""" """
def get(self): def get(self):
return self.getInitrd(self.Get('os_install_arch_machine'), return self.getInitrd(self.Get('os_install_arch_machine'),
self.Get('os_install_linux_shortname'), self.Get('os_install_linux_shortname'),
@ -397,33 +415,37 @@ class VariableOsInstallSystemMap(ReadonlyVariable):
""" """
Install system map filename Install system map filename
""" """
def get(self): def get(self):
systemmapfile = self.Get('os_install_kernel').replace('vmlinuz', systemmapfile = self.Get('os_install_kernel').replace('vmlinuz',
'System.map') 'System.map')
if systemmapfile.startswith('System.map') and path.exists( if systemmapfile.startswith('System.map') and path.exists(
path.join(self.Get('cl_chroot_path'),'boot',systemmapfile)): path.join(self.Get('cl_chroot_path'), 'boot', systemmapfile)):
return systemmapfile return systemmapfile
else: else:
return "" return ""
class VariableOsInstallKernelCpufreq(ReadonlyVariable): class VariableOsInstallKernelCpufreq(ReadonlyVariable):
""" """
Cpufreq modules Cpufreq modules
""" """
def get(self): def get(self):
"""Get cpufreq (and other from modules_3= param) from conf.d/modules""" """Get cpufreq (and other from modules_3= param) from conf.d/modules"""
cpufreqmods = map(lambda x:x.partition('=')[2].strip("\n '\""), cpufreqmods = map(lambda x: x.partition('=')[2].strip("\n '\""),
filter(lambda x:x.startswith('modules_3'), filter(lambda x: x.startswith('modules_3'),
readLinesFile('/etc/conf.d/modules'))) readLinesFile('/etc/conf.d/modules')))
if cpufreqmods: if cpufreqmods:
return cpufreqmods[0] return cpufreqmods[0]
else: else:
return "" return ""
class VariableClInstallKernelUid(ReadonlyVariable): class VariableClInstallKernelUid(ReadonlyVariable):
""" """
Variable install kernel UID Variable install kernel UID
""" """
def get(self): def get(self):
return getKernelUid(self.Get('os_install_root_dev')) return getKernelUid(self.Get('os_install_root_dev'))

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,25 +14,24 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import sys import sys
from os import path from calculate.lib.datavars import ReadonlyVariable, VariableInterface
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable from calculate.lib.variables.linux import Linux
from calculate.lib.variables.linux import (Linux,VariableOsLinuxName,
VariableOsLinuxSystem,VariableOsLinuxSubname)
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3',sys.modules[__name__])
class InstallLinux(Linux): setLocalTranslate('cl_install3', sys.modules[__name__])
def __getFromImageOrCurrent(self,currentVar):
class InstallLinux(Linux, VariableInterface):
def __getFromImageOrCurrent(self, currentVar):
"""Get value from install image or current system""" """Get value from install image or current system"""
if self.Get('cl_action') == 'system': if self.Get('cl_action') == 'system':
image = self.Get('cl_image') image = self.Get('cl_image')
if image: if image:
d = image.getInfo() d = image.getInfo()
# support lazy values # support lazy values
res = d.get(currentVar,"") res = d.get(currentVar, "")
return str(res()) if callable(res) else res return str(res()) if callable(res) else res
else: else:
return "" return ""
@ -48,39 +47,47 @@ class InstallLinux(Linux):
"""Get by distroinfo or current info""" """Get by distroinfo or current info"""
return self.__getFromImageOrCurrent(self.current_variable) return self.__getFromImageOrCurrent(self.current_variable)
class VariableOsInstallLinuxShortname(InstallLinux,ReadonlyVariable):
class VariableOsInstallLinuxShortname(InstallLinux, ReadonlyVariable):
"""Shortname of system""" """Shortname of system"""
current_variable = "os_linux_shortname" current_variable = "os_linux_shortname"
class VariableOsInstallLinuxVer(InstallLinux,ReadonlyVariable):
"""Shortname of system""" class VariableOsInstallLinuxVer(InstallLinux, ReadonlyVariable):
"""Version of system"""
current_variable = "os_linux_ver" current_variable = "os_linux_ver"
class VariableOsInstallLinuxBuild(InstallLinux,ReadonlyVariable):
"""Shortname of system""" class VariableOsInstallLinuxBuild(InstallLinux, ReadonlyVariable):
"""Build of system"""
current_variable = "os_linux_build" current_variable = "os_linux_build"
class VariableOsInstallArchMachine(InstallLinux,ReadonlyVariable):
"""Shortname of system""" class VariableOsInstallArchMachine(InstallLinux, ReadonlyVariable):
"""Arch of system"""
current_variable = "os_arch_machine" current_variable = "os_arch_machine"
class VariableOsInstallLinuxFiles(InstallLinux,ReadonlyVariable):
"""Shortname of system""" class VariableOsInstallLinuxFiles(InstallLinux, ReadonlyVariable):
"""Files num in system"""
current_variable = "os_linux_files" current_variable = "os_linux_files"
class VariableOsInstallLinuxName(InstallLinux,ReadonlyVariable):
class VariableOsInstallLinuxName(InstallLinux, ReadonlyVariable):
""" """
Install distro name Install distro name
""" """
current_variable = "os_linux_name" current_variable = "os_linux_name"
class VariableOsInstallLinuxSystem(InstallLinux,ReadonlyVariable):
class VariableOsInstallLinuxSystem(InstallLinux, ReadonlyVariable):
""" """
Install system name Install system name
""" """
current_variable = "os_linux_system" current_variable = "os_linux_system"
class VariableOsInstallLinuxSubname(InstallLinux,ReadonlyVariable):
class VariableOsInstallLinuxSubname(InstallLinux, ReadonlyVariable):
""" """
Install subname Install subname
""" """

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,24 +14,26 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import sys import sys
from os import path from os import path
from calculate.lib.datavars import Variable, VariableError, ReadonlyVariable from calculate.lib.datavars import Variable, VariableError, ReadonlyVariable
from calculate.lib.variables.locale import Locale from calculate.lib.variables.locale import Locale
from calculate.lib.utils.files import readLinesFile, process from calculate.lib.utils.files import readLinesFile, process
from calculate.lib.utils.common import getValueFromCmdLine, getValueFromConfig from calculate.lib.utils.common import getValueFromCmdLine, getValueFromConfig
from pytz import timezone,country_timezones,UnknownTimeZoneError from pytz import timezone, country_timezones, UnknownTimeZoneError
from datetime import datetime from datetime import datetime
from operator import itemgetter from operator import itemgetter
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_install3',sys.modules[__name__])
class LocaleVariable(ReadonlyVariable,Locale): setLocalTranslate('cl_install3', sys.modules[__name__])
class LocaleVariable(ReadonlyVariable, Locale):
""" """
Locale variables not using for flash installation Locale variables not using for flash installation
""" """
def uncompatible(self): def uncompatible(self):
""" """
Network setting up unavailable for flash installation Network setting up unavailable for flash installation
@ -41,6 +43,7 @@ class LocaleVariable(ReadonlyVariable,Locale):
_("Locale configuration unavailable for Flash install") _("Locale configuration unavailable for Flash install")
return "" return ""
class VariableOsInstallLinguas(LocaleVariable): class VariableOsInstallLinguas(LocaleVariable):
""" """
Current LINGUAS value Current LINGUAS value
@ -49,74 +52,79 @@ class VariableOsInstallLinguas(LocaleVariable):
def get(self): def get(self):
def get_linguas(lines): def get_linguas(lines):
linguas = map(lambda x:x.strip().rpartition('=')[-1].strip('"\''), linguas = map(lambda x: x.strip().rpartition('=')[-1].strip('"\''),
filter(lambda x: x.startswith("LINGUAS="), filter(lambda x: x.startswith("LINGUAS="),
lines)) lines))
return linguas[-1] if linguas else "" return linguas[-1] if linguas else ""
makeconf = '/etc/make.conf' makeconf = '/etc/make.conf'
emerge_config = self.Get('cl_emerge_config') emerge_config = self.Get('cl_emerge_config')
if emerge_config and "LINGUAS" in emerge_config: if emerge_config and "LINGUAS" in emerge_config:
return emerge_config['LINGUAS'].encode('UTF-8') return emerge_config['LINGUAS'].encode('UTF-8')
infocommand = ['emerge','--info'] infocommand = ['emerge', '--info']
defaultLinguas = "bg en de es fr it pl pt_BR nl ru uk" defaultLinguas = "bg en de es fr it pl pt_BR nl ru uk"
# get linguas from make.conf, emerge --info or default # get linguas from make.conf, emerge --info or default
curlanguage = self.Get('os_install_locale_language') curlanguage = self.Get('os_install_locale_language')
return get_linguas(readLinesFile(makeconf)) or \ return get_linguas(readLinesFile(makeconf)) or \
" ".join(filter(lambda x:x=="en" or x==curlanguage, " ".join(filter(lambda x: x == "en" or x == curlanguage,
get_linguas( get_linguas(
process(*infocommand).readlines() or "").split())) or \ process(
*infocommand).readlines() or "").split())) or \
defaultLinguas defaultLinguas
class VariableOsInstallLocaleConsolefont(LocaleVariable): class VariableOsInstallLocaleConsolefont(LocaleVariable):
""" """
Consolefont for locale Consolefont for locale
""" """
def get(self): def get(self):
return self.getFieldByKeymap("consolefont", return self.getFieldByKeymap("consolefont",
self.Get('os_install_locale_keymap')) self.Get('os_install_locale_keymap'))
class VariableOsInstallLocaleKeymap(LocaleVariable): class VariableOsInstallLocaleKeymap(LocaleVariable):
""" """
Keymap of locale (used for /etc/conf.d/keymaps) Keymap of locale (used for /etc/conf.d/keymaps)
""" """
def get(self): def get(self):
# get keymap from boot calculate param (keymap specified # get keymap from boot calculate param (keymap specified
# by lang) # by lang)
keymapConfd = '/etc/conf.d/keymaps' keymap = getValueFromCmdLine("calculate", 1)
keymap = getValueFromCmdLine("calculate",1)
if self.isLangExists(keymap): if self.isLangExists(keymap):
return self.getFieldByLang('keymap',keymap) return self.getFieldByLang('keymap', keymap)
# get keymap by os_install_locale_lang
# Temporary comment get keymap from config file
#keymap = getValueFromConfig(keymapConfd,'KEYMAP')
#if keymap:
# return keymap
return self.getFieldByLang("keymap", return self.getFieldByLang("keymap",
self.Get("os_install_locale_lang")) self.Get("os_install_locale_lang"))
class VariableOsInstallLocaleDumpkeys(LocaleVariable): class VariableOsInstallLocaleDumpkeys(LocaleVariable):
""" """
Dumpkeys_charset for keymap Dumpkeys_charset for keymap
""" """
def get(self): def get(self):
# is specified keymap support by locale hash # is specified keymap support by locale hash
if self.Get('os_install_locale_keymap') in self.getFields('keymap'): if self.Get('os_install_locale_keymap') in self.getFields('keymap'):
return self.getFieldByKeymap("dumpkeys_charset", return self.getFieldByKeymap("dumpkeys_charset",
self.Get('os_install_locale_keymap')) self.Get('os_install_locale_keymap'))
else: else:
return self.getFieldByLang("dumpkeys_charset", return self.getFieldByLang("dumpkeys_charset",
self.Get('os_install_locale_lang')) self.Get('os_install_locale_lang'))
class VariableOsInstallLocaleLocale(LocaleVariable): class VariableOsInstallLocaleLocale(LocaleVariable):
""" """
Locale (at example: ru_RU.UTF-8) Locale (at example: ru_RU.UTF-8)
""" """
def get(self): def get(self):
"""locale (example: ru_RU.UTF-8)""" """locale (example: ru_RU.UTF-8)"""
return self.getFieldByLang("locale", return self.getFieldByLang("locale",
self.Get('os_install_locale_lang')) self.Get('os_install_locale_lang'))
class VariableOsInstallLocaleLang(LocaleVariable): class VariableOsInstallLocaleLang(LocaleVariable):
""" """
@ -125,7 +133,7 @@ class VariableOsInstallLocaleLang(LocaleVariable):
mode = 'w' mode = 'w'
metavalue = "LANG" metavalue = "LANG"
type = 'choice' type = 'choice'
opt = ["--lang","-l"] opt = ["--lang", "-l"]
def init(self): def init(self):
self.label = _("Language") self.label = _("Language")
@ -137,28 +145,35 @@ class VariableOsInstallLocaleLang(LocaleVariable):
def choice(self): def choice(self):
return sorted(zip(self.Get('os_lang'), return sorted(zip(self.Get('os_lang'),
map(str,self.Get('os_lang',humanreadable=True))),key=itemgetter(1)) map(str, self.Get('os_lang', humanreadable=True))),
key=itemgetter(1))
class VariableOsInstallLocaleLanguage(LocaleVariable): class VariableOsInstallLocaleLanguage(LocaleVariable):
""" """
Short language (at example ru) Short language (at example ru)
""" """
def get(self): def get(self):
return self.getFieldByLang("language", return self.getFieldByLang("language",
self.Get('os_install_locale_lang')) self.Get('os_install_locale_lang'))
class VariableOsInstallLocaleXkb(LocaleVariable): class VariableOsInstallLocaleXkb(LocaleVariable):
""" """
Keyboard layout for X server Keyboard layout for X server
""" """
def get(self): def get(self):
return self.getFieldByLang("xkblayout", return self.getFieldByLang("xkblayout",
self.Get('os_install_locale_lang')) self.Get('os_install_locale_lang'))
class VariableOsInstallLocaleXkbname(LocaleVariable): class VariableOsInstallLocaleXkbname(LocaleVariable):
""" """
Keyboard layout name for X server Keyboard layout name for X server
""" """
def get(self): def get(self):
localeXkb = self.Get("os_install_locale_xkb") localeXkb = self.Get("os_install_locale_xkb")
if localeXkb: if localeXkb:
@ -182,131 +197,135 @@ class VariableOsInstallClockTimezone(LocaleVariable):
def get(self): def get(self):
return self.Get('os_clock_timezone') return self.Get('os_clock_timezone')
def check(self,value): def check(self, value):
if not value or not path.isfile(path.join( if not value or not path.isfile(path.join(
"/usr/share/zoneinfo",value)): "/usr/share/zoneinfo", value)):
raise VariableError(_("Wrong timezone %s")%value) raise VariableError(_("Wrong timezone %s") % value)
def generateComments(self,tzs): def generateComments(self, tzs):
""" """
Generate comments by timezone names Generate comments by timezone names
""" """
for tzname in tzs: for tzname in tzs:
# add separator # add separator
if tzname == "---": if tzname == "---":
yield ("---","---") yield ("---", "---")
continue continue
try: try:
tz = timezone(tzname) tz = timezone(tzname)
strinfo = tz.localize(datetime.now()).strftime('%z') strinfo = tz.localize(datetime.now()).strftime('%z')
yield (tzname,"%s (%s:%s)"%(tzname,strinfo[:3],strinfo[-2:])) yield (
tzname, "%s (%s:%s)" % (tzname, strinfo[:3], strinfo[-2:]))
except UnknownTimeZoneError: except UnknownTimeZoneError:
pass pass
def choice(self): def choice(self):
source = ["Etc/GMT-12", source = ["Etc/GMT-12",
"Pacific/Midway", "Pacific/Midway",
"Pacific/Honolulu", "Pacific/Honolulu",
"America/Anchorage", "America/Anchorage",
"Canada/Pacific", "Canada/Pacific",
"America/Tijuana", "America/Tijuana",
"America/Phoenix", "America/Phoenix",
"America/Denver", "America/Denver",
"America/Mazatlan", "America/Mazatlan",
"America/Monterrey", "America/Monterrey",
"America/Regina", "America/Regina",
"America/Mexico_City", "America/Mexico_City",
"Canada/Central", "Canada/Central",
"America/Bogota", "America/Bogota",
"America/New_York", "America/New_York",
"America/Indiana/Indianapolis", "America/Indiana/Indianapolis",
"America/Halifax", "America/Halifax",
"America/Caracas", "America/Caracas",
"America/Manaus", "America/Manaus",
"America/Santiago", "America/Santiago",
"America/St_Johns", "America/St_Johns",
"America/Sao_Paulo", "America/Sao_Paulo",
"America/Argentina/Buenos_Aires", "America/Argentina/Buenos_Aires",
"Etc/GMT+3", "Etc/GMT+3",
"America/Montevideo", "America/Montevideo",
"Atlantic/South_Georgia", "Atlantic/South_Georgia",
"Atlantic/Azores", "Atlantic/Azores",
"Atlantic/Cape_Verde", "Atlantic/Cape_Verde",
"UTC", "UTC",
"Africa/Casablanca", "Africa/Casablanca",
"Europe/Amsterdam", "Europe/Amsterdam",
"Europe/Belgrade", "Europe/Belgrade",
"Europe/Brussels", "Europe/Brussels",
"Europe/Zagreb", "Europe/Zagreb",
"Africa/Tunis", "Africa/Tunis",
"Europe/Kaliningrad", "Europe/Kaliningrad",
"Asia/Amman", "Asia/Amman",
"Europe/Istanbul", "Europe/Istanbul",
"Asia/Beirut", "Asia/Beirut",
"Europe/Helsinki", "Europe/Helsinki",
"Europe/Kiev", "Europe/Kiev",
"Europa/Sofia", "Europa/Sofia",
"Africa/Windhoek", "Africa/Windhoek",
"Asia/Jerusalem", "Asia/Jerusalem",
"Africa/Cairo", "Africa/Cairo",
"Europe/Minsk", "Europe/Minsk",
"Africa/Harare", "Africa/Harare",
"Europe/Moscow", "Europe/Moscow",
"Asia/Baghdad", "Asia/Baghdad",
"Asia/Kuwait", "Asia/Kuwait",
"Africa/Nairobi", "Africa/Nairobi",
"Asia/Tbilisi", "Asia/Tbilisi",
"Asia/Tehran", "Asia/Tehran",
"Europe/Samara", "Europe/Samara",
"Asia/Muscat", "Asia/Muscat",
"Asia/Baku", "Asia/Baku",
"Asia/Yerevan", "Asia/Yerevan",
"Asia/Kabul", "Asia/Kabul",
"Asia/Yekaterinburg", "Asia/Yekaterinburg",
"Asia/Karachi", "Asia/Karachi",
"Asia/Calcutta", "Asia/Calcutta",
"Asia/Jayapura", "Asia/Jayapura",
"Asia/Katmandu", "Asia/Katmandu",
"Asia/Almaty", "Asia/Almaty",
"Asia/Omsk", "Asia/Omsk",
"Asia/Dhaka", "Asia/Dhaka",
"Asia/Rangoon", "Asia/Rangoon",
"Asia/Krasnoyarsk", "Asia/Krasnoyarsk",
"Asia/Bangkok", "Asia/Bangkok",
"Asia/Irkutsk", "Asia/Irkutsk",
"Asia/Hong_Kong", "Asia/Hong_Kong",
"Asia/Singapore", "Asia/Singapore",
"Australia/Perth", "Australia/Perth",
"Asia/Taipei", "Asia/Taipei",
"Asia/Yakutsk", "Asia/Yakutsk",
"Asia/Tokyo", "Asia/Tokyo",
"Asia/Seoul", "Asia/Seoul",
"Australia/Adelaide", "Australia/Adelaide",
"Australia/Darwin", "Australia/Darwin",
"Asia/Vladivostok", "Asia/Vladivostok",
"Australia/Brisbane", "Australia/Brisbane",
"Pacific/Guam", "Pacific/Guam",
"Australia/Melbourne", "Australia/Melbourne",
"Australia/Hobart", "Australia/Hobart",
"Asia/Srednekolymsk", "Asia/Srednekolymsk",
"Asia/Kamchatka", "Asia/Kamchatka",
"Pacific/Auckland", "Pacific/Auckland",
"Etc/GMT-13"] "Etc/GMT-13"]
def sortkey(s): def sortkey(s):
tz = timezone(s) tz = timezone(s)
strinfo = tz.localize(datetime.now()).strftime('%z') strinfo = tz.localize(datetime.now()).strftime('%z')
return (int(strinfo[:3]),int("%s%s"%(strinfo[0],strinfo[-2:]))) return int(strinfo[:3]), int("%s%s" % (strinfo[0], strinfo[-2:]))
try: try:
lang = self.Get('os_install_locale_lang').split('_')[1] lang = self.Get('os_install_locale_lang').split('_')[1]
nativeTZ = map(lambda x:x.encode('utf-8'), nativeTZ = map(lambda x: x.encode('utf-8'),
country_timezones[lang]) country_timezones[lang])
source = nativeTZ + ["---"] + \ source = nativeTZ + ["---"] + \
sorted(filter(lambda x:not x in nativeTZ,source), sorted(filter(lambda x: not x in nativeTZ, source),
key=sortkey) key=sortkey)
except (KeyError,IndexError) as e: except (KeyError, IndexError):
pass pass
return list(self.generateComments(source)) return list(self.generateComments(source))
class VariableOsInstallClockType(Variable): class VariableOsInstallClockType(Variable):
""" """
Type of clock (UTC or local) Type of clock (UTC or local)
@ -321,9 +340,9 @@ class VariableOsInstallClockType(Variable):
def get(self): def get(self):
"""type of clock (UTC or local)""" """type of clock (UTC or local)"""
clockTypeFile = ['/etc/conf.d/clock','/etc/conf.d/hwclock'] clockTypeFile = ['/etc/conf.d/clock', '/etc/conf.d/hwclock']
for f in clockTypeFile: for f in clockTypeFile:
clock = getValueFromConfig(f,"clock") clock = getValueFromConfig(f, "clock")
if clock: if clock:
if clock.upper() == 'UTC': if clock.upper() == 'UTC':
return clock.upper() return clock.upper()
@ -332,4 +351,4 @@ class VariableOsInstallClockType(Variable):
return "local" return "local"
def choice(self): def choice(self):
return ["local","UTC"] return ["local", "UTC"]

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,38 +14,33 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import sys import sys
import re from calculate.lib.datavars import (Variable, VariableInterface,
import pty,fcntl ReadonlyVariable, ReadonlyTableVariable,
from subprocess import Popen FieldValue, HumanReadable)
from os import path from calculate.lib.utils.files import (process, checkUtils)
from itertools import *
from calculate.lib.datavars import (TableVariable,Variable,VariableError,
ReadonlyVariable,ReadonlyTableVariable,
FieldValue)
from calculate.lib.utils.files import (process,checkUtils)
from calculate.install.distr import PartitionDistributive
from calculate.install.fs_manager import FileSystemManager
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3',sys.modules[__name__])
class LvmHelper: setLocalTranslate('cl_install3', sys.modules[__name__])
class LvmHelper(VariableInterface):
def getLvmData(self): def getLvmData(self):
"""Get route table, exclude specifed iface""" """Get route table, exclude specifed iface"""
pvDisplayProg = checkUtils('/sbin/pvdisplay') pvDisplayProg = checkUtils('/sbin/pvdisplay')
pvDisplay = process(pvDisplayProg,"--noh","-Co", pvDisplay = process(pvDisplayProg, "--noh", "-Co",
"lv_name,vg_name,pv_name") "lv_name,vg_name,pv_name")
for line in pvDisplay: for line in pvDisplay:
line = line.split() line = line.split()
if len(line) == 3: if len(line) == 3:
yield line yield line
####################################################### #######################################################
# Devices variables # Devices variables
####################################################### #######################################################
class VariableOsLvmData(ReadonlyTableVariable,LvmHelper): class VariableOsLvmData(ReadonlyTableVariable, LvmHelper):
""" """
Information about disk devices Information about disk devices
""" """
@ -53,13 +48,14 @@ class VariableOsLvmData(ReadonlyTableVariable,LvmHelper):
'os_lvm_vgname', 'os_lvm_vgname',
'os_lvm_pvname'] 'os_lvm_pvname']
def get(self,hr=False): def get(self, hr=HumanReadable.No):
"""LVM hash""" """LVM hash"""
return list(self.getLvmData()) or [[]] return list(self.getLvmData()) or [[]]
setValue = Variable.setValue setValue = Variable.setValue
class VariableOsLvmLvname(FieldValue,ReadonlyVariable):
class VariableOsLvmLvname(FieldValue, ReadonlyVariable):
""" """
Logical volumes names Logical volumes names
""" """
@ -67,7 +63,8 @@ class VariableOsLvmLvname(FieldValue,ReadonlyVariable):
source_variable = "os_lvm_data" source_variable = "os_lvm_data"
column = 0 column = 0
class VariableOsLvmVgname(FieldValue,ReadonlyVariable):
class VariableOsLvmVgname(FieldValue, ReadonlyVariable):
""" """
Volume groups names Volume groups names
""" """
@ -75,7 +72,8 @@ class VariableOsLvmVgname(FieldValue,ReadonlyVariable):
source_variable = "os_lvm_data" source_variable = "os_lvm_data"
column = 1 column = 1
class VariableOsLvmPvname(FieldValue,ReadonlyVariable):
class VariableOsLvmPvname(FieldValue, ReadonlyVariable):
""" """
Phisical volumes names Phisical volumes names
""" """

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,35 +14,36 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import sys import sys
import re import re
from os import path,readlink from os import path, readlink
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable, \ from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
READONLY, TableVariable,FieldValue READONLY, TableVariable, FieldValue,
VariableInterface, HumanReadable)
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_install3',sys.modules[__name__])
from calculate.lib.utils.ip import (getInterfaces,getIp,getMask,getMac, setLocalTranslate('cl_install3', sys.modules[__name__])
cidrToMask,maskToCidr,getIpNet,isDhcpIp,checkIp,checkMask,
getOperState,getPlugged) from calculate.lib.utils.ip import (getInterfaces, getIp, getMask, getMac,
cidrToMask, maskToCidr, getIpNet, isDhcpIp,
checkIp, checkMask,
getOperState, getPlugged)
from calculate.lib.utils.device import lspci from calculate.lib.utils.device import lspci
from calculate.lib.utils.files import listDirectory,readLinesFile,process,\ from calculate.lib.utils.files import (listDirectory, readLinesFile)
readFile
from calculate.lib.utils import ip from calculate.lib.utils import ip
from calculate.lib.utils.portage import isPkgInstalled from calculate.lib.utils.portage import isPkgInstalled
from operator import itemgetter from operator import itemgetter
from itertools import * from itertools import *
from functools import partial
import hashlib
from calculate.install.distr import DistributiveError from calculate.install.distr import DistributiveError
class NetHelper:
class NetHelper(VariableInterface):
""" """
Network variables not using for flash installation Network variables not using for flash installation
""" """
routing = False routing = False
def uncompatible(self): def uncompatible(self):
""" """
Network setting up unavailable for flash installation Network setting up unavailable for flash installation
@ -51,13 +52,14 @@ class NetHelper:
return \ return \
_("Network configuration is unavailable for Flash install") _("Network configuration is unavailable for Flash install")
if self.routing and not self.Select('os_install_net_interfaces', if self.routing and not self.Select('os_install_net_interfaces',
where='os_install_net_status', where='os_install_net_status',
_notin=('off','dhcp'),limit=1): _notin=('off', 'dhcp'), limit=1):
return _("Network routing configuration is not available if all " return _("Network routing configuration is not available if all "
"interfaces are set to DHCP") "interfaces are set to DHCP")
return "" return ""
class VariableOsInstallNtp(NetHelper,Variable):
class VariableOsInstallNtp(NetHelper, Variable):
""" """
NTP server for system NTP server for system
""" """
@ -69,13 +71,15 @@ class VariableOsInstallNtp(NetHelper,Variable):
self.label = _("NTP server") self.label = _("NTP server")
self.help = _("set the NTP server for the system") self.help = _("set the NTP server for the system")
class VariableOsInstallProxy(NetHelper,Variable):
class VariableOsInstallProxy(NetHelper, Variable):
""" """
Proxy for system Proxy for system
""" """
value = "" value = ""
class VariableOsInstallNetInterfaces(NetHelper,ReadonlyVariable):
class VariableOsInstallNetInterfaces(NetHelper, ReadonlyVariable):
""" """
Net interface devices Net interface devices
""" """
@ -87,7 +91,8 @@ class VariableOsInstallNetInterfaces(NetHelper,ReadonlyVariable):
def get(self): def get(self):
return sorted(getInterfaces()) return sorted(getInterfaces())
class VariableOsInstallNetInterfacesOrig(NetHelper,ReadonlyVariable):
class VariableOsInstallNetInterfacesOrig(NetHelper, ReadonlyVariable):
""" """
Net interface devices orig name from udev (enp0s2) Net interface devices orig name from udev (enp0s2)
Depricated Depricated
@ -97,26 +102,30 @@ class VariableOsInstallNetInterfacesOrig(NetHelper,ReadonlyVariable):
def get(self): def get(self):
return self.Get('os_install_net_interfaces') return self.Get('os_install_net_interfaces')
class VariableOsNetInterfacesInfo(NetHelper,ReadonlyVariable):
class VariableOsNetInterfacesInfo(NetHelper, ReadonlyVariable):
""" """
Inforamation about net interfaces Inforamation about net interfaces
""" """
def get(self): def get(self):
netInterfaces=self.Get("os_net_interfaces") self.Get("os_net_interfaces")
listInterfacesInfo = [] listInterfacesInfo = []
# Получена ли сеть по DHCP если нет to ip или off # Получена ли сеть по DHCP если нет to ip или off
for interface,ipaddr,dhcp in zip(self.Get('os_install_net_interfaces'), for interface, ipaddr, dhcp in zip(
self.Get('os_install_net_ip'), self.Get('os_install_net_interfaces'),
self.Get('os_install_net_dhcp_set')): self.Get('os_install_net_ip'),
self.Get('os_install_net_dhcp_set')):
if dhcp == "on": if dhcp == "on":
listInterfacesInfo.append((interface, _("DHCP"))) listInterfacesInfo.append((interface, _("DHCP")))
else: else:
listInterfacesInfo.append((interface, listInterfacesInfo.append((interface,
ipaddr if ipaddr else _("Off"))) ipaddr if ipaddr else _("Off")))
return ", ".join(map(lambda x:"%s (%s)"%(x[0],x[1]), return ", ".join(map(lambda x: "%s (%s)" % (x[0], x[1]),
listInterfacesInfo)) listInterfacesInfo))
class VariableOsInstallNetData(NetHelper,TableVariable):
class VariableOsInstallNetData(NetHelper, TableVariable):
""" """
Hash for information about net Hash for information about net
""" """
@ -135,27 +144,31 @@ class VariableOsInstallNetData(NetHelper,TableVariable):
return ifaces[0] return ifaces[0]
else: else:
return "enp0s0" return "enp0s0"
self.label = _("Addresses") self.label = _("Addresses")
# self.help = _("IP address with network (example:%s)")%"192.168.1.1/24" # self.help = _("IP address with network (example:%s)")%"192.168.1.1/24"
self.help = _("Network interface, DHCP or IP address and network mask " self.help = _("Network interface, DHCP or IP address and network mask "
"(example: %s)")%(" --iface %s:192.168.1.1:24"% "(example: %s)") % (" --iface %s:192.168.1.1:24" %
defaultInterface()) defaultInterface())
def raiseReadonlyIndexError(self,fieldname="",variablename="", def raiseReadonlyIndexError(self, fieldname="", variablename="",
value=""): value=""):
""" """
Behavior on change readonly index Behavior on change readonly index
""" """
raise VariableError(_("Network interface %s not found")%value) raise VariableError(_("Network interface %s not found") % value)
class VariableOsInstallNetHostname(NetHelper,Variable): class VariableOsInstallNetHostname(NetHelper, Variable):
""" """
Computer hostname Computer hostname
""" """
def get(self): def get(self):
return self.Get('os_install_net_fqdn').partition('.')[0] return self.Get('os_install_net_fqdn').partition('.')[0]
class VariableOsInstallNetFqdn(NetHelper,Variable):
class VariableOsInstallNetFqdn(NetHelper, Variable):
""" """
Full host name Full host name
""" """
@ -166,41 +179,46 @@ class VariableOsInstallNetFqdn(NetHelper,Variable):
self.label = _("Hostname") self.label = _("Hostname")
self.help = _("set either the short or the full hostname") self.help = _("set either the short or the full hostname")
def set(self,value): def set(self, value):
if "." in value: if "." in value:
return value return value
else: else:
return "%s.%s"%(value,self.Get('os_install_net_domain')) return "%s.%s" % (value, self.Get('os_install_net_domain'))
def check(self,value): def check(self, value):
maxfqdn = 254 maxfqdn = 254
if len(value) > maxfqdn: if len(value) > maxfqdn:
raise VariableError( raise VariableError(
_("The hostname length should be less than %d")%maxfqdn) _("The hostname length should be less than %d") % maxfqdn)
def get(self): def get(self):
if path.exists('/proc/self/fd/1') and \ if path.exists('/proc/self/fd/1') and \
readlink('/proc/self/fd/1') == '/dev/console' and \ readlink('/proc/self/fd/1') == '/dev/console' and \
self.Get('os_root_dev') == '/dev/nfs': self.Get('os_root_dev') == '/dev/nfs':
return "calculate.local" return "calculate.local"
return self.Get('os_net_fqdn') return self.Get('os_net_fqdn')
class VariableOsInstallNetDomain(NetHelper,Variable):
class VariableOsInstallNetDomain(NetHelper, Variable):
""" """
Domain on install system Domain on install system
""" """
def get(self): def get(self):
return self.Get('os_install_net_fqdn').partition('.')[2] return self.Get('os_install_net_fqdn').partition('.')[2]
class VariableOsInstallNetAllow(NetHelper,Variable):
class VariableOsInstallNetAllow(NetHelper, Variable):
""" """
Allowed network Allowed network
""" """
def get(self): def get(self):
"""Allowed network""" """Allowed network"""
return self.Get("os_net_allow") return self.Get("os_net_allow")
class VariableOsInstallNetName(NetHelper,ReadonlyVariable):
class VariableOsInstallNetName(NetHelper, ReadonlyVariable):
""" """
Net device names Net device names
""" """
@ -211,22 +229,25 @@ class VariableOsInstallNetName(NetHelper,ReadonlyVariable):
def get(self): def get(self):
rePci = re.compile(r"(\d\d:\d\d\.\d)(?:/[^/]+){2}$") rePci = re.compile(r"(\d\d:\d\d\.\d)(?:/[^/]+){2}$")
def getPci(interface): def getPci(interface):
pathname = path.realpath(path.join('/sys/class/net', pathname = path.realpath(path.join('/sys/class/net',
interface)) interface))
pci = rePci.search(pathname) pci = rePci.search(pathname)
if pci: if pci:
return pci.group(1) return pci.group(1)
else: else:
return "" return ""
pciEthernet = lspci(shortInfo=True) pciEthernet = lspci(shortInfo=True)
return map(lambda x:"{vendor} {name}".format(**x), return map(lambda x: "{vendor} {name}".format(**x),
map(lambda x:pciEthernet.get(getPci(x), map(lambda x: pciEthernet.get(getPci(x),
{'vendor':_("Unknown"), {'vendor': _("Unknown"),
'name':_("vendor")}), 'name': _("vendor")}),
self.Get('os_install_net_interfaces'))) self.Get('os_install_net_interfaces')))
class VariableOsInstallNetMac(NetHelper,ReadonlyVariable):
class VariableOsInstallNetMac(NetHelper, ReadonlyVariable):
""" """
Net devices mac (Example: 01:02:03:04:05:06) Net devices mac (Example: 01:02:03:04:05:06)
""" """
@ -236,10 +257,11 @@ class VariableOsInstallNetMac(NetHelper,ReadonlyVariable):
self.label = _("MAC") self.label = _("MAC")
def get(self): def get(self):
return map(lambda x:getMac(x).lower(), return map(lambda x: getMac(x).lower(),
self.Get('os_install_net_interfaces')) self.Get('os_install_net_interfaces'))
class VariableOsInstallNetStatus(NetHelper,Variable): class VariableOsInstallNetStatus(NetHelper, Variable):
""" """
Net status (dhcp,ip,or off) Net status (dhcp,ip,or off)
""" """
@ -250,10 +272,10 @@ class VariableOsInstallNetStatus(NetHelper,Variable):
def get(self): def get(self):
return map(self.getDefaultValue, return map(self.getDefaultValue,
self.Get('os_install_net_interfaces')) self.Get('os_install_net_interfaces'))
def getDefaultValue(self,iface): def getDefaultValue(self, iface):
def statusValue(ipaddr,dhcp): def statusValue(ipaddr, dhcp):
if not getPlugged(iface): if not getPlugged(iface):
return 'off' return 'off'
if dhcp == "on": if dhcp == "on":
@ -265,29 +287,31 @@ class VariableOsInstallNetStatus(NetHelper,Variable):
return "off" return "off"
else: else:
return "dhcp" return "dhcp"
rootDevNfs = self.Get('os_root_dev') == '/dev/nfs' rootDevNfs = self.Get('os_root_dev') == '/dev/nfs'
return statusValue(getIp(iface),"on" \ return statusValue(getIp(iface), "on" \
if rootDevNfs or isDhcpIp(iface) else "off") if rootDevNfs or isDhcpIp(iface) else "off")
def set(self,value): def set(self, value):
value = map(lambda x:x.lower() if x else x,value) value = map(lambda x: x.lower() if x else x, value)
ifaces = self.Get('os_install_net_interfaces') ifaces = self.Get('os_install_net_interfaces')
return map(lambda x:self.getDefaultValue(x[1]) \ return map(lambda x: self.getDefaultValue(x[1]) \
if x[0] == "auto" else x[0], if x[0] == "auto" else x[0],
zip(value,ifaces)) zip(value, ifaces))
def check(self,value): def check(self, value):
for status in value: for status in value:
if status not in map(lambda x:x[0],self.choice()) and \ if status not in map(lambda x: x[0], self.choice()) and \
not checkIp(status): not checkIp(status):
raise VariableError(_("Wrong IP address %s")%status) raise VariableError(_("Wrong IP address %s") % status)
def choice(self): def choice(self):
return (("dhcp",_("DHCP")), return (("dhcp", _("DHCP")),
("off", _("Disabled")), ("off", _("Disabled")),
("auto", _("Auto"))) ("auto", _("Auto")))
class VariableOsInstallNetIp(NetHelper,ReadonlyVariable):
class VariableOsInstallNetIp(NetHelper, ReadonlyVariable):
""" """
IP for all network interfaces IP for all network interfaces
""" """
@ -297,20 +321,21 @@ class VariableOsInstallNetIp(NetHelper,ReadonlyVariable):
self.label = _("IP address") self.label = _("IP address")
def get(self): def get(self):
return map(lambda x:"" if x[1].lower() == "off" else return map(lambda x: "" if x[1].lower() == "off" else
getIp(x[0]) if x[1].lower() == "dhcp" else x[1], getIp(x[0]) if x[1].lower() == "dhcp" else x[1],
zip(self.Get('os_install_net_interfaces'), zip(self.Get('os_install_net_interfaces'),
self.Get('os_install_net_status'))) self.Get('os_install_net_status')))
# def check(self,value):
# dhcps = self.Get('os_install_net_dhcp_set')
# wrongIp = filter(lambda x:x[0] and not checkIp(x[0]),
# zip(value,dhcps))
# if wrongIp:
# if wrongIp[0][0]:
# raise VariableError(_("Wrong IP address %s")%wrongIp[0][0])
#def check(self,value):
# dhcps = self.Get('os_install_net_dhcp_set')
# wrongIp = filter(lambda x:x[0] and not checkIp(x[0]),
# zip(value,dhcps))
# if wrongIp:
# if wrongIp[0][0]:
# raise VariableError(_("Wrong IP address %s")%wrongIp[0][0])
class VariableOsInstallNetNetwork(NetHelper,ReadonlyVariable): class VariableOsInstallNetNetwork(NetHelper, ReadonlyVariable):
""" """
Network for ip (Example:192.168.0.0/16) Network for ip (Example:192.168.0.0/16)
""" """
@ -320,11 +345,12 @@ class VariableOsInstallNetNetwork(NetHelper,ReadonlyVariable):
self.label = _("Network") self.label = _("Network")
def get(self): def get(self):
return map(lambda x:getIpNet(x[0],x[1]) if x[0] and x[1] else "", return map(lambda x: getIpNet(x[0], x[1]) if x[0] and x[1] else "",
zip(self.Get('os_install_net_ip'), zip(self.Get('os_install_net_ip'),
self.Get('os_install_net_mask'))) self.Get('os_install_net_mask')))
class VariableOsInstallNetCidr(NetHelper,ReadonlyVariable): class VariableOsInstallNetCidr(NetHelper, ReadonlyVariable):
""" """
CIDR of interfaces CIDR of interfaces
""" """
@ -337,10 +363,11 @@ class VariableOsInstallNetCidr(NetHelper,ReadonlyVariable):
""" """
Get CIDR of ip,net (Example: 24) Get CIDR of ip,net (Example: 24)
""" """
return map(lambda x:maskToCidr(x) if x else '', return map(lambda x: maskToCidr(x) if x else '',
self.Get('os_install_net_mask')) self.Get('os_install_net_mask'))
class VariableOsInstallNetMask(NetHelper,Variable):
class VariableOsInstallNetMask(NetHelper, Variable):
""" """
Net mask of interfaces (Example:255.255.0.0) Net mask of interfaces (Example:255.255.0.0)
""" """
@ -350,28 +377,30 @@ class VariableOsInstallNetMask(NetHelper,Variable):
self.label = _("Mask") self.label = _("Mask")
def get(self): def get(self):
return map(lambda x:cidrToMask(getMask(x)), return map(lambda x: cidrToMask(getMask(x)),
self.Get('os_install_net_interfaces')) self.Get('os_install_net_interfaces'))
def set(self,value): def set(self, value):
""" """
Convert to mask CIDR value Convert to mask CIDR value
""" """
def convertCidrToMask(x): def convertCidrToMask(x):
if x and x.isdigit() and int(x) in range(0,33): if x and x.isdigit() and int(x) in range(0, 33):
return cidrToMask(int(x)) return cidrToMask(int(x))
else: else:
return x return x
res = map(convertCidrToMask,value)
res = map(convertCidrToMask, value)
return res return res
def check(self,value): def check(self, value):
dhcps = self.Get('os_install_net_status') dhcps = self.Get('os_install_net_status')
wrongMask = filter(lambda x:(x[0] or not x[1] in ("off","dhcp")) and \ wrongMask = filter(lambda x: (x[0] or not x[1] in ("off", "dhcp")) and \
not checkMask(x[0]), not checkMask(x[0]),
zip(value,dhcps)) zip(value, dhcps))
if wrongMask: if wrongMask:
raise VariableError(_("Wrong mask %s")%wrongMask[0][0]) raise VariableError(_("Wrong mask %s") % wrongMask[0][0])
def choice(self): def choice(self):
return ["255.255.255.255", return ["255.255.255.255",
@ -381,7 +410,7 @@ class VariableOsInstallNetMask(NetHelper,Variable):
"0.0.0.0"] "0.0.0.0"]
class VariableOsInstallNetDhcpSet(NetHelper,Variable): class VariableOsInstallNetDhcpSet(NetHelper, Variable):
""" """
Describe ip was get by DHCP or manualy Describe ip was get by DHCP or manualy
""" """
@ -391,10 +420,11 @@ class VariableOsInstallNetDhcpSet(NetHelper,Variable):
self.label = _("DHCP") self.label = _("DHCP")
def get(self): def get(self):
return map(lambda x:"on" if x == "dhcp" else "off", return map(lambda x: "on" if x == "dhcp" else "off",
self.Get('os_install_net_status')) self.Get('os_install_net_status'))
class VariableOsInstallNetRouteData(NetHelper,TableVariable):
class VariableOsInstallNetRouteData(NetHelper, TableVariable):
""" """
Route table data Route table data
""" """
@ -415,41 +445,42 @@ class VariableOsInstallNetRouteData(NetHelper,TableVariable):
_("add a routing rule (specified as " _("add a routing rule (specified as "
"NETWORK:[GATEWAY][:DEV[:SOURCE]])") "NETWORK:[GATEWAY][:DEV[:SOURCE]])")
def get(self,hr=False): def get(self, hr=HumanReadable.No):
"""Routing hash""" """Routing hash"""
interfaces = self.Get('os_install_net_interfaces') interfaces = self.Get('os_install_net_interfaces')
interfaces_status = self.Get('os_install_net_status') interfaces_status = self.Get('os_install_net_status')
interfaces_network = self.Get('os_install_net_network') interfaces_network = self.Get('os_install_net_network')
staticInterface = \ staticInterface = \
map(itemgetter(0,2), map(itemgetter(0, 2),
filter(lambda x:not x[1] in ("off","dhcp"), filter(lambda x: not x[1] in ("off", "dhcp"),
zip(interfaces,interfaces_status,interfaces_network))) zip(interfaces, interfaces_status, interfaces_network)))
route_data = [] route_data = []
if staticInterface: if staticInterface:
staticInterface,skipNet = zip(*staticInterface) staticInterface, skipNet = zip(*staticInterface)
return map(lambda x:[x[0], return map(lambda x: [x[0],
x[1].get('via',''), x[1].get('via', ''),
x[1].get('dev',''), x[1].get('dev', ''),
x[1].get('src','')], x[1].get('src', '')],
ifilter(lambda x:not x[0] in skipNet, ifilter(lambda x: not x[0] in skipNet,
ip.getRouteTable(staticInterface))) or [[]] ip.getRouteTable(staticInterface))) or [[]]
return [[]] return [[]]
def getHumanReadableAuto(self): def getHumanReadableAuto(self):
return Variable.getHumanReadableAuto(self) return Variable.getHumanReadableAuto(self)
def setValue(self,value,force=False): def setValue(self, value, force=False):
""" """
Standard action for set value Standard action for set value
""" """
self.value = self.set(value) self.value = self.set(value)
self.wasSet = True self.wasSet = True
self.invalid = False self.invalid = False
# run check # run check
if not force: if not force:
self._check() self._check()
class VariableOsInstallNetRouteNetwork(FieldValue,NetHelper,Variable):
class VariableOsInstallNetRouteNetwork(NetHelper, FieldValue, Variable):
""" """
Net for route table record Net for route table record
""" """
@ -461,23 +492,24 @@ class VariableOsInstallNetRouteNetwork(FieldValue,NetHelper,Variable):
self.label = _("Network") self.label = _("Network")
def choice(self): def choice(self):
return ["default"] #+self.Get('os_install_net_network') return ["default"] # +self.Get('os_install_net_network')
def check(self,value): def check(self, value):
########################## ##########################
# detect duplicate network # detect duplicate network
########################## ##########################
for wrongnet in ifilterfalse(ip.checkNet, for wrongnet in ifilterfalse(ip.checkNet,
ifilter("default".__ne__, ifilter("default".__ne__,
value)): value)):
raise VariableError(_("Wrong network %s")%wrongnet) raise VariableError(_("Wrong network %s") % wrongnet)
dupNetwork = list(set(filter(lambda x:value.count(x)>1, dupNetwork = list(set(filter(lambda x: value.count(x) > 1,
value))) value)))
if dupNetwork: if dupNetwork:
raise VariableError( raise VariableError(
_("Network '%s' is used more than once")%dupNetwork[0]) _("Network '%s' is used more than once") % dupNetwork[0])
class VariableOsInstallNetRouteGw(FieldValue,NetHelper,Variable): class VariableOsInstallNetRouteGw(NetHelper, FieldValue, Variable):
""" """
Gateway for route table record Gateway for route table record
""" """
@ -487,30 +519,32 @@ class VariableOsInstallNetRouteGw(FieldValue,NetHelper,Variable):
def init(self): def init(self):
self.label = _("Gateway") self.label = _("Gateway")
def check(self,value): def check(self, value):
############################# #############################
# search unreachable gateways # search unreachable gateways
############################# #############################
NET,GW = 0,1 NET, GW = 0, 1
netsGw = zip(self.Get('os_install_net_route_network'), netsGw = zip(self.Get('os_install_net_route_network'),
value) value)
nets = filter(lambda x:x and x != "default", nets = filter(lambda x: x and x != "default",
chain(self.Get('os_install_net_route_network'), chain(self.Get('os_install_net_route_network'),
self.Get('os_install_net_network'))) self.Get('os_install_net_network')))
for wrongip in ifilterfalse(ip.checkIp,value): for wrongip in ifilterfalse(ip.checkIp, value):
raise VariableError(_("Wrong gateway IP %s")%wrongip) raise VariableError(_("Wrong gateway IP %s") % wrongip)
wrongGws = map(lambda x:x[GW], wrongGws = map(lambda x: x[GW],
filter(lambda x:not ip.isIpInNet(x[GW], filter(lambda x: not ip.isIpInNet(x[GW],
*(set(nets) - set(x[NET]))), *(set(nets) - set(
filter(lambda x:x[GW], x[NET]))),
netsGw))) filter(lambda x: x[GW],
netsGw)))
if wrongGws: if wrongGws:
raise VariableError(_("Gateways %s are unreachable")% raise VariableError(_("Gateways %s are unreachable") %
(",".join(wrongGws))) (",".join(wrongGws)))
class VariableOsInstallNetRouteDev(FieldValue,NetHelper,Variable):
class VariableOsInstallNetRouteDev(NetHelper, FieldValue, Variable):
""" """
Device for route table record Device for route table record
""" """
@ -524,7 +558,8 @@ class VariableOsInstallNetRouteDev(FieldValue,NetHelper,Variable):
def choice(self): def choice(self):
return self.Get('os_install_net_interfaces') return self.Get('os_install_net_interfaces')
class VariableOsInstallNetRouteSrc(FieldValue,NetHelper,Variable):
class VariableOsInstallNetRouteSrc(NetHelper, FieldValue, Variable):
""" """
Source ip for route table record Source ip for route table record
""" """
@ -536,61 +571,64 @@ class VariableOsInstallNetRouteSrc(FieldValue,NetHelper,Variable):
self.label = _("Source IP") self.label = _("Source IP")
def choice(self): def choice(self):
return [""]+self.Get('os_install_net_ip') return [""] + self.Get('os_install_net_ip')
def check(self,value): def check(self, value):
for wrongip in ifilterfalse(ip.checkIp, for wrongip in ifilterfalse(ip.checkIp,
ifilter(None,value)): ifilter(None, value)):
raise VariableError(_("Wrong source IP %s")%wrongip) raise VariableError(_("Wrong source IP %s") % wrongip)
ipAddrs = self.Get('os_install_net_ip') ipAddrs = self.Get('os_install_net_ip')
wrongIps = filter(lambda x: x and not x in ipAddrs, wrongIps = filter(lambda x: x and not x in ipAddrs,
value) value)
if wrongIps: if wrongIps:
raise VariableError( raise VariableError(
_("Wrong IP address %s in the specified source IP")% _("Wrong IP address %s in the specified source IP") %
(",".join(wrongIps))) (",".join(wrongIps)))
class VariableOsInstallNetRoute(NetHelper,ReadonlyVariable):
class VariableOsInstallNetRoute(NetHelper, ReadonlyVariable):
""" """
Data by route for conf.d/net Data by route for conf.d/net
""" """
def performRouteData(self,performFunc): def performRouteData(self, performFunc):
routeMatrix = zip(self.Get('os_install_net_route_network'), routeMatrix = zip(self.Get('os_install_net_route_network'),
self.Get('os_install_net_route_gw'), self.Get('os_install_net_route_gw'),
self.Get('os_install_net_route_dev'), 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 DEV, IP, CIDR, NET = 0, 1, 2, 1
return map(lambda x:performFunc(x[DEV],x[NET],routeMatrix), return map(lambda x: performFunc(x[DEV], x[NET], routeMatrix),
# union ip and mask to ip/net # union ip and mask to ip/net
map(lambda x:(x[DEV],ip.getIpNet(x[IP],cidr=x[CIDR])) \ map(lambda x: (x[DEV], ip.getIpNet(x[IP], cidr=x[CIDR])) \
if x[IP] and x[CIDR] else (x[DEV],""), if x[IP] and x[CIDR] else (x[DEV], ""),
#filter(lambda x:x[IP] and x[CIDR], # filter(lambda x:x[IP] and x[CIDR],
zip(self.Get('os_install_net_interfaces'), zip(self.Get('os_install_net_interfaces'),
self.Get('os_install_net_ip'), self.Get('os_install_net_ip'),
self.Get('os_install_net_cidr')))) self.Get('os_install_net_cidr'))))
def get(self): def get(self):
"""Route info for conf.d/net""" """Route info for conf.d/net"""
defaultDev = 0 defaultDev = 0
workIfaces = self.Select('os_install_net_interfaces', workIfaces = self.Select('os_install_net_interfaces',
where='os_install_net_status', where='os_install_net_status',
_notin="off") _notin="off")
if len(workIfaces) == 1: if len(workIfaces) == 1:
defaultDev = workIfaces[0] defaultDev = workIfaces[0]
def getRouteForInterfaceConf(interface,net,routeMatrix):
NET,GW,DEV,SRC = 0,1,2,3 def getRouteForInterfaceConf(interface, net, routeMatrix):
NET, GW, DEV, SRC = 0, 1, 2, 3
return "\n".join( return "\n".join(
# build string for route from net,gateway,dev and src # build string for route from net,gateway,dev and src
map(lambda x:"{net}{gateway}{src}".format( map(lambda x: "{net}{gateway}{src}".format(
net=x[NET], net=x[NET],
gateway=" via %s"%x[GW] if x[GW] else "", gateway=" via %s" % x[GW] if x[GW] else "",
src=" src %s"%x[SRC] if x[SRC] else ""), src=" src %s" % x[SRC] if x[SRC] else ""),
# filter by interface and discard direct routes # filter by interface and discard direct routes
# example: for 192.168.1.5/24 discard 192.168.1.0/24 net # example: for 192.168.1.5/24 discard 192.168.1.0/24 net
filter(lambda x:(interface==x[DEV] or defaultDev and \ filter(lambda x: (interface == x[DEV] or defaultDev and
interface==defaultDev) \ interface == defaultDev) \
and net!=x[NET],routeMatrix))) and net != x[NET], routeMatrix)))
return self.performRouteData(getRouteForInterfaceConf) return self.performRouteData(getRouteForInterfaceConf)
@ -604,56 +642,65 @@ class VariableOsInstallNetNmroute(VariableOsInstallNetRoute):
"""Route info for system-connections of NetworkManager""" """Route info for system-connections of NetworkManager"""
defaultDev = 0 defaultDev = 0
workIfaces = self.Select('os_install_net_interfaces', workIfaces = self.Select('os_install_net_interfaces',
where='os_install_net_status', where='os_install_net_status',
_notin="off") _notin="off")
if len(workIfaces) == 1: if len(workIfaces) == 1:
defaultDev = workIfaces[0] defaultDev = workIfaces[0]
def getRouteForInterfaceNM(interface,net,routeMatrix):
NET,GW,DEV,SRC = 0,1,2,3 def getRouteForInterfaceNM(interface, net, routeMatrix):
defaultGw = map(lambda x:"%s;"%x[GW], NET, GW, DEV, SRC = 0, 1, 2, 3
filter(lambda x:interface==x[DEV] and \ defaultGw = map(lambda x: "%s;" % x[GW],
x[NET]=="default", filter(lambda x: interface == x[DEV] and \
routeMatrix)) x[NET] == "default",
routeMatrix))
return "{0}\n".format(defaultGw[0] if defaultGw else "") + \ return "{0}\n".format(defaultGw[0] if defaultGw else "") + \
"\n".join( "\n".join(
# build string for route from net,gateway,dev and src # build string for route from net,gateway,dev and src
map(lambda x:"routes{num}={ip};{cidr};{gateway};0;".format( map(lambda
num=x[0]+1, x: "routes{num}={ip};{cidr};{gateway};0;".format(
ip=x[1][NET].partition('/')[0], num=x[0] + 1,
cidr=x[1][NET].partition('/')[2], ip=x[1][NET].partition('/')[0],
gateway=x[1][GW] if x[1][GW] else "0.0.0.0"), cidr=x[1][NET].partition('/')[2],
# filter by interface and discard direct routes gateway=x[1][GW] if x[1][GW] else "0.0.0.0"),
# example: for 192.168.1.5/24 discard 192.168.1.0/24 net # filter by interface and discard direct routes
enumerate( # example: for 192.168.1.5/24 discard 192.168.1.0/24 net
filter(lambda x:(interface==x[DEV] or defaultDev and \ enumerate(
interface==defaultDev) and net!=x[NET] and \ filter(lambda x: (interface == x[
x[NET]!="default",routeMatrix)))) DEV] or defaultDev and
interface == defaultDev) and net !=
x[
NET] and \
x[NET] != "default",
routeMatrix))))
return self.performRouteData(getRouteForInterfaceNM) return self.performRouteData(getRouteForInterfaceNM)
class VariableOsInstallNetConfAvailable(NetHelper,Variable):
class VariableOsInstallNetConfAvailable(NetHelper, Variable):
""" """
Available net configuration Available net configuration
""" """
type = "list" type = "list"
def get(self): def get(self):
mapNetConf = (('networkmanager','net-misc/networkmanager', mapNetConf = (('networkmanager', 'net-misc/networkmanager',
_("NetworkManager")), _("NetworkManager")),
('openrc','',_('OpenRC'))) ('openrc', '', _('OpenRC')))
image = self.Get('cl_image') image = self.Get('cl_image')
if image: if image:
with image as distr: with image as distr:
try: try:
distrPath = image.getDirectory() distrPath = image.getDirectory()
return map(itemgetter(0,2), return map(itemgetter(0, 2),
filter(lambda x:not x[1] or isPkgInstalled(x[1], filter(lambda x: not x[1] or isPkgInstalled(x[1],
prefix=distrPath), prefix=distrPath),
mapNetConf)) mapNetConf))
except DistributiveError as e: except DistributiveError as e:
pass pass
return sorted(map(itemgetter(0,2),mapNetConf[-1:]),key=itemgetter(1)) return sorted(map(itemgetter(0, 2), mapNetConf[-1:]), key=itemgetter(1))
class VariableOsInstallNetConf(NetHelper,Variable):
class VariableOsInstallNetConf(NetHelper, Variable):
""" """
Net setup (networkmanager or openrc) Net setup (networkmanager or openrc)
""" """
@ -667,16 +714,17 @@ class VariableOsInstallNetConf(NetHelper,Variable):
def get(self): def get(self):
"""Net setup (networkmanager or openrc)""" """Net setup (networkmanager or openrc)"""
if filter(lambda x:x.lower() == ("networkmanager"), if filter(lambda x: x.lower() == "networkmanager",
listDirectory('/etc/runlevels/boot')+ listDirectory('/etc/runlevels/boot') +
listDirectory('/etc/runlevels/default')) \ listDirectory('/etc/runlevels/default')) \
or self.Get('os_root_type') == "livecd": or self.Get('os_root_type') == "livecd":
nm = "networkmanager" nm = "networkmanager"
else: else:
nm = "" nm = ""
for val,comment in self.Get('os_install_net_conf_available'): for val, comment in self.Get('os_install_net_conf_available'):
if nm == val and not (self.Get('os_root_dev') == '/dev/nfs' and \ if nm == val and not (self.Get('os_root_dev') == '/dev/nfs' and
self.Get('os_install_root_type') == "livecd"): self.Get(
'os_install_root_type') == "livecd"):
return nm return nm
else: else:
return "openrc" return "openrc"
@ -684,7 +732,8 @@ class VariableOsInstallNetConf(NetHelper,Variable):
def choice(self): def choice(self):
return self.Get('os_install_net_conf_available') return self.Get('os_install_net_conf_available')
class VariableOsInstallNetDnsSearch(NetHelper,Variable):
class VariableOsInstallNetDnsSearch(NetHelper, Variable):
""" """
Dns search Dns search
""" """
@ -705,22 +754,23 @@ class VariableOsInstallNetDnsSearch(NetHelper,Variable):
return True return True
return False return False
def set(self,value): def set(self, value):
return " ".join(re.split('[; ,]',value)) return " ".join(re.split('[; ,]', value))
def get(self): def get(self):
"""Get current name servers""" """Get current name servers"""
dnsSearch = " ".join( dnsSearch = " ".join(
map(lambda x:x.strip().partition("search")[2].strip(), map(lambda x: x.strip().partition("search")[2].strip(),
filter(lambda x:x.lstrip().startswith("search"), filter(lambda x: x.lstrip().startswith("search"),
readLinesFile('/etc/resolv.conf')))) readLinesFile('/etc/resolv.conf'))))
return "" if self.isDNSByDHCP() else dnsSearch return "" if self.isDNSByDHCP() else dnsSearch
def humanReadable(self): def humanReadable(self):
return self.Get() or (_("Get via DHCP") return self.Get() or (_("Get via DHCP")
if self.isDNSByDHCP() if self.isDNSByDHCP()
else _("Not used")) else _("Not used"))
class VariableOsInstallNetDns(VariableOsInstallNetDnsSearch): class VariableOsInstallNetDns(VariableOsInstallNetDnsSearch):
""" """
Dns servers Dns servers
@ -732,27 +782,30 @@ class VariableOsInstallNetDns(VariableOsInstallNetDnsSearch):
self.label = _("Domain name server") self.label = _("Domain name server")
self.help = _("domain name server (comma-separated)") self.help = _("domain name server (comma-separated)")
def set(self,value): def set(self, value):
return " ".join(re.split('[; ,]',value)) return " ".join(re.split('[; ,]', value))
def get(self): def get(self):
dnsIps = filter(ip.checkIp, dnsIps = filter(ip.checkIp,
map(lambda x:x.strip().partition("nameserver")[2].strip(), map(lambda x: x.strip().partition("nameserver")[
filter(lambda x:x.lstrip().startswith("nameserver"), 2].strip(),
readLinesFile('/etc/resolv.conf')))) filter(
lambda x: x.lstrip().startswith("nameserver"),
readLinesFile('/etc/resolv.conf'))))
return "" if self.isDNSByDHCP() else " ".join(dnsIps) return "" if self.isDNSByDHCP() else " ".join(dnsIps)
def check(self,value): def check(self, value):
reIp = re.compile(ip.IP_ADDR) reIp = re.compile(ip.IP_ADDR)
if any(ifilterfalse(reIp.match,value.split(' '))): if any(ifilterfalse(reIp.match, value.split(' '))):
raise VariableError(_("Wrong IP address for DNS")) raise VariableError(_("Wrong IP address for DNS"))
def humanReadable(self): def humanReadable(self):
return self.Get() or (_("Get via DHCP") return self.Get() or (_("Get via DHCP")
if self.isDNSByDHCP() if self.isDNSByDHCP()
else _("Not used")) else _("Not used"))
class VariableOsInstallNetSettings(NetHelper,Variable):
class VariableOsInstallNetSettings(NetHelper, Variable):
""" """
Net service configured Net service configured
""" """
@ -760,7 +813,8 @@ class VariableOsInstallNetSettings(NetHelper,Variable):
value = "" value = ""
def choice(self): def choice(self):
return [("","")]+self.Get('os_install_net_conf_available') return [("", "")] + self.Get('os_install_net_conf_available')
class VariableOsInstallPxeIp(Variable): class VariableOsInstallPxeIp(Variable):
""" """

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -18,27 +18,27 @@ import os
import sys import sys
import re import re
from os import path from os import path
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable, \ from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
TableVariable,PasswordError, \ TableVariable, PasswordError,
ReadonlyTableVariable,FieldValue, \ DataVarsError, VariableInterface)
DataVarsError
from calculate.install.fs_manager import FileSystemManager from calculate.install.fs_manager import FileSystemManager
from calculate.lib.utils.files import (readFile,getProgPath,process, from calculate.lib.utils.files import (readFile, getProgPath, process,
readLinesFile) readLinesFile)
from calculate.lib.utils.common import getPasswdUsers,getUserGroups,getGroups from calculate.lib.utils.common import getPasswdUsers, getUserGroups, getGroups
from calculate.lib.utils.common import getValueFromConfig,getValueFromCmdLine from calculate.lib.utils.common import getValueFromConfig, getValueFromCmdLine
from calculate.lib.utils.common import getUserPrimaryGroup from calculate.lib.utils.common import getUserPrimaryGroup
from calculate.lib.utils.portage import isPkgInstalled from calculate.lib.utils.portage import isPkgInstalled
from calculate.lib.utils.device import getUdevDeviceInfo from calculate.lib.utils.device import getUdevDeviceInfo
from crypt import crypt from crypt import crypt
from calculate.lib.encrypt import encrypt from calculate.lib.encrypt import encrypt
import calculate.lib.cl_template as cl_template import calculate.lib.cl_ini_parser as cl_ini_parser
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_install3',sys.modules[__name__]) setLocalTranslate('cl_install3', sys.modules[__name__])
class UserHelper:
class UserHelper(VariableInterface):
""" """
Locale variables not using for flash installation Locale variables not using for flash installation
""" """
@ -54,11 +54,12 @@ class UserHelper:
return _("Autologin is available for Xorg sessions only") return _("Autologin is available for Xorg sessions only")
return "" return ""
class VariableOsInstallScratch(ReadonlyVariable): class VariableOsInstallScratch(ReadonlyVariable):
""" """
Install system in scratch mode Install system in scratch mode
""" """
type = "bool" type = "bool"
opt = ['--build'] opt = ['--build']
def get(self): def get(self):
@ -68,6 +69,7 @@ class VariableOsInstallScratch(ReadonlyVariable):
else: else:
return self.Get('os_scratch') return self.Get('os_scratch')
class VariableOsFormatType(ReadonlyVariable): class VariableOsFormatType(ReadonlyVariable):
""" """
Filesystem format support by calcualte-install Filesystem format support by calcualte-install
@ -78,26 +80,28 @@ class VariableOsFormatType(ReadonlyVariable):
"""Filesystem format support by calcualte-install""" """Filesystem format support by calcualte-install"""
return FileSystemManager.supportFS.keys() return FileSystemManager.supportFS.keys()
class VariableOsFormatUse(ReadonlyVariable): class VariableOsFormatUse(ReadonlyVariable):
""" """
Avialable format by mkfs utility Avialable format by mkfs utility
""" """
type = "list" type = "list"
# (on or off) autoupdate config from install program # (on or off) autoupdate config from install program
cl_autoupdate_set = {'value': "off", cl_autoupdate_set = {
'type': "bool", 'type': "bool",
'value': "off"} 'value': "off"}
def checkFunc(self,fs): def checkFunc(self, fs):
if "format" in FileSystemManager.supportFS[fs] and \ if "format" in FileSystemManager.supportFS[fs] and \
path.exists(FileSystemManager.supportFS[fs]["format"]): path.exists(FileSystemManager.supportFS[fs]["format"]):
return "yes" return "yes"
return "no" return "no"
def get(self): def get(self):
return map(self.checkFunc, self.Get('os_format_type')) return map(self.checkFunc, self.Get('os_format_type'))
class VariableClMigrateRootPwd(UserHelper,Variable):
class VariableClMigrateRootPwd(UserHelper, Variable):
""" """
Root password Root password
""" """
@ -111,10 +115,10 @@ class VariableClMigrateRootPwd(UserHelper,Variable):
self.label = _("Root password") self.label = _("Root password")
def get(self): def get(self):
rootPasswd = map(lambda x:x[1], rootPasswd = map(lambda x: x[1],
filter("root".__eq__, filter("root".__eq__,
map(lambda x:x.split(':')[0:2], map(lambda x: x.split(':')[0:2],
readLinesFile('/etc/shadow')))) readLinesFile('/etc/shadow'))))
if rootPasswd: if rootPasswd:
rootPasswd = rootPasswd[0] rootPasswd = rootPasswd[0]
else: else:
@ -126,7 +130,7 @@ class VariableClMigrateRootPwd(UserHelper,Variable):
rootPasswd = "" rootPasswd = ""
return rootPasswd or "" return rootPasswd or ""
def set(self,value): def set(self, value):
""" """
Encrypt password Encrypt password
""" """
@ -138,13 +142,14 @@ class VariableClMigrateRootPwd(UserHelper,Variable):
else: else:
return encryptObj.getHashPasswd(value, "shadow_ssha256") return encryptObj.getHashPasswd(value, "shadow_ssha256")
def check(self,value): def check(self, value):
if not value: if not value:
raise PasswordError(_("Password for user %s missing")%"root") raise PasswordError(_("Password for user %s missing") % "root")
class VariableClInstallHomeCryptSet(UserHelper,Variable): class VariableClInstallHomeCryptSet(UserHelper, Variable):
type = 'bool' type = 'bool'
opt = ["--crypt-home","-C"] opt = ["--crypt-home", "-C"]
untrusted = True untrusted = True
def init(self): def init(self):
@ -155,19 +160,20 @@ class VariableClInstallHomeCryptSet(UserHelper,Variable):
return ("off" if self.Get('cl_autologin') return ("off" if self.Get('cl_autologin')
else self.Get('cl_home_crypt_set')) else self.Get('cl_home_crypt_set'))
def check(self,value): def check(self, value):
if value == "on" and self.Get('cl_autologin'): if value == "on" and self.Get('cl_autologin'):
raise VariableError( raise VariableError(
_("User profile encryption is uncompatible with autologin")) _("User profile encryption is uncompatible with autologin"))
class VariableClMigrateData(UserHelper,TableVariable):
class VariableClMigrateData(UserHelper, TableVariable):
""" """
User migrate data table User migrate data table
""" """
type = 'table' type = 'table'
opt = ["--user","-u"] opt = ["--user", "-u"]
metavalue = 'USER[:GROUPS]' metavalue = 'USER[:GROUPS]'
source = ['cl_migrate_user','cl_migrate_user_groups', source = ['cl_migrate_user', 'cl_migrate_user_groups',
'cl_migrate_user_pwd'] 'cl_migrate_user_pwd']
untrusted = True untrusted = True
@ -175,15 +181,18 @@ class VariableClMigrateData(UserHelper,TableVariable):
self.help = _("add a user to the installed system") self.help = _("add a user to the installed system")
self.label = _("Migrating users") self.label = _("Migrating users")
class VariableClMigrateDataBrief(UserHelper,TableVariable):
class VariableClMigrateDataBrief(UserHelper, TableVariable):
""" """
User migrate data table for brief view User migrate data table for brief view
""" """
source = ['cl_migrate_user','cl_migrate_user_groups'] source = ['cl_migrate_user', 'cl_migrate_user_groups']
def init(self): def init(self):
self.label = _("Migrating users") self.label = _("Migrating users")
class VariableClMigrateUser(UserHelper,Variable):
class VariableClMigrateUser(UserHelper, Variable):
""" """
Migrate users list Migrate users list
""" """
@ -196,26 +205,28 @@ class VariableClMigrateUser(UserHelper,Variable):
""" """
Migrating users (users above 1000 uid) Migrating users (users above 1000 uid)
""" """
return filter("root".__ne__,getPasswdUsers()) return filter("root".__ne__, getPasswdUsers())
class VariableClMigrateUserGroups(UserHelper,Variable):
class VariableClMigrateUserGroups(UserHelper, Variable):
""" """
Migrate users groups Migrate users groups
""" """
type = 'choice-list-list' type = 'choice-list-list'
defaultGroupList = ["users","wheel","audio","cdrom","video", defaultGroupList = ["users", "wheel", "audio", "cdrom", "video",
"cdrw","usb","plugdev","games","lp","scanner","uucp"] "cdrw", "usb", "plugdev", "games", "lp", "scanner",
"uucp"]
def getDefaultGroups(self): def getDefaultGroups(self):
return list(set(self.defaultGroupList)&set(getGroups())) return list(set(self.defaultGroupList) & set(getGroups()))
def init(self): def init(self):
self.label = _("Groups") self.label = _("Groups")
def set(self,value): def set(self, value):
value = map(lambda x: x \ value = map(lambda x: x \
if x and any(x) else self.getDefaultGroups(), if x and any(x) else self.getDefaultGroups(),
value) value)
return value return value
def getPrimaryGroup(self, username): def getPrimaryGroup(self, username):
@ -229,9 +240,9 @@ class VariableClMigrateUserGroups(UserHelper,Variable):
User groups User groups
""" """
passwdList = getPasswdUsers() passwdList = getPasswdUsers()
return map(lambda x:(self.getPrimaryGroup(x) + (getUserGroups(x) return map(lambda x: (self.getPrimaryGroup(x) + (getUserGroups(x)
if x in passwdList else self.getDefaultGroups())), if x in passwdList else self.getDefaultGroups())),
self.Get('cl_migrate_user')) self.Get('cl_migrate_user'))
def choice(self): def choice(self):
""" """
@ -239,7 +250,8 @@ class VariableClMigrateUserGroups(UserHelper,Variable):
""" """
return getGroups() return getGroups()
class VariableClMigrateUserPwd(UserHelper,Variable):
class VariableClMigrateUserPwd(UserHelper, Variable):
""" """
Migrate users who need to change passwords Migrate users who need to change passwords
""" """
@ -257,16 +269,16 @@ class VariableClMigrateUserPwd(UserHelper,Variable):
if os.access(fileName, os.R_OK): if os.access(fileName, os.R_OK):
migrateusers = self.Get("cl_migrate_user") migrateusers = self.Get("cl_migrate_user")
if migrateusers: if migrateusers:
lenData=9 lenData = 9
shadowData = filter(lambda x: len(x)==lenData, shadowData = filter(lambda x: len(x) == lenData,
map(lambda x: x.rstrip().split(":"), map(lambda x: x.rstrip().split(":"),
open(fileName))) open(fileName)))
shadowData = filter(lambda x: x[0] in migrateusers, shadowData) shadowData = filter(lambda x: x[0] in migrateusers, shadowData)
shadowData = map(lambda x: (x[0], x[1]), shadowData) shadowData = map(lambda x: (x[0], x[1]), shadowData)
shadowUsers = map(lambda x: x[0], shadowData) shadowUsers = map(lambda x: x[0], shadowData)
for userName in migrateusers: for userName in migrateusers:
if userName in shadowUsers: if userName in shadowUsers:
userData = filter(lambda x: x[0]==userName, userData = filter(lambda x: x[0] == userName,
shadowData) shadowData)
hashPwd = userData[0][1] hashPwd = userData[0][1]
retList.append(hashPwd) retList.append(hashPwd)
@ -274,34 +286,35 @@ class VariableClMigrateUserPwd(UserHelper,Variable):
retList.append("") retList.append("")
return retList return retList
def check(self,value): def check(self, value):
""" """
Check exists password for all migrate users Check exists password for all migrate users
""" """
for user,pwd in zip(self.Get('cl_migrate_user'),value): for user, pwd in zip(self.Get('cl_migrate_user'), value):
if not pwd: if not pwd:
raise PasswordError( raise PasswordError(
_("Password for user %s missing")%user) _("Password for user %s missing") % user)
def set(self,value): def set(self, value):
""" """
Encrypt passwords Encrypt passwords
""" """
reCheck = re.compile("^\$[^$]+\$[^$]+\$.*$") reCheck = re.compile("^\$[^$]+\$[^$]+\$.*$")
encryptObj = encrypt() encryptObj = encrypt()
return map(lambda x:x if reCheck.match(x) or not x else \ return map(lambda x: x if reCheck.match(x) or not x else \
encryptObj.getHashPasswd(x, "shadow_ssha256"), encryptObj.getHashPasswd(x, "shadow_ssha256"),
value) value)
class VariableClAutologin(UserHelper,Variable): class VariableClAutologin(UserHelper, Variable):
""" """
Autologin variable (contains user name for autologin) or Autologin variable (contains user name for autologin) or
empty string if disable empty string if disable
""" """
type = 'choiceedit' type = 'choiceedit'
opt = ["--autologin",'-A'] opt = ["--autologin", '-A']
metavalue = "USER" metavalue = "USER"
xorg_need = True xorg_need = True
@ -311,13 +324,13 @@ class VariableClAutologin(UserHelper,Variable):
def get(self): def get(self):
# autologin enable for livecd and all install type CMC # autologin enable for livecd and all install type CMC
cmdDomainSet = (getValueFromCmdLine("calculate","domain_pw") or cmdDomainSet = (getValueFromCmdLine("calculate", "domain_pw") or
getValueFromCmdLine("calculate","domain") or "") getValueFromCmdLine("calculate", "domain") or "")
if (not cmdDomainSet and if (not cmdDomainSet and
self.Get('os_install_root_type') == "livecd" ) or \ self.Get('os_install_root_type') == "livecd") or \
self.Get('os_install_linux_shortname') == "CMC": self.Get('os_install_linux_shortname') == "CMC":
nonRootUsers = filter(lambda x: x != "root", nonRootUsers = filter(lambda x: x != "root",
self.Get('cl_migrate_user')) self.Get('cl_migrate_user'))
if nonRootUsers: if nonRootUsers:
return nonRootUsers[0] return nonRootUsers[0]
else: else:
@ -325,19 +338,20 @@ class VariableClAutologin(UserHelper,Variable):
return "" return ""
def set(self, value): def set(self, value):
return {'none':''}.get(value, value) return {'none': ''}.get(value, value)
def choice(self): def choice(self):
return [""]+filter(lambda x:x != "root",self.Get('cl_migrate_user')) return [""] + filter(lambda x: x != "root", self.Get('cl_migrate_user'))
def check(self,value): def check(self, value):
""" """
Autologin only for migrated non-root users Autologin only for migrated non-root users
""" """
if value and not value in self.Get('cl_migrate_user'): if value and not value in self.Get('cl_migrate_user'):
raise VariableError(_("User %s does not exist")%value) raise VariableError(_("User %s does not exist") % value)
if value == "root": if value == "root":
raise VariableError(_("Autologin is unavailable for user %s")%value) raise VariableError(
_("Autologin is unavailable for user %s") % value)
def humanReadable(self): def humanReadable(self):
return self.Get() or _("Not used") return self.Get() or _("Not used")
@ -348,13 +362,14 @@ class VariableClAutologin(UserHelper,Variable):
""" """
try: try:
if (self.Get('cl_action') == 'merge' and if (self.Get('cl_action') == 'merge' and
self.Get('client.cl_remote_host')): self.Get('client.cl_remote_host')):
return \ return \
_("The autologin is not available with domain workstations") _("The autologin is not available with domain workstations")
except DataVarsError: except DataVarsError:
pass pass
return UserHelper.uncompatible(self) return UserHelper.uncompatible(self)
class VariableClInstallAutoupdateSet(Variable): class VariableClInstallAutoupdateSet(Variable):
""" """
(on or off) autoupdate config from install program for install (on or off) autoupdate config from install program for install
@ -362,120 +377,120 @@ class VariableClInstallAutoupdateSet(Variable):
type = "bool" type = "bool"
value = "off" value = "off"
class VariableOsInstallMakeopts(Variable): class VariableOsInstallMakeopts(Variable):
""" """
Make.conf makeopts Make.conf makeopts
""" """
def get(self): def get(self):
cpunum = self.Get('hr_cpu_num') cpunum = self.Get('hr_cpu_num')
if cpunum == "1": if cpunum == "1":
return "-j1" return "-j1"
else: else:
return "-j%d"%(int(cpunum)+1) return "-j%d" % (int(cpunum) + 1)
class VariableOsGrubConf(ReadonlyVariable): class VariableOsGrubConf(ReadonlyVariable):
""" """
DEPRICATED content of current grub.conf DEPRICATED content of current grub.conf
""" """
class VariableOsInstallGrubDevicemapConf(ReadonlyVariable): class VariableOsInstallGrubDevicemapConf(ReadonlyVariable):
""" """
DEPRICATED content of device.map file for grub DEPRICATED content of device.map file for grub
""" """
os_install_grub_devicemap_conf = {} os_install_grub_devicemap_conf = {}
class VariableClDistfilesPath(Variable): class VariableClDistfilesPath(Variable):
""" """
DISTFILES path DISTFILES path
""" """
value = '/var/calculate/remote/distfiles' value = '/var/calculate/remote/distfiles'
class VariableClPkgdirPath(Variable): class VariableClPkgdirPath(Variable):
""" """
PKGDIR path PKGDIR path
""" """
def get(self): def get(self):
return "/var/calculate/remote/packages/%s/%s" % ( return "/var/calculate/remote/packages/%s/%s" % (
self.Get('os_install_linux_shortname'), self.Get('os_install_linux_shortname'),
self.Get('os_install_arch_machine')) self.Get('os_install_arch_machine'))
class VariableClInstallDevFrom(Variable): class VariableClInstallDevFrom(Variable):
""" """
Root device of previous installed os Root device of previous installed os
""" """
def set(self,value):
def set(self, value):
""" """
If device in calculate3.env dev_from not exists set '' If device in calculate3.env dev_from not exists set ''
""" """
if value: if value:
value = getUdevDeviceInfo(name=value).get('DEVNAME',value) value = getUdevDeviceInfo(name=value).get('DEVNAME', value)
if value in self.Get('os_disk_dev'): if value in self.Get('os_disk_dev'):
return value return value
else: else:
return "" return ""
def get(self): def get(self):
if (self.Get('cl_autopartition_set') == 'on' and if (self.Get('cl_autopartition_set') == 'on' and
"root" in self.Get('cl_autopartition_scheme')): "root" in self.Get('cl_autopartition_scheme')):
return self.Select('cl_autopartition_disk_dev', return self.Select('cl_autopartition_disk_dev',
where='cl_autopartition_disk_scheme',eq='root',limit=1) where='cl_autopartition_disk_scheme', eq='root',
limit=1)
return "" return ""
class VariableClInstallAutoupdateSet(Variable):
"""
Autoupdate for install or configure system
"""
def get_cl_install_autoupdate_set(self):
"""Get autoupdate default value"""
if self.Get('ac_install_system') == "up":
if self.Get('os_install_linux_system') == 'desktop':
return "on"
else:
return "off"
else:
return self.Get('cl_autoupdate_set')
class VariableOsNvidiaMask(ReadonlyVariable): class VariableOsNvidiaMask(ReadonlyVariable):
""" """
Get nvidia card mask versions Get nvidia card mask versions
""" """
def get(self): def get(self):
image = self.Get('cl_image') image = self.Get('cl_image')
try: try:
if image: if image:
image = image.convertToDirectory() image = image.convertToDirectory()
chrootPath = image.getDirectory() chrootPath = image.getDirectory()
chrootPath = image.getDirectory()
else: else:
chrootPath = self.Get("cl_chroot_path") chrootPath = self.Get("cl_chroot_path")
nvidiaeclass = path.join(chrootPath, nvidiaeclass = path.join(chrootPath,
'usr/portage/eclass/nvidia-driver.eclass') 'usr/portage/eclass/nvidia-driver.eclass')
if not os.access(nvidiaeclass,os.R_OK): if not os.access(nvidiaeclass, os.R_OK):
return "" return ""
category = "0300" category = "0300"
vendor = "10de:" vendor = "10de:"
lsPciProg = getProgPath("/usr/sbin/lspci") lsPciProg = getProgPath("/usr/sbin/lspci")
nvidiacards = filter(lambda x:" %s: "%category in x, nvidiacards = filter(lambda x: " %s: " % category in x,
process(lsPciProg,"-d",vendor,"-n")) process(lsPciProg, "-d", vendor, "-n"))
if not nvidiacards: if not nvidiacards:
return "" return ""
cardsid = \ cardsid = \
map(lambda x:x.groups()[0], map(lambda x: x.groups()[0],
filter(lambda x:x, filter(lambda x: x,
map(lambda x:re.search("[0-9a-fA-F]{4}:([0-9a-fA-F]{4})",x), map(lambda x: re.search(
nvidiacards))) "[0-9a-fA-F]{4}:([0-9a-fA-F]{4})", x),
nvidiacards)))
if not cardsid: if not cardsid:
return "" return ""
eclassdata = readFile(nvidiaeclass) eclassdata = readFile(nvidiaeclass)
drv_categories = re.findall('^drv_([^=]+)="', eclassdata, re.M) drv_categories = re.findall('^drv_([^=]+)="', eclassdata, re.M)
drvs = map(lambda x:(x[0],x[1].replace('\\\n','').split()), drvs = map(lambda x: (x[0], x[1].replace('\\\n', '').split()),
re.findall('\ndrv_(%s)="(.*?)"'%"|".join(drv_categories), re.findall(
eclassdata,re.S)) '\ndrv_(%s)="(.*?)"' % "|".join(drv_categories),
eclassdata, re.S))
mask_categories = re.findall('^mask_([^=]+)="', eclassdata, re.M) mask_categories = re.findall('^mask_([^=]+)="', eclassdata, re.M)
masks = dict(map(lambda x:(x[0],x[1].replace('\\\n','')), masks = dict(map(lambda x: (x[0], x[1].replace('\\\n', '')),
re.findall('\nmask_(%s)="(.*?)"'%"|".join(drv_categories), re.findall('\nmask_(%s)="(.*?)"' % "|".join(
eclassdata,re.S))) drv_categories),
drvsForCardsid = filter(lambda x:set(x[1])&set(cardsid),drvs) eclassdata, re.S)))
drvsForCardsid = filter(lambda x: set(x[1]) & set(cardsid), drvs)
if drvsForCardsid and drvsForCardsid[0][0] in masks: if drvsForCardsid and drvsForCardsid[0][0] in masks:
return masks[drvsForCardsid[0][0]] return masks[drvsForCardsid[0][0]]
finally: finally:
@ -483,6 +498,7 @@ class VariableOsNvidiaMask(ReadonlyVariable):
image.close() image.close()
return "" return ""
class VariableOsInstallLvmSet(ReadonlyVariable): class VariableOsInstallLvmSet(ReadonlyVariable):
""" """
Using lvm Using lvm
@ -496,6 +512,7 @@ class VariableOsInstallLvmSet(ReadonlyVariable):
else: else:
return "off" return "off"
class VariableOsInstallMdadmSet(ReadonlyVariable): class VariableOsInstallMdadmSet(ReadonlyVariable):
""" """
Using mdadm Using mdadm
@ -509,23 +526,27 @@ class VariableOsInstallMdadmSet(ReadonlyVariable):
else: else:
return "off" return "off"
class VariableClChrootGrub(ReadonlyVariable): class VariableClChrootGrub(ReadonlyVariable):
""" """
Chroot for grub-mkconfig Chroot for grub-mkconfig
""" """
def get(self): def get(self):
if self.Get('os_install_scratch') == "on": if self.Get('os_install_scratch') == "on":
if self.Get('cl_action') == 'system': if self.Get('cl_action') == 'system':
return self.Get('cl_target').mdirectory return self.Get('cl_target').mdirectory
else: else:
return path.join(self.Get('cl_chroot_path'),"mnt/scratch") return path.join(self.Get('cl_chroot_path'), "mnt/scratch")
else: else:
return self.Get('cl_chroot_path') return self.Get('cl_chroot_path')
class VariableOsGrub2Path(Variable): class VariableOsGrub2Path(Variable):
""" """
Get Grub2 Install cmd (grub-install or grub2-install) Get Grub2 Install cmd (grub-install or grub2-install)
""" """
def get(self): def get(self):
# find grub2-install # find grub2-install
grubInstall = getProgPath('/usr/sbin/grub2-install') grubInstall = getProgPath('/usr/sbin/grub2-install')
@ -533,11 +554,12 @@ class VariableOsGrub2Path(Variable):
return grubInstall return grubInstall
# find grub-install and check, that this is grub2-install (ver 1.99) # find grub-install and check, that this is grub2-install (ver 1.99)
grubInstall = getProgPath('/usr/sbin/grub-install') grubInstall = getProgPath('/usr/sbin/grub-install')
if grubInstall and filter(lambda x:"1.99" in x or "2." in x, if grubInstall and filter(lambda x: "1.99" in x or "2." in x,
process(grubInstall,'--version')): process(grubInstall, '--version')):
return grubInstall return grubInstall
return "" return ""
class VariableClSetup(Variable): class VariableClSetup(Variable):
""" """
Type of setup Type of setup
@ -557,13 +579,14 @@ class VariableClSetup(Variable):
'audio': _("audio parameters"), 'audio': _("audio parameters"),
'session': _("session settings"), 'session': _("session settings"),
'users': _("user settings")} 'users': _("user settings")}
return mapType.get(self.Get(),"") return mapType.get(self.Get(), "")
def check(self,value): def check(self, value):
if value == "boot" and self.Get('os_install_root_type') == 'livecd': if value == "boot" and self.Get('os_install_root_type') == 'livecd':
raise VariableError( raise VariableError(
_("Boot configuration is not available on a LiveCD")) _("Boot configuration is not available on a LiveCD"))
class VariableClLive(Variable): class VariableClLive(Variable):
""" """
Apply live templates Apply live templates
@ -576,6 +599,7 @@ class VariableClLive(Variable):
self.label = _("Configure dynamic options only") self.label = _("Configure dynamic options only")
self.help = _("configure dynamic options only") self.help = _("configure dynamic options only")
class VariableOsInstallPxe(Variable): class VariableOsInstallPxe(Variable):
""" """
Installation for PXE loading Installation for PXE loading
@ -584,25 +608,29 @@ class VariableOsInstallPxe(Variable):
value = "off" value = "off"
untrusted = True untrusted = True
def check(self,value): def check(self, value):
if value == "on": if value == "on":
if self.Get('os_linux_system') != "server": if self.Get('os_linux_system') != "server":
raise VariableError( raise VariableError(
_("PXE install is available for Calculate Directory Server only")+'.') _("PXE install is available for Calculate "
for pkg in ['net-misc/dhcp','net-ftp/tftp-hpa','net-fs/nfs-utils']: "Directory Server only") + '.')
for pkg in ['net-misc/dhcp', 'net-ftp/tftp-hpa',
'net-fs/nfs-utils']:
if not isPkgInstalled(pkg): if not isPkgInstalled(pkg):
raise VariableError( raise VariableError(
_("For PXE install, you need to install package %s") _("For PXE install, you need to install package %s")
%pkg) % pkg)
try: try:
config = cl_template.iniParser('/etc/calculate/calculate.env') config = cl_ini_parser.iniParser('/etc/calculate/calculate.env')
val = config.getVar('server','sr_dhcp_set') val = config.getVar('server', 'sr_dhcp_set')
if val.encode('utf-8') == "on": if val.encode('utf-8') == "on":
return return
except: except Exception:
pass pass
raise VariableError( raise VariableError(
_("PXE install is only available if the DHCP service has been configured first")) _("PXE install is only available if the DHCP "
"service has been configured first"))
class VariableOsInstallPxePath(Variable): class VariableOsInstallPxePath(Variable):
""" """
@ -616,11 +644,12 @@ class VariableOsInstallPxePath(Variable):
self.label = _("Installation path") self.label = _("Installation path")
self.help = _("path for PXE install") self.help = _("path for PXE install")
class VariableOsInstallUefiSet(Variable): class VariableOsInstallUefiSet(Variable):
""" """
Install in UEFI Install in UEFI
""" """
type = "bool" type = "bool"
opt = ['--uefi'] opt = ['--uefi']
def init(self): def init(self):
@ -632,24 +661,24 @@ class VariableOsInstallUefiSet(Variable):
return self.Get('cl_autopartition_uefi_set') return self.Get('cl_autopartition_uefi_set')
else: else:
if self.Get('os_install_disk_efi') or \ if self.Get('os_install_disk_efi') or \
"/boot/efi" in self.Get('os_location_dest'): "/boot/efi" in self.Get('os_location_dest'):
if self.Get('os_install_arch_machine') == 'x86_64' and \ if self.Get('os_install_arch_machine') == 'x86_64' and \
self.Get('os_install_root_type') != 'flash': self.Get('os_install_root_type') != 'flash':
return self.Get('os_uefi_set') return self.Get('os_uefi_set')
return 'off' return 'off'
def check(self,value): def check(self, value):
if value == 'on': if value == 'on':
if self.Get('os_uefi_set') == 'off' and \ if self.Get('os_uefi_set') == 'off' and \
self.Get('os_install_root_type') == 'hdd': self.Get('os_install_root_type') == 'hdd':
raise VariableError( raise VariableError(
_("Your system must be loaded in UEFI for using this " _("Your system must be loaded in UEFI for using this "
"bootloader")) "bootloader"))
if not 'gpt' in self.Get('os_device_table'): if not 'gpt' in self.Get('os_device_table'):
raise VariableError( raise VariableError(
_("GPT is needed for using the UEFI bootloader")) _("GPT is needed for using the UEFI bootloader"))
if not (self.Get('os_install_disk_efi') or \ if not (self.Get('os_install_disk_efi') or
"/boot/efi" in self.Get('os_location_dest')): "/boot/efi" in self.Get('os_location_dest')):
raise VariableError( raise VariableError(
_("A EF00 partition is needed for using " _("A EF00 partition is needed for using "
"the UEFI bootloader")) "the UEFI bootloader"))
@ -672,20 +701,22 @@ class VariableOsInstallUefiSet(Variable):
_("This option not used for Flash install") _("This option not used for Flash install")
return "" return ""
class VariableOsInstallUefiBriefSet(VariableOsInstallUefiSet): class VariableOsInstallUefiBriefSet(VariableOsInstallUefiSet):
def uncompatible(self): def uncompatible(self):
if self.Get('os_install_root_type') == 'flash': if self.Get('os_install_root_type') == 'flash':
return _("This option not used for Flash install") return _("This option not used for Flash install")
return "" return ""
def get(self): def get(self):
return self.Get('os_install_uefi_set') return self.Get('os_install_uefi_set')
class VariableOsInstallGrubTerminal(Variable): class VariableOsInstallGrubTerminal(Variable):
""" """
Gfxmode Gfxmode
""" """
type = "choice" type = "choice"
opt = ['--grub-terminal'] opt = ['--grub-terminal']
metavalue = "TERMINAL" metavalue = "TERMINAL"
@ -699,16 +730,16 @@ class VariableOsInstallGrubTerminal(Variable):
return 'console' return 'console'
grubDefault = path.join(self.Get('cl_chroot_path'), grubDefault = path.join(self.Get('cl_chroot_path'),
'etc/default/grub') 'etc/default/grub')
if getValueFromConfig(grubDefault,'GRUB_TERMINAL') == 'console': if getValueFromConfig(grubDefault, 'GRUB_TERMINAL') == 'console':
return 'console' return 'console'
grubCfg = '/boot/grub/grub.cfg' grubCfg = '/boot/grub/grub.cfg'
if re.search('^terminal_output\s*console',readFile(grubCfg),re.M): if re.search('^terminal_output\s*console', readFile(grubCfg), re.M):
return 'console' return 'console'
return 'gfxterm' return 'gfxterm'
def choice(self): def choice(self):
return ['gfxterm','console'] return ['gfxterm', 'console']
def uncompatible(self): def uncompatible(self):
""" """
@ -718,7 +749,8 @@ class VariableOsInstallGrubTerminal(Variable):
return _("Grub configuration unavailable for Flash install") return _("Grub configuration unavailable for Flash install")
return "" return ""
class PackageCheckHelper(ReadonlyVariable):
class PackageCheckVariable(ReadonlyVariable):
""" """
Конструктор для переменных проверки установлен ли пакет Конструктор для переменных проверки установлен ли пакет
""" """
@ -735,25 +767,26 @@ class PackageCheckHelper(ReadonlyVariable):
if image: if image:
with image as distr: with image as distr:
distrPath = image.getDirectory() distrPath = image.getDirectory()
if isPkgInstalled(self.package,prefix=distrPath): if isPkgInstalled(self.package, prefix=distrPath):
return "on" return "on"
else: else:
prefix = self.Get(self.prefix_variable) prefix = self.Get(self.prefix_variable)
if isPkgInstalled(self.package, prefix=prefix): if isPkgInstalled(self.package, prefix=prefix):
return "on" return "on"
except: except Exception:
pass pass
return "off" return "off"
class VariableOsInstallAlsaSet(PackageCheckHelper): class VariableOsInstallAlsaSet(PackageCheckVariable):
""" """
Установлен ли media-sound/alsa-utils Установлен ли media-sound/alsa-utils
""" """
image = True image = True
package = "media-sound/alsa-utils" package = "media-sound/alsa-utils"
class VariableOsInstallX11ServerSet(PackageCheckHelper):
class VariableOsInstallX11ServerSet(PackageCheckVariable):
""" """
Установлен ли x11-base/xorg-server Установлен ли x11-base/xorg-server
""" """
@ -761,7 +794,7 @@ class VariableOsInstallX11ServerSet(PackageCheckHelper):
package = "x11-base/xorg-server" package = "x11-base/xorg-server"
class FlashUncompatible: class FlashUncompatible(VariableInterface):
def uncompatible(self): def uncompatible(self):
""" """
Update setting up unavailable for flash installation Update setting up unavailable for flash installation
@ -771,6 +804,7 @@ class FlashUncompatible:
_("Update configuration unavailable for Flash install") _("Update configuration unavailable for Flash install")
return "" return ""
try: try:
import calculate.update.variables.update as update import calculate.update.variables.update as update
@ -780,21 +814,23 @@ try:
return self.Get('update.cl_update_autocheck_set') return self.Get('update.cl_update_autocheck_set')
class VariableClInstallAutocheckInterval(FlashUncompatible, class VariableClInstallAutocheckInterval(FlashUncompatible,
update.VariableClUpdateAutocheckInterval): update.VariableClUpdateAutocheckInterval):
def get(self): def get(self):
return self.Get('update.cl_update_autocheck_interval') return self.Get('update.cl_update_autocheck_interval')
class VariableClInstallCleanpkgSet(FlashUncompatible, class VariableClInstallCleanpkgSet(FlashUncompatible,
update.VariableClUpdateCleanpkgSet): update.VariableClUpdateCleanpkgSet):
def get(self): def get(self):
return self.Get('update.cl_update_cleanpkg_set') return self.Get('update.cl_update_cleanpkg_set')
class VariableClInstallOtherSet(FlashUncompatible, class VariableClInstallOtherSet(FlashUncompatible,
update.VariableClUpdateOtherSet): update.VariableClUpdateOtherSet):
def get(self): def get(self):
return self.Get('update.cl_update_other_set') return self.Get('update.cl_update_other_set')
except ImportError: except ImportError:
update = None
class VariableClInstallAutocheckSet(FlashUncompatible, Variable): class VariableClInstallAutocheckSet(FlashUncompatible, Variable):
value = "off" value = "off"

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,287 +14,325 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import sys, time, os import sys
from calculate.lib.datavars import VariableError,DataVarsError,DataVars from calculate.lib.datavars import VariableError, DataVarsError
from calculate.install.install import InstallError
from calculate.install.distr import DistributiveError from calculate.install.distr import DistributiveError
import install import install
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
setLocalTranslate('cl_install3',sys.modules[__name__])
setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
from calculate.core.server.func import WsdlBase from calculate.core.server.func import WsdlBase
from calculate.install.utils.cl_install import ClInstallAction from calculate.install.utils.cl_install import ClInstallAction
from calculate.install.utils.cl_setup import (ClSetupAudioAction, from calculate.install.utils.cl_setup import (
ClSetupLocaleAction,ClSetupVideoAction,ClSetupSystemAction, ClSetupLocaleAction, ClSetupVideoAction, ClSetupSystemAction,
ClSetupBootAction,ClSetupNetworkAction, ClSetupBootAction, ClSetupNetworkAction,
ClSetupSessionAction) ClSetupSessionAction)
class Wsdl(WsdlBase): class Wsdl(WsdlBase):
methods = [{ methods = [{
# идентификатор метода # идентификатор метода
'method_name':"install", 'method_name': "install",
# категория метода # категория метода
'category':__("Installation"), 'category': __("Installation"),
# заголовок метода # заголовок метода
'title':__("System Install"), 'title': __("System Install"),
# иконка для графической консоли # иконка для графической консоли
'image':'calculate-install,system-installer,applications-other,'\ 'image': ('calculate-install,system-installer,applications-other,'
'drive-harddisk', 'drive-harddisk'),
# метод присутствует в графической консоли # метод присутствует в графической консоли
'gui':True, 'gui': True,
# консольная команда # консольная команда
'command':'cl-install', 'command': 'cl-install',
# права для запуска метода # права для запуска метода
'rights':['install'], 'rights': ['install'],
# объект содержащий модули для действия # объект содержащий модули для действия
'logic':{'Install':install.Install}, 'logic': {'Install': install.Install},
# описание действия # описание действия
'action':ClInstallAction, 'action': ClInstallAction,
# объект переменных # объект переменных
'datavars':"install", 'datavars': "install",
'native_error':(VariableError,DistributiveError, 'native_error': (VariableError, DistributiveError,
DataVarsError,install.InstallError), DataVarsError, install.InstallError),
# значения по умолчанию для переменных этого метода # значения по умолчанию для переменных этого метода
'setvars':{'cl_action!':'system','cl_dispatch_conf':'usenew'}, 'setvars': {'cl_action!': 'system', 'cl_dispatch_conf': 'usenew'},
# описание груп (список лямбда функций) # описание груп (список лямбда функций)
'groups': [ 'groups': [
lambda group:group(_("Language and locale"), lambda group: group(_("Language and locale"),
image="welcome", image="welcome",
normal=('os_install_locale_lang','os_install_clock_timezone')), normal=('os_install_locale_lang',
lambda group:group(_("Distribution"), 'os_install_clock_timezone')),
normal=('cl_image_filename',), lambda group: group(_("Distribution"),
hide=('cl_image_linux_shortname','cl_image_arch_machine', normal=('cl_image_filename',),
'cl_image_new_only'), hide=('cl_image_linux_shortname',
expert=('cl_image_linux_shortname', 'cl_image_arch_machine', 'cl_image_arch_machine',
'cl_image_new_only')), 'cl_image_new_only'),
lambda group:group(_("Allocate drive space"), expert=('cl_image_linux_shortname',
normal=('cl_autopartition_set',), 'cl_image_arch_machine',
hide=('cl_autopartition_set',), 'cl_image_new_only')),
brief=('cl_autopartition_brief_set',), lambda group: group(_("Allocate drive space"),
expert=('cl_autopartition_scheme', normal=('cl_autopartition_set',),
'cl_autopartition_table','cl_autopartition_root_size', hide=('cl_autopartition_set',),
'cl_autopartition_swap_size', brief=('cl_autopartition_brief_set',),
'cl_autopartition_device'), expert=('cl_autopartition_scheme',
expert_label=_("Click to set up autopartition options")), 'cl_autopartition_table',
lambda group:group(_("Mount points"), 'cl_autopartition_root_size',
normal=('os_location_data',), 'cl_autopartition_swap_size',
hide=('os_location_data','os_install_mbr','os_install_uefi_set'), 'cl_autopartition_device'),
brief_force=('os_location_brief_data','os_install_bootloader'), expert_label=_(
brief=('os_install_uefi_brief_set',), "Click to set up autopartition options")),
expert=('cl_uuid_set', lambda group: group(_("Mount points"),
'os_install_root_type', normal=('os_location_data',),
'os_install_mbr', hide=('os_location_data', 'os_install_mbr',
'os_install_uefi_set', 'os_install_uefi_set'),
'os_install_kernel_scheduler')), brief_force=('os_location_brief_data',
lambda group:group(_("Network settings"), 'os_install_bootloader'),
normal=('os_install_net_conf','os_install_net_data', brief=('os_install_uefi_brief_set',),
'os_install_net_fqdn','os_install_ntp'), expert=('cl_uuid_set',
expert=('os_install_net_dns','os_install_net_dns_search', 'os_install_root_type',
'os_install_net_route_data')), 'os_install_mbr',
lambda group:group(_("Users"), 'os_install_uefi_set',
normal=('cl_migrate_root_pwd','cl_migrate_data','cl_autologin'), 'os_install_kernel_scheduler')),
expert=('cl_install_home_crypt_set',), lambda group: group(_("Network settings"),
hide=('cl_migrate_data',), normal=(
brief=('cl_migrate_data_brief',)), 'os_install_net_conf',
lambda group:group(_("Video"), 'os_install_net_data',
normal=('os_install_x11_video_drv','os_install_x11_composite', 'os_install_net_fqdn', 'os_install_ntp'),
'os_install_x11_resolution','os_install_fb_resolution', expert=('os_install_net_dns',
'os_install_grub_terminal')), 'os_install_net_dns_search',
'os_install_net_route_data')),
lambda group: group(_("Users"),
normal=(
'cl_migrate_root_pwd', 'cl_migrate_data',
'cl_autologin'),
expert=('cl_install_home_crypt_set',),
hide=('cl_migrate_data',),
brief=('cl_migrate_data_brief',)),
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')),
lambda group: group(_("Update"), lambda group: group(_("Update"),
normal=('cl_install_autocheck_set', normal=('cl_install_autocheck_set',
'cl_install_autocheck_interval', 'cl_install_autocheck_interval',
'cl_install_cleanpkg_set', 'cl_install_cleanpkg_set',
'cl_install_other_set'))], 'cl_install_other_set'))],
# действие выводит информацию перед запуском # действие выводит информацию перед запуском
'brief':{'next':__("Perform"), 'brief': {'next': __("Perform"),
'image':'finish', 'image': 'finish',
'name':__("Start installing")}}, 'name': __("Start installing")}},
# установка на Flash # установка на Flash
{ {
'method_name': "install_flash", 'method_name': "install_flash",
'category': __("Installation"), 'category': __("Installation"),
'title': __("Flash Install"), 'title': __("Flash Install"),
'image': ('drive-removable-media-usb-pendrive,' 'image': ('drive-removable-media-usb-pendrive,'
'drive-removable-media-usb,media-flash'), 'drive-removable-media-usb,media-flash'),
'gui':True, 'gui': True,
'rights':['install'], 'rights': ['install'],
'logic':{'Install':install.Install}, 'logic': {'Install': install.Install},
'action':ClInstallAction, 'action': ClInstallAction,
'datavars':"install", 'datavars': "install",
'native_error':(VariableError,DistributiveError, 'native_error': (VariableError, DistributiveError,
DataVarsError,install.InstallError), DataVarsError, install.InstallError),
'setvars':{'cl_action!':'system','cl_install_type':'flash', 'setvars': {'cl_action!': 'system', 'cl_install_type': 'flash',
'cl_protect_use_set!':'off', 'cl_protect_use_set!': 'off',
'cl_dispatch_conf':'usenew'}, 'cl_dispatch_conf': 'usenew'},
'groups':[ 'groups': [
lambda group:group(_("Flash install"), lambda group: group(_("Flash install"),
normal=('os_install_disk_single','cl_image_filename'), normal=('os_install_disk_single',
expert=('os_location_data',), 'cl_image_filename'),
next_label=_("Perform"))]}, expert=('os_location_data',),
next_label=_("Perform"))]},
# PXE установка # PXE установка
{ {
'method_name':"install_pxe", 'method_name': "install_pxe",
'category':__("Installation"), 'category': __("Installation"),
'title':__("PXE Install"), 'title': __("PXE Install"),
'image':('gnome-network-properties,network-server,' 'image': ('gnome-network-properties,network-server,'
'preferences-desktop-remote-desktop'), 'preferences-desktop-remote-desktop'),
'command':'cl-install-pxe', 'command': 'cl-install-pxe',
'gui':True, 'gui': True,
'rights':['installpxe'], 'rights': ['installpxe'],
'logic':{'Install':install.Install}, 'logic': {'Install': install.Install},
'action':ClInstallAction, 'action': ClInstallAction,
'datavars':"install", 'datavars': "install",
'native_error':(VariableError,DistributiveError, 'native_error': (VariableError, DistributiveError,
DataVarsError,install.InstallError), DataVarsError, install.InstallError),
'setvars':{'cl_action!':'system','os_install_pxe':'on', 'setvars': {'cl_action!': 'system', 'os_install_pxe': 'on',
'cl_protect_use_set!':'off', 'cl_protect_use_set!': 'off',
'cl_dispatch_conf':'usenew'}, 'cl_dispatch_conf': 'usenew'},
# действие выводит информацию перед запуском # действие выводит информацию перед запуском
'brief':{'next':__("Installation"), 'brief': {'next': __("Installation"),
'image':'finish', 'image': 'finish',
'name':__("Start installing")}, 'name': __("Start installing")},
'groups':[ 'groups': [
lambda group:group(_("PXE install"), lambda group: group(_("PXE install"),
normal=('cl_image_filename',), normal=('cl_image_filename',),
expert=('os_install_pxe_path', expert=('os_install_pxe_path',
'os_install_pxe_ip'), 'os_install_pxe_ip'),
next_label=_("Perform"))]}, next_label=_("Perform"))]},
# настройка загрузки системы # настройка загрузки системы
{ {
'method_name':"setup_boot", 'method_name': "setup_boot",
'category':__("Configuration"), 'category': __("Configuration"),
'title':__("Boot"), 'title': __("Boot"),
'image':'stock_save,drive-harddisk', 'image': 'stock_save,drive-harddisk',
'command':'cl-setup-boot', 'command': 'cl-setup-boot',
'gui':True, 'gui': True,
'rights':['setupboot'], 'rights': ['setupboot'],
'logic':{'Install':install.Install}, 'logic': {'Install': install.Install},
'action':ClSetupBootAction, 'action': ClSetupBootAction,
'datavars':"install", 'datavars': "install",
'native_error':(VariableError,DataVarsError,install.InstallError), 'native_error': (
'setvars':{'cl_action!':'merge','cl_merge_pkg!':[None], VariableError, DataVarsError, install.InstallError),
'cl_merge_set!':"on",'cl_setup':'boot'}, 'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'groups':[ 'cl_merge_set!': "on", 'cl_setup': 'boot'},
lambda group:group(_("Boot"), 'groups': [
normal=('os_install_mbr','os_install_uefi_set', lambda group: group(_("Boot"),
'os_install_kernel_scheduler', normal=(
'os_install_grub_terminal'), 'os_install_mbr', 'os_install_uefi_set',
expert=('cl_templates_locate','cl_dispatch_conf', 'os_install_kernel_scheduler',
'cl_verbose_set'), 'os_install_grub_terminal'),
next_label=_("Save"))]}, expert=(
'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
{ {
# настройка сети # настройка сети
'method_name':"setup_network", 'method_name': "setup_network",
'category':__("Configuration"), 'category': __("Configuration"),
'title':__("Network"), 'title': __("Network"),
'image':'network-workgroup,' 'image': 'network-workgroup,'
'network-idle,preferences-system-network', 'network-idle,preferences-system-network',
'command':'cl-setup-network', 'command': 'cl-setup-network',
'gui':True, 'gui': True,
'rights':['setupnetwork'], 'rights': ['setupnetwork'],
'logic':{'Install':install.Install}, 'logic': {'Install': install.Install},
'action':ClSetupNetworkAction, 'action': ClSetupNetworkAction,
'datavars':"install", 'datavars': "install",
'native_error':(VariableError,DataVarsError,install.InstallError), 'native_error': (
'setvars':{'cl_action!':'merge','cl_merge_pkg!':[None], VariableError, DataVarsError, install.InstallError),
'cl_merge_set!':"on",'cl_setup':'network'}, 'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'groups':[ 'cl_merge_set!': "on", 'cl_setup': 'network'},
lambda group:group(_("Network"), 'groups': [
normal=('os_install_net_conf','os_install_net_data', lambda group: group(_("Network"),
'os_install_net_fqdn','os_install_ntp'), normal=('os_install_net_conf',
expert=('os_install_net_dns','os_install_net_dns_search', 'os_install_net_data',
'os_install_net_route_data', 'os_install_net_fqdn',
'cl_templates_locate','cl_dispatch_conf', 'os_install_ntp'),
'cl_verbose_set'), expert=('os_install_net_dns',
next_label=_("Save"))]}, 'os_install_net_dns_search',
'os_install_net_route_data',
'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
{ {
# перенастройка системы # перенастройка системы
'method_name':"setup_system", 'method_name': "setup_system",
'category':__("Configuration"), 'category': __("Configuration"),
'title':__("System"), 'title': __("System"),
'image':'run-build,applications-ide,system-run,system,computer', 'image': 'run-build,applications-ide,system-run,system,computer',
'command':'cl-setup-system', 'command': 'cl-setup-system',
'gui':True, 'gui': True,
'rights':['setupsystem'], 'rights': ['setupsystem'],
'logic':{'Install':install.Install}, 'logic': {'Install': install.Install},
'action':ClSetupSystemAction, 'action': ClSetupSystemAction,
'datavars':"install", 'datavars': "install",
'native_error':(VariableError,DataVarsError,install.InstallError), 'native_error': (
'setvars':{'cl_action!':'merge','cl_live':'off'}, VariableError, DataVarsError, install.InstallError),
'groups':[ 'setvars': {'cl_action!': 'merge', 'cl_live': 'off'},
lambda group:group(_("Update system settings"), 'groups': [
normal=('cl_live',), lambda group: group(_("Update system settings"),
expert=('cl_templates_locate','cl_dispatch_conf', normal=('cl_live',),
'cl_verbose_set'), expert=(
next_label=_("Save"))]}, 'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
{ {
# настройка видео # настройка видео
'method_name':"setup_video", 'method_name': "setup_video",
'category':__("Configuration"), 'category': __("Configuration"),
'title':__("Video"), 'title': __("Video"),
'image':'system-config-display,video-display,gnome-multimedia', 'image': 'system-config-display,video-display,gnome-multimedia',
'command':'cl-setup-video', 'command': 'cl-setup-video',
'gui':True, 'gui': True,
'rights':['setupvideo'], 'rights': ['setupvideo'],
'logic':{'Install':install.Install}, 'logic': {'Install': install.Install},
'action':ClSetupVideoAction, 'action': ClSetupVideoAction,
'datavars':"install", 'datavars': "install",
'native_error':(VariableError,DataVarsError,install.InstallError), 'native_error': (
'setvars':{'cl_action!':'merge','cl_merge_pkg!':[None], VariableError, DataVarsError, install.InstallError),
'cl_merge_set!':"on",'cl_setup':'video'}, 'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'groups':[ 'cl_merge_set!': "on", 'cl_setup': 'video'},
lambda group:group(_("Video"), 'groups': [
normal=('os_install_x11_video_drv', lambda group: group(_("Video"),
'os_install_x11_resolution', normal=('os_install_x11_video_drv',
'os_install_x11_composite', 'os_install_x11_resolution',
'os_install_fb_resolution'), 'os_install_x11_composite',
expert=('cl_templates_locate','cl_dispatch_conf', 'os_install_fb_resolution'),
'cl_verbose_set'), expert=(
next_label=_("Save"))]}, 'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
{ {
# настройка локали # настройка локали
'method_name':"setup_locale", 'method_name': "setup_locale",
'category':__("Configuration"), 'category': __("Configuration"),
'title':__("Locale"), 'title': __("Locale"),
'image':'locale,preferences-desktop-locale', 'image': 'locale,preferences-desktop-locale',
'command':'cl-setup-locale', 'command': 'cl-setup-locale',
'gui':True, 'gui': True,
'rights':['setuplocale'], 'rights': ['setuplocale'],
'logic':{'Install':install.Install}, 'logic': {'Install': install.Install},
'action':ClSetupLocaleAction, 'action': ClSetupLocaleAction,
'datavars':"install", 'datavars': "install",
'native_error':(VariableError,DataVarsError,install.InstallError), 'native_error': (
'setvars':{'cl_action!':'merge','cl_merge_pkg!':[None], VariableError, DataVarsError, install.InstallError),
'cl_merge_set!':"on",'cl_setup':'locale'}, 'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'groups':[ 'cl_merge_set!': "on", 'cl_setup': 'locale'},
lambda group:group(_("Locale"), 'groups': [
normal=('os_install_locale_lang', lambda group: group(_("Locale"),
'os_install_clock_timezone'), normal=('os_install_locale_lang',
expert=('cl_templates_locate','cl_dispatch_conf', 'os_install_clock_timezone'),
'cl_verbose_set'), expert=(
next_label=_("Save"))]}, 'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
{ {
# настройка локали # настройка локали
'method_name':"setup_session", 'method_name': "setup_session",
'category':__("Configuration"), 'category': __("Configuration"),
'title':__("Session"), 'title': __("Session"),
'image':'system-lock-screen', 'image': 'system-lock-screen',
'command':'cl-setup-session', 'command': 'cl-setup-session',
'gui':True, 'gui': True,
'rights':['setupsession'], 'rights': ['setupsession'],
'logic':{'Install':install.Install}, 'logic': {'Install': install.Install},
'action':ClSetupSessionAction, 'action': ClSetupSessionAction,
'datavars':"install", 'datavars': "install",
'native_error':(VariableError,DataVarsError,install.InstallError), 'native_error': (
'setvars':{'cl_action!':'merge','cl_merge_pkg!':[None], VariableError, DataVarsError, install.InstallError),
'cl_merge_set!':"on",'cl_setup':'session'}, 'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'groups':[ 'cl_merge_set!': "on", 'cl_setup': 'session'},
lambda group:group(_("Session"), 'groups': [
normal=('cl_autologin', 'cl_install_home_crypt_set'), lambda group: group(_("Session"),
expert=('cl_templates_locate','cl_dispatch_conf', normal=('cl_autologin',
'cl_verbose_set'), 'cl_install_home_crypt_set'),
next_label=_("Save"))]} expert=(
] 'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]}
]

Loading…
Cancel
Save