Added installation to flash.

Performed refactoring installSystem method.
netsetup
Mike Hiretsky 14 years ago
parent 8969c46978
commit 1ff933dc40

@ -431,6 +431,9 @@ class Distributive(object):
" '%s' " %fromdir + _("to") +\
" '%s':\n%s" %(todir,errmes))
def performFormat(self):
pass
def formatPartition(self,format=""):
pass
@ -585,7 +588,7 @@ class PartitionDistributive(Distributive):
'jfs':'/sbin/mkfs.jfs -f %s',
'reiserfs':'/sbin/mkfs.reiserfs -f %s',
'xfs':'/sbin/mkfs.xfs -f %s',
'vfat':'/sbin/mkfs.vfat -F 32 %s',
'vfat':'/usr/sbin/mkfs.vfat -F 32 %s',
'swap':'/sbin/mkswap %s'
}
@ -756,6 +759,13 @@ class PartitionDistributive(Distributive):
raise DistributiveError(_("Cann't format partition") + " %s:\n%s"%
(dev,errmes))
def performFormat(self):
"""Perform format for all partition of this distributive"""
if self.multipartition:
self.formatAllPartitions()
elif self.isFormat:
self.formatPartition(self.partition,format=self.fileSystem)
def changeSystemID(self,dev,systemid):
parentDir = os.path.split(dev)[0]
def detectDeviceForPartition(dev):
@ -968,7 +978,7 @@ class IsoDistributive(Distributive):
def getIsoContentDirectory(self):
"""Return directory with content of iso image"""
squash = convertToSquash()
squash = self.convertToSquash()
return pathdirname(squash.file)
def releaseChild(self,child):
@ -1046,30 +1056,14 @@ class FlashDistributive(PartitionDistributive):
"""Install distributive to partition from source distributive"""
# make temporary directory for creating iso image
distrTo = self.convertToDirectory()
try:
# getting squash from source
if isinstance(source,IsoDistributive):
self.copy(getIsoContentDirectory(),distrTo.directory)
else:
distDirectory = source.convertToDirectory()
squashDistr = SquashDistributive(
pathjoin(isoDirectory,"livecd.squashfs"))
squashDistr.installFrom(distDirectory)
import ipdb
ipdb.set_trace()
# prepare iso
self.prepareIso(directory)
# pack iso
self.packToIso(isoDirectory, self.file)
# remove temporary directory after creating iso image
self._removeDirectory(isoDirectory)
except DistributiveError,e:
self._removeDirectory(isoDirectory)
raise e
except KeyboardInterrupt,e:
self._removeDirectory(isoDirectory)
raise DistributiveError(_("Keyboard interrupt"))
# getting squash from source
if isinstance(source,IsoDistributive):
self.copy(source.getIsoContentDirectory(),distrTo.directory)
else:
distDirectory = source.convertToDirectory()
squashDistr = SquashDistributive(
pathjoin(isoDirectory,"livecd.squashfs"))
squashDistr.installFrom(distDirectory)
class ScratchDistributive(Distributive):
def __init__(self,directory,parent=None,mdirectory="/mnt/install",

@ -994,7 +994,8 @@ class fillVars(object, glob_attr):
def get_os_format_type(self):
"""Filesystem format support by calcualte-install"""
return filter(lambda x:not x in ("default","noformat"),
return filter(lambda x:not x in ("default","noformat") and
x in convertDictOpt._fileSystemOpt,
filter(lambda x:not x.startswith("_"),
convertDictOpt._fileSystemOpt.keys())+\
convertDictOpt._propertiesFileSystem.keys())
@ -1026,7 +1027,15 @@ class fillVars(object, glob_attr):
return res[0][0]
def get_os_install_mbr(self):
if self.Get('os_device_dev'):
if self.Get('os_install_root_type') == "flash":
rootdev = self.Get('os_install_root_dev')
device = filter(lambda x:x in rootdev,
self.Get('os_device_dev'))
if device:
return device[0]
else:
return ""
elif self.Get('os_device_dev'):
return self.Get('os_device_dev')[0]
else:
return ""

@ -91,6 +91,7 @@ class convertDictOpt:
"""Convert dict install option"""
_defaultFS = "reiserfs"
_defaultFlashFS = "vfat"
_diskDefaultMountPoints = { "default":{"fileSystem":_defaultFS,
"isFormat":False,
@ -118,6 +119,9 @@ class convertDictOpt:
"options":[]},
"noformat":{"fileSystem":"",
"isFormat":False,
"options":[]},
"defaultflash":{"fileSystem":_defaultFlashFS,
"isFormat":True,
"options":[]}}
_ext2Options = {"options":["acl", "noacl", "bsddf", "minixdf", "check",
@ -352,7 +356,7 @@ class convertDictOpt:
self._propertiesFileSystem.keys()
def getAllAvailableFileSystemOpt(self):
return filter(lambda x: x in ("default","noformat") or
return filter(lambda x: x in ("default","noformat","defaultflash") or
(not "makefs" in self._fileSystemOpt[x] or
pathexists(self._fileSystemOpt[x]["makefs"])),
self.getAllSupportFileSystemOpt())
@ -494,10 +498,14 @@ class convertDictOpt:
"""Get zip() the value of the variable name"""
return zip(*map(self.clVars.Get, argvVarNames))
def getDefaultOptFileSystem(self, fileSystem):
def getDefaultOptFileSystem(self, fileSystem, devicetype="hdd"):
"""Get default properties for fileSystem"""
if not fileSystem in self._propertiesFileSystem:
fileSystem="default"
if devicetype == "flash" and fileSystem=="default":
fileSystem="defaultflash"
if devicetype != "flash" and fileSystem=="defaultflash":
fileSystem="default"
propertiesFileSystem = self._propertiesFileSystem.copy()
return propertiesFileSystem[fileSystem]
@ -519,6 +527,14 @@ class convertDictOpt:
"""Get default properties for swap"""
return self._bindDefaultMountPoint
def _getDeviceType(self,dev):
"""Get device type, considing given by user param"""
oldRootDev = self.clVars.Get('os_install_root_dev')
self.clVars.Set('os_install_root_dev',dev,True)
rootType = self.clVars.Get('os_install_root_type')
self.clVars.Set('os_install_root_dev',oldRootDev,True)
return rootType
def __call__(self, optionsDict={}):
"""Convert dict options (bind options, swap options or disk options)"""
optProperties = optionsDict.copy()
@ -548,7 +564,12 @@ class convertDictOpt:
dictUpdateProperty["mountPoint"] = optMountPoint
supportedFS = self.getAllSupportFileSystemOpt()
if optMountPoint == "/":
excludeFS = set(["vfat"])
# check install type (flash or hdd)
if self._getDeviceType(dev) != "flash":
excludeFS = set(["vfat"])
else:
excludeFS = set(supportedFS) - \
set(["vfat","noformat","default"])
else:
excludeFS = set([])
availableFS = self.getAllAvailableFileSystemOpt()
@ -569,19 +590,27 @@ class convertDictOpt:
raise InstallError(_("File system '%s' is not available")\
%optFileSystem)
if optFileSystem in excludeFS:
mp = optMountPoint
if mp == '/' and self._getDeviceType(dev) == "flash":
mp = "flash"
raise InstallError(
_("File system for '%s' should not be '%s'")
%(optMountPoint, optFileSystem))
%(mp, optFileSystem))
if not "fileSystem" in dictOptions or optFileSystem == "default":
dictOptions.update(self.getDefaultOptFileSystem(optFileSystem))
dictOptions.update(
self.getDefaultOptFileSystem(optFileSystem,
self._getDeviceType(dev)))
if optFileSystem == "noformat":
if not format:
raise InstallError(\
_("Partition %s is not formatted")%dev)
elif format in excludeFS:
mp = optMountPoint
if mp == '/' and self._getDeviceType(dev) == "flash":
mp = "flash"
raise InstallError(\
_("File system for '%s' should not be '%s'")
%(optMountPoint, format))
%(mp, format))
if not options:
options = ["noatime"]
dictOptions["fileSystem"] = format
@ -745,18 +774,81 @@ class cl_install(color_print):
self.defaultPrint("\b\b \n")
def prepareBoot(self,targetDistr):
self.installBootloader(targetDistr)
"""Prepare system for boot"""
if self.clVars.Get('os_install_root_type') == "flash":
self.installSyslinuxBootloader(targetDistr)
else:
self.installGrubBootloader(targetDistr)
def getTargetDistributive(self,disk,fileSystem="reiserfs",isFormat=False,
systemId=None,buildermode=False):
"""Get target distributive by params"""
if buildermode:
return ScratchPartitionDistributive(disk,mdirectory="/mnt/install",
check=True, fileSystem=fileSystem,
isFormat=isFormat, systemId=systemId)
elif self.clVars.Get('os_install_root_type')=="flash":
return FlashDistributive(disk,mdirectory="/mnt/install",
check=True, fileSystem=fileSystem,
isFormat=isFormat, systemId=systemId)
else:
return PartitionDistributive(disk,mdirectory="/mnt/install",
target = PartitionDistributive(disk,mdirectory="/mnt/install",
check=True, fileSystem=fileSystem,
isFormat=isFormat, systemId=systemId)
noRootPartDisksOptions = filter(lambda x: x['mountPoint']!="/",
self.listDisksOptions)
flagMultipartition = False
objMultiPartitions = False
# Disk multipartitions
if noRootPartDisksOptions:
flagMultipartition = True
objMultiPartitions = MultiPartitions()
for diskOptions in noRootPartDisksOptions:
dev = diskOptions["dev"]
mountPoint = diskOptions["mountPoint"]
fileSystem = diskOptions["fileSystem"]
isFormat = diskOptions["isFormat"]
systemId = diskOptions["systemId"]
objMultiPartitions.addPartition(dev=dev,
mountPoint=mountPoint,
fileSystem=fileSystem,
isFormat=isFormat,
systemId=systemId)
# Swap multipartitions
if self.listSwapsOptions:
flagMultipartition = True
if not objMultiPartitions:
objMultiPartitions = MultiPartitions()
for diskOptions in self.listSwapsOptions:
dev = diskOptions["dev"]
mountPoint = "swap"
fileSystem = diskOptions["fileSystem"]
isFormat = diskOptions["isFormat"]
systemId = diskOptions["systemId"]
objMultiPartitions.addPartition(dev=dev,
mountPoint=mountPoint,
fileSystem=fileSystem,
isFormat=isFormat,
systemId=systemId)
# Bind multipartitions
if self.listBindsOptions:
flagMultipartition = True
if not objMultiPartitions:
objMultiPartitions = MultiPartitions()
for diskOptions in self.listBindsOptions:
dev = diskOptions["srcMountPoint"]
mountPoint = diskOptions["destMountPoint"]
fileSystem = "bind"
isFormat = diskOptions["isFormat"]
objMultiPartitions.addPartition(dev=dev,
mountPoint=mountPoint,
fileSystem=fileSystem,
isFormat=isFormat,
systemId=None)
if flagMultipartition:
# Set Multipartition
target.multipartition=objMultiPartitions
return target
def applyTemplates(self,directory):
"""Apply templates for root of system."""
@ -799,8 +891,9 @@ class cl_install(color_print):
usedDevices = map(lambda x:x['dev'],listSwaps)+usedDevicesOnlyDisks
usedMP = map(lambda x:x['mountPoint'],listDisks) + \
map(lambda x:x['destMountPoint'],listBinds)
if self.clVars.Get('os_install_scratch') == "on" and \
filter(lambda x: x != '/', usedMP):
# check mount options for scratch and flash
if filter(lambda x: x != '/', usedMP):
if self.clVars.Get('os_install_scratch') == "on":
self.printERROR(
_("Builder mode is not support multipartition"))
return False
@ -941,17 +1034,52 @@ class cl_install(color_print):
bindDestSrc.pop(bindSrcDest[destMountPoint])
bindSrcDest[srcMountPoint] = destMountPoint
# update install root dev
rootDev = filter(lambda x:x[1]['mountPoint']=='/',devMount.items())
if not rootDev:
self.printERROR(_("Need specify root partition"))
return False
self.clVars.Set('os_install_root_dev',rootDev[0][0],True)
osInstallRootType = self.clVars.Get('os_install_root_type')
# update bind variables by new hash
new_bind_dest, new_bind_src = \
reduce(lambda x,y:[x[0]+[y[0]],x[1]+[y[1]]],
sorted(bindDestSrc.items()),[[]]*2)
if osInstallRootType != "flash":
new_bind_dest, new_bind_src = \
reduce(lambda x,y:[x[0]+[y[0]],x[1]+[y[1]]],
sorted(bindDestSrc.items()) ,
[[]]*2)
# discard all bind point for flash installation
else:
new_bind_dest = []
new_bind_src = []
if filter(lambda x: x != '/', usedMP):
self.printERROR(
_("Installation to flash disk is not support multipartition"))
return False
if filter(lambda x:x['dev']!="none",listSwaps):
self.printERROR(
_("Installation to flash disk is not support swap disks"))
return False
if builderMode:
self.printERROR(
_("Installation to flash disk is not support builder mode"))
return False
# receive substitution func. Discard all mp, exclude '/' for flash
if osInstallRootType != "flash":
substitution = lambda data,mp: data
else:
substitution = lambda data,mp: data if mp == '/' else ""
# update variables by new hash
new_mount, new_format, new_isformat, new_options= \
reduce(lambda x,y:[x[0]+[devMount[y]['mountPoint']],
x[1]+[devMount[y]['fileSystem']],
x[2]+[devMount[y]['isFormat']],
x[3]+[devMount[y]['options']]],
sorted(devMount.keys()),[[]]*4)
reduce(lambda x,y:[x[0]+[substitution(devMount[y]['mountPoint'],
devMount[y]['mountPoint'])],
x[1]+[substitution(devMount[y]['fileSystem'],
devMount[y]['mountPoint'])],
x[2]+[substitution(devMount[y]['isFormat'],
devMount[y]['mountPoint'])],
x[3]+[substitution(devMount[y]['options'],
devMount[y]['mountPoint'])]],
sorted(devMount.keys()),[[]]*4)
map(lambda x:self.clVars.Set(x[0],x[1],True),
(('os_install_disk_mount',new_mount),
@ -961,13 +1089,6 @@ class cl_install(color_print):
('os_install_disk_options',new_options),
('os_install_bind_path',new_bind_src),
('os_install_bind_mountpoint',new_bind_dest)))
rootDev = self.getFieldByField("dev","mount","/",
secondPrefix="os_install_disk")
if not rootDev:
self.printERROR(_("Need specify root partition"))
return False
self.clVars.Set('os_install_root_dev',rootDev,True)
return True
def setUsers(self,listUsers):
@ -1079,14 +1200,60 @@ class cl_install(color_print):
else:
return ""
def installBootloader(self,target):
def setActivePartition(self,partition):
reActive = re.compile('^%s\s*[*]'%partition)
device = filter(lambda x:x in partition,
self.clVars.Get('os_device_dev'))
if not device:
raise DistributiveError(_("Cann't get parent device"))
device = device[0]
fdiskProcess = process("/sbin/fdisk","-l",device)
if fdiskProcess.failed():
raise DistributiveError(_("Cann't get device information\n%s")%
fdiskProcess.read())
if not filter(reActive.search,fdiskProcess):
grubDisk = self.getFieldByField("grub","mount","/",
secondPrefix="os_install_disk")
if grubDisk and grubDisk.rpartition(',')[2].isdigit():
fdiskProcess = process("/sbin/fdisk", "/dev/%s"%device)
fdiskProcess.write("a\n%d\nw\n"%
(int(grubDisk.rpartition(',')[2])+1))
if fdiskProcess.success():
return True
raise DistributiveError(_("Cann't set active partition"))
else:
return True
def installSyslinuxBootloader(self,target):
"""Install boot loader by syslinux
Perform syslinux installation to flash.
"""
ddProcess = process("/bin/dd","if=/usr/share/syslinux/mbr.bin",
"of=/dev/%s"%self.clVars.Get('os_install_mbr'),
stderr=STDOUT)
if ddProcess.failed():
raise DistributiveError(_("Cann't write master boot record\n%s")%
ddProcess.read())
target.close()
installRootDev = self.clVars.Get('os_install_root_dev')
syslinuxProcess = process("/usr/bin/syslinux",
installRootDev, stderr=STDOUT)
if syslinuxProcess.failed():
raise DistributiveError(_("Cann't install syslinux\n%s")%
syslinuxProcess.read())
# is partition active
return self.setActivePartition(self.clVars.Get('os_install_root_dev'))
def installGrubBootloader(self,target):
"""Install boot loader
Perform grub installation to disk, which has root partition
"""
grubProcess = process("/sbin/grub",
"--device-map=%s/boot/grub/device.map"%target.getDirectory(),
"--batch")
"--batch",stderr=STDOUT)
bootDisk = self.getFieldByField("grub","mount","/boot",
secondPrefix="os_install_disk")
if not bootDisk:
@ -1247,7 +1414,7 @@ class cl_install(color_print):
'usr/lib/opengl')
openGLenv = pathjoin(self.clVars.Get('cl_chroot_path'),
'etc/env.d/03opengl')
openGlMods = filter(lambda x:x != "global",
os.listdir(pathGlModules))
mapGL_drivers = {'fglrx':"ati" if "ati" in openGlMods
@ -1359,6 +1526,35 @@ class cl_install(color_print):
'boot',self.clVars.Get('os_install_initrd'))
return InitRamFs(initrdPath).cleanInitRamFs()
def afterCopyHDDinstall(self,targetDistr):
"""Action performed after distributive copy for hdd install"""
# copy clt files from current system
self.printMessageForTest(_("Coping clt templates to new system"))
cltCpy = cltCopy(target=targetDistr.getDirectory())
for directory in self.clVars.Get('cl_template_clt_path'):
cltCpy.performCopy(directory)
self.printByResult(True)
# join templates
self.printMessageForTest(_("Updating config"))
self.applyTemplates(targetDistr.getDirectory())
# mount bind mount points
self.printByResult(True)
# optimize initrd
self.printMessageForTest(_("Creating new initrd file"))
self.printByResult(self.cleanInitrd())
self.printMessageForTest(_("Post-install configuration"))
targetDistr.postinstallMountBind()
self.printByResult(True)
# migrate users
self.printSUCCESS(_("Migrate users"))
objMigrate = migrate(targetDistr.getDirectory())
if not objMigrate.migrate(addUsers,changePwdUsers,migrateUsers):
raise InstallError(_("Can not migrate users to new system"))
def installSystem(self, force=False, bootDisk=None, stdinReadPwd=False,
builder=False):
"""install System by current variable enviroment"""
@ -1367,15 +1563,6 @@ class cl_install(color_print):
error = None
distrCopy = False
try:
# error in stdin
#if not stdinReadPwd:
#import StringIO
#sys.stdin = StringIO.StringIO()
#sys.stdin.write("no")
#print sys.stdin.read()
#sys.stdin.close()
#if textStdin:
#raise InstallError("incorrect stdin '%s'"%textStdin)
rootPartdev = self.clVars.Get('os_install_root_dev')
rootPartCmdList = filter(lambda x: x['dev']==rootPartdev,
self.listDisksOptions)
@ -1386,16 +1573,13 @@ class cl_install(color_print):
rootPartIsFormat=rootPartCmdDict['isFormat']
rootPartSystemId=rootPartCmdDict['systemId']
# wait 10 sec
#waittime = 3
#self.printSUCCESS(_("Installation will start pass %d seconds.")
#%waittime)
self.printInfo(sourceDistr,targetDistr)
targetDistr = self.getTargetDistributive(rootPartdev,
buildermode=builder,
fileSystem=rootPartFileSystem,
isFormat=rootPartIsFormat,
systemId=rootPartSystemId)
buildermode=builder,
fileSystem=rootPartFileSystem,
isFormat=rootPartIsFormat,
systemId=rootPartSystemId)
self.printInfo(sourceDistr,targetDistr)
distRep = DistributiveRepository()
distName = self.clVars.Get('cl_image')
if distName:
@ -1405,79 +1589,17 @@ class cl_install(color_print):
dialogMessage = _("Continue with the installation of \
the system") + " (yes/no)"
dialogRes = dialogYesNo(dialogMessage)
if dialogRes is None:
return True
elif dialogRes is False:
if dialogRes in (None,False):
return True
# set Users passwords
changePwdUsers = self.generateHashRoot(stdinRead=stdinReadPwd)
addUsers = self.generateHashUsers(stdinRead=stdinReadPwd)
migrateUsers = self.getNamesMigrateUsers()
# cmd options
noRootPartDisksOptions = filter(lambda x: x['mountPoint']!="/",
self.listDisksOptions)
flagMultipartition = False
objMultiPartitions = False
# Disk multipartitions
if noRootPartDisksOptions:
flagMultipartition = True
objMultiPartitions = MultiPartitions()
for diskOptions in noRootPartDisksOptions:
dev = diskOptions["dev"]
mountPoint = diskOptions["mountPoint"]
fileSystem = diskOptions["fileSystem"]
isFormat = diskOptions["isFormat"]
systemId = diskOptions["systemId"]
objMultiPartitions.addPartition(dev=dev,
mountPoint=mountPoint,
fileSystem=fileSystem,
isFormat=isFormat,
systemId=systemId)
# Swap multipartitions
if self.listSwapsOptions:
flagMultipartition = True
if not objMultiPartitions:
objMultiPartitions = MultiPartitions()
for diskOptions in self.listSwapsOptions:
dev = diskOptions["dev"]
mountPoint = "swap"
fileSystem = diskOptions["fileSystem"]
isFormat = diskOptions["isFormat"]
systemId = diskOptions["systemId"]
objMultiPartitions.addPartition(dev=dev,
mountPoint=mountPoint,
fileSystem=fileSystem,
isFormat=isFormat,
systemId=systemId)
# Bind multipartitions
if self.listBindsOptions:
flagMultipartition = True
if not objMultiPartitions:
objMultiPartitions = MultiPartitions()
for diskOptions in self.listBindsOptions:
dev = diskOptions["srcMountPoint"]
mountPoint = diskOptions["destMountPoint"]
fileSystem = "bind"
isFormat = diskOptions["isFormat"]
objMultiPartitions.addPartition(dev=dev,
mountPoint=mountPoint,
fileSystem=fileSystem,
isFormat=isFormat,
systemId=None)
self.printMessageForTest(_("Formating partitions"))
if flagMultipartition:
# Set Multipartition
targetDistr.multipartition=objMultiPartitions
# Format all partitions
targetDistr.formatAllPartitions()
else:
# Format root partition
if targetDistr.isFormat:
targetDistr.formatPartition(targetDistr.partition,
format=targetDistr.fileSystem)
targetDistr.performFormat()
self.printByResult(True)
# install distributive
self.printMessageForTest(
_("Unpacking system image into target"))
@ -1486,32 +1608,8 @@ the system") + " (yes/no)"
targetDistr.installFrom(sourceDistr)
self.printByResult(True)
# copy clt files from current system
self.printMessageForTest(_("Coping clt templates to new system"))
cltCpy = cltCopy(target=targetDistr.getDirectory())
for directory in self.clVars.Get('cl_template_clt_path'):
cltCpy.performCopy(directory)
self.printByResult(True)
# join templates
self.printMessageForTest(_("Updating config"))
self.applyTemplates(targetDistr.getDirectory())
# mount bind mount points
self.printByResult(True)
# optimize initrd
self.printMessageForTest(_("Creating new initrd file"))
self.printByResult(self.cleanInitrd())
self.printMessageForTest(_("Post-install configuration"))
targetDistr.postinstallMountBind()
self.printByResult(True)
# migrate users
self.printSUCCESS(_("Migrate users"))
objMigrate = migrate(targetDistr.getDirectory())
if not objMigrate.migrate(addUsers,changePwdUsers,migrateUsers):
raise InstallError(_("Can not migrate users to new system"))
if self.clVars.Get('os_install_root_type') != "flash":
self.afterCopyHDDinstall(targetDistr)
# change boot config
if self.clVars.Get('os_install_mbr'):
self.printMessageForTest(_("Preparing system for reboot"))

@ -48,6 +48,12 @@ CMD_OPTIONS = [{'shortOption':"d",
'action':'append',
'help':_("the SWAP_DISK for installation")
},
{'longOption':"type",
'optVal':"DISKTYPE",
'type':'choice',
'choices':['flash','hdd','usb-hdd'],
'help':_("device type for installed system")
},
{'shortOption':"f",
'longOption':"force",
'help':_("no questions during the install process")
@ -253,6 +259,9 @@ class install_cmd(share_cmd):
self.logicObj.clVars.Set('os_install_scratch',"on",True)
else:
self.logicObj.clVars.Set('os_install_scratch',"off",True)
if self.optobj.values.type:
self.logicObj.clVars.Set('os_install_root_type',
self.optobj.values.type, True)
listDiskOptions = []
listBindOptions = []
listSwapOptions = []

@ -252,7 +252,7 @@ class Data:
os_install_net_domain = {'mode':"w"}
# type of device for install
os_install_root_type = {}
os_install_root_type = {'mode':'w'}
# proxy server for system
os_install_proxy = {'mode':'w',

Loading…
Cancel
Save