|
|
|
@ -22,31 +22,58 @@ from time import sleep
|
|
|
|
|
import re
|
|
|
|
|
import sys
|
|
|
|
|
import operator
|
|
|
|
|
from shutil import copyfile,copytree
|
|
|
|
|
from subprocess import Popen,PIPE,STDOUT
|
|
|
|
|
from contextlib import nested
|
|
|
|
|
from shutil import copyfile, copytree
|
|
|
|
|
from subprocess import Popen, PIPE
|
|
|
|
|
from itertools import *
|
|
|
|
|
from functools import partial
|
|
|
|
|
from calculate.lib.datavars import VariableError
|
|
|
|
|
|
|
|
|
|
from calculate.lib.utils.files import (runOsCommand,isMount,removeDir,
|
|
|
|
|
processProgress,countFiles,STDOUT,
|
|
|
|
|
typeFile,pathJoin,process,getRunCommands,
|
|
|
|
|
readLinesFile,getProgPath,listDirectory,checkUtils,
|
|
|
|
|
MAGIC_COMPRESS,MAGIC_SYMLINK,MAGIC_CONTINUE)
|
|
|
|
|
from calculate.lib.utils.common import getTupleVersion,cmpVersion
|
|
|
|
|
from calculate.lib.utils.device import (detectDeviceForPartition,
|
|
|
|
|
getUdevDeviceInfo, countPartitions,
|
|
|
|
|
refreshUdev)
|
|
|
|
|
from calculate.lib.variables.linux import LinuxDataVars,Linux
|
|
|
|
|
from calculate.lib.utils.files import (runOsCommand, isMount, removeDir,
|
|
|
|
|
processProgress, STDOUT,
|
|
|
|
|
typeFile, pathJoin, process,
|
|
|
|
|
listDirectory, checkUtils,
|
|
|
|
|
MAGIC_COMPRESS, MAGIC_SYMLINK,
|
|
|
|
|
MAGIC_CONTINUE, makeDirectory,
|
|
|
|
|
PercentProgress)
|
|
|
|
|
from calculate.lib.utils.device import (detectDeviceForPartition,
|
|
|
|
|
getUdevDeviceInfo, countPartitions)
|
|
|
|
|
from calculate.lib.utils.tools import classproperty, Signal
|
|
|
|
|
from calculate.lib.variables.linux import LinuxDataVars, Linux
|
|
|
|
|
from calculate.lib.cl_vars_share import varsShare
|
|
|
|
|
from calculate.lib.cl_template import _terms
|
|
|
|
|
|
|
|
|
|
import threading
|
|
|
|
|
|
|
|
|
|
from calculate.lib.cl_lang import setLocalTranslate
|
|
|
|
|
setLocalTranslate('cl_install3',sys.modules[__name__])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DefaultMountPath:
|
|
|
|
|
"""
|
|
|
|
|
Пути по умолчанию для монтирования образов
|
|
|
|
|
"""
|
|
|
|
|
BaseMountPath = '/run/calculate/mount'
|
|
|
|
|
BuildDirectory = '/var/calculate/tmp/iso'
|
|
|
|
|
|
|
|
|
|
@classproperty
|
|
|
|
|
def IsoImage(cls):
|
|
|
|
|
return path.join(cls.BaseMountPath, "iso")
|
|
|
|
|
|
|
|
|
|
@classproperty
|
|
|
|
|
def SquashImage(cls):
|
|
|
|
|
return path.join(cls.BaseMountPath, "squash")
|
|
|
|
|
|
|
|
|
|
@classproperty
|
|
|
|
|
def ArchiveImage(cls):
|
|
|
|
|
return path.join(cls.BaseMountPath, "tarball")
|
|
|
|
|
|
|
|
|
|
@classproperty
|
|
|
|
|
def DefaultMount(cls):
|
|
|
|
|
return path.join(cls.BaseMountPath, "distro")
|
|
|
|
|
|
|
|
|
|
@classproperty
|
|
|
|
|
def InstallMount(cls):
|
|
|
|
|
return path.join(cls.BaseMountPath, "install")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class cpProcessProgress(processProgress):
|
|
|
|
|
|
|
|
|
|
def init(self,*args,**kwargs):
|
|
|
|
@ -84,7 +111,7 @@ def progressCopyFile(source,dest):
|
|
|
|
|
"""
|
|
|
|
|
size = int(os.lstat(source).st_size)
|
|
|
|
|
bufsize = (100-(size%100)+size) / 100
|
|
|
|
|
with nested(open(source,'rb'),open(dest,'w')) as (infile,outfile):
|
|
|
|
|
with (open(source, 'rb'), open(dest, 'w')) as (infile, outfile):
|
|
|
|
|
for i in xrange(1,101):
|
|
|
|
|
outfile.write(infile.read(bufsize))
|
|
|
|
|
yield i
|
|
|
|
@ -204,7 +231,7 @@ class Distributive(object):
|
|
|
|
|
dist2 = dist1.convertToDirectory()
|
|
|
|
|
dist1.close()
|
|
|
|
|
"""
|
|
|
|
|
#print "Close", self
|
|
|
|
|
#print "Close", self, self.locked
|
|
|
|
|
if self.locked:
|
|
|
|
|
return False
|
|
|
|
|
if self.ref:
|
|
|
|
@ -436,8 +463,11 @@ class Distributive(object):
|
|
|
|
|
If queried name is not free then to name append random string
|
|
|
|
|
"""
|
|
|
|
|
newDirectoryName = directory
|
|
|
|
|
while path.exists(newDirectoryName):
|
|
|
|
|
newDirectoryName = "%s.%s"%(directory,self.rndString())
|
|
|
|
|
for i in range(0,9999):
|
|
|
|
|
if not path.exists(newDirectoryName):
|
|
|
|
|
return newDirectoryName
|
|
|
|
|
else:
|
|
|
|
|
newDirectoryName = "%s.%04d"%(directory, i)
|
|
|
|
|
return newDirectoryName
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
@ -458,6 +488,7 @@ class Distributive(object):
|
|
|
|
|
d['os_linux_subname'] = dv.Get('os_linux_subname')
|
|
|
|
|
d['os_linux_system'] = dv.Get('os_linux_system')
|
|
|
|
|
d['cl_make_profile'] = dv.Get('cl_make_profile')
|
|
|
|
|
d['cl_profile_name'] = dv.Get('cl_profile_name')
|
|
|
|
|
# make lazy call
|
|
|
|
|
d['os_linux_files'] = partial(dv.Get, 'os_linux_files')
|
|
|
|
|
except VariableError:
|
|
|
|
@ -492,6 +523,7 @@ class Distributive(object):
|
|
|
|
|
extname = mapExtName.get(distr.__class__, "")
|
|
|
|
|
image = distr.convertToDirectory()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print str(e)
|
|
|
|
|
if distr:
|
|
|
|
|
distr.close()
|
|
|
|
|
return {}.copy()
|
|
|
|
@ -540,6 +572,10 @@ class Distributive(object):
|
|
|
|
|
except DistributiveError:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def post_clear(self):
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DirectoryDistributive(Distributive):
|
|
|
|
|
"""
|
|
|
|
|
Дистрибутив в директории
|
|
|
|
@ -616,7 +652,7 @@ class DirectoryDistributive(Distributive):
|
|
|
|
|
child.directory = None
|
|
|
|
|
|
|
|
|
|
def close(self):
|
|
|
|
|
if self.system_mounted:
|
|
|
|
|
if not self.locked and self.system_mounted:
|
|
|
|
|
self.umountSystemDirectories()
|
|
|
|
|
Distributive.close(self)
|
|
|
|
|
|
|
|
|
@ -637,6 +673,12 @@ class DirectoryDistributive(Distributive):
|
|
|
|
|
raise DistributiveError(_("Failed to clean directory") +
|
|
|
|
|
" %s:\n%s" % (self.directory, errmes))
|
|
|
|
|
|
|
|
|
|
def post_clear(self):
|
|
|
|
|
if path.exists(self.directory):
|
|
|
|
|
execStr = '/bin/rm -rf --one-file-system %s'%self.directory
|
|
|
|
|
res,errmes = self.runOsCommand(execStr)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def installFrom(self, source, **kwargs):
|
|
|
|
|
"""Install distributive to directory from source distributive"""
|
|
|
|
|
if isinstance(source,ArchiveDistributive):
|
|
|
|
@ -672,7 +714,7 @@ class DataPartition:
|
|
|
|
|
"""Data partition"""
|
|
|
|
|
dev = None
|
|
|
|
|
mountPoint = None
|
|
|
|
|
fileSystem = "reiserfs"
|
|
|
|
|
fileSystem = "ext4"
|
|
|
|
|
isFormat = False
|
|
|
|
|
systemId = None
|
|
|
|
|
partitionTable = None
|
|
|
|
@ -684,33 +726,35 @@ class MultiPartitions:
|
|
|
|
|
|
|
|
|
|
def addPartition(self, **argv):
|
|
|
|
|
"""Add partition in data partition list"""
|
|
|
|
|
dictDataPart = reduce(lambda x,y:\
|
|
|
|
|
x.update({y:getattr(DataPartition,y)}) or x,
|
|
|
|
|
filter(lambda x: not x.startswith('_'),
|
|
|
|
|
DataPartition.__dict__),{})
|
|
|
|
|
updateAttrData = filter(lambda x: x[1]!=None, dictDataPart.items())
|
|
|
|
|
dictDataPart = reduce(lambda x, y: \
|
|
|
|
|
x.update({y: getattr(DataPartition, y)}) or x,
|
|
|
|
|
filter(lambda x: not x.startswith('_'),
|
|
|
|
|
DataPartition.__dict__), {})
|
|
|
|
|
updateAttrData = filter(lambda x: x[1] != None, dictDataPart.items())
|
|
|
|
|
defaultAttr = []
|
|
|
|
|
for attrName, attrValue in updateAttrData:
|
|
|
|
|
if not attrName in argv.keys():
|
|
|
|
|
defaultAttr.append(attrName)
|
|
|
|
|
argv[attrName] = attrValue
|
|
|
|
|
if set(argv.keys()) != set(dictDataPart.keys()):
|
|
|
|
|
notFoundAttr = set(dictDataPart.keys()) - set(argv.keys())
|
|
|
|
|
notFoundAttr = set(dictDataPart.keys()) - set(argv.keys())
|
|
|
|
|
if notFoundAttr:
|
|
|
|
|
raise DistributiveError(_("The following attributes "
|
|
|
|
|
"are not specified: (%s)")\
|
|
|
|
|
%", ".join(map(lambda x:"DataPartition.%s"%x, notFoundAttr)))
|
|
|
|
|
unnecessaryAttr = (set(dictDataPart.keys()) ^ set(argv.keys())) -\
|
|
|
|
|
set(dictDataPart.keys())
|
|
|
|
|
"are not specified: (%s)") \
|
|
|
|
|
% ", ".join(
|
|
|
|
|
map(lambda x: "DataPartition.%s" % x, notFoundAttr)))
|
|
|
|
|
unnecessaryAttr = (set(dictDataPart.keys()) ^ set(argv.keys())) - \
|
|
|
|
|
set(dictDataPart.keys())
|
|
|
|
|
if unnecessaryAttr:
|
|
|
|
|
raise DistributiveError(_("Failed to use attributes (%s) ")\
|
|
|
|
|
%", ".join(map(lambda x:"DataPartition.%s"%x, unnecessaryAttr)))
|
|
|
|
|
raise DistributiveError(_("Failed to use attributes (%s) ") \
|
|
|
|
|
% ", ".join(
|
|
|
|
|
map(lambda x: "DataPartition.%s" % x, unnecessaryAttr)))
|
|
|
|
|
else:
|
|
|
|
|
partObj = DataPartition()
|
|
|
|
|
for attr, value in argv.items():
|
|
|
|
|
if attr in defaultAttr:
|
|
|
|
|
continue
|
|
|
|
|
setattr(partObj,attr,value)
|
|
|
|
|
setattr(partObj, attr, value)
|
|
|
|
|
self.listPartitions.append(partObj)
|
|
|
|
|
|
|
|
|
|
def getSystemId(self):
|
|
|
|
@ -739,60 +783,60 @@ class MultiPartitions:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PartitionDistributive(Distributive):
|
|
|
|
|
formatUtilities = {'ext2':'/sbin/mkfs.ext2 %s %s',
|
|
|
|
|
'ext3':'/sbin/mkfs.ext3 %s %s',
|
|
|
|
|
'ext4':'/sbin/mkfs.ext4 %s %s',
|
|
|
|
|
'jfs':'/sbin/mkfs.jfs %s -f %s',
|
|
|
|
|
'reiserfs':'/sbin/mkfs.reiserfs %s -f %s',
|
|
|
|
|
'btrfs':'/sbin/mkfs.btrfs -f %s %s',
|
|
|
|
|
'nilfs2':'/sbin/mkfs.nilfs2 %s %s',
|
|
|
|
|
'xfs':'/sbin/mkfs.xfs %s -f %s',
|
|
|
|
|
'vfat':'/usr/sbin/mkfs.vfat %s -F 32 %s',
|
|
|
|
|
'ntfs-3g':'/usr/sbin/mkfs.ntfs %s -FQ %s',
|
|
|
|
|
'ntfs':'/usr/sbin/mkfs.ntfs %s -FQ %s',
|
|
|
|
|
'uefi':'/usr/sbin/mkfs.vfat %s %s',
|
|
|
|
|
'swap':'/sbin/mkswap %s'
|
|
|
|
|
}
|
|
|
|
|
labelForUtilities = { 'ext2':'-L %s',
|
|
|
|
|
'ext3':'-L %s',
|
|
|
|
|
'ext4':'-L %s',
|
|
|
|
|
'btrfs':'-L %s',
|
|
|
|
|
'nilfs2':'-L %s',
|
|
|
|
|
'jfs':'-L %s',
|
|
|
|
|
'reiserfs':'-l %s',
|
|
|
|
|
'xfs':'-L %s',
|
|
|
|
|
'vfat':'-n %s',
|
|
|
|
|
'ntfs-3g':'-L %s',
|
|
|
|
|
'ntfs':'-L %s',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
formatId = { 'ext2' : '83',
|
|
|
|
|
'ext3' : '83',
|
|
|
|
|
'ext4' : '83',
|
|
|
|
|
'reiserfs' : '83',
|
|
|
|
|
'btrfs' : '83',
|
|
|
|
|
'nilfs2' : '83',
|
|
|
|
|
'jfs' : '83',
|
|
|
|
|
'xfs' : '83',
|
|
|
|
|
'vfat' : '0b',
|
|
|
|
|
'swap' : '82'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
formatIdGpt = { 'ext2' : '8300',
|
|
|
|
|
'ext3' : '8300',
|
|
|
|
|
'ext4' : '8300',
|
|
|
|
|
'reiserfs' : '8300',
|
|
|
|
|
'btrfs' : '8300',
|
|
|
|
|
'nilfs2' : '8300',
|
|
|
|
|
'jfs' : '8300',
|
|
|
|
|
'xfs' : '8300',
|
|
|
|
|
'vfat' : '0700',
|
|
|
|
|
'swap' : '8200'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def __init__(self,partition,parent=None,mdirectory="/mnt/calculate",
|
|
|
|
|
formatUtilities = {'ext2': '/sbin/mkfs.ext2 %s %s',
|
|
|
|
|
'ext3': '/sbin/mkfs.ext3 %s %s',
|
|
|
|
|
'ext4': '/sbin/mkfs.ext4 %s %s',
|
|
|
|
|
'jfs': '/sbin/mkfs.jfs %s -f %s',
|
|
|
|
|
'reiserfs': '/sbin/mkfs.reiserfs %s -f %s',
|
|
|
|
|
'btrfs': '/sbin/mkfs.btrfs -f %s %s',
|
|
|
|
|
'nilfs2': '/sbin/mkfs.nilfs2 %s %s',
|
|
|
|
|
'xfs': '/sbin/mkfs.xfs %s -f %s',
|
|
|
|
|
'vfat': '/usr/sbin/mkfs.vfat %s -F 32 %s',
|
|
|
|
|
'ntfs-3g': '/usr/sbin/mkfs.ntfs %s -FQ %s',
|
|
|
|
|
'ntfs': '/usr/sbin/mkfs.ntfs %s -FQ %s',
|
|
|
|
|
'uefi': '/usr/sbin/mkfs.vfat %s %s',
|
|
|
|
|
'swap': '/sbin/mkswap %s'
|
|
|
|
|
}
|
|
|
|
|
labelForUtilities = {'ext2': '-L %s',
|
|
|
|
|
'ext3': '-L %s',
|
|
|
|
|
'ext4': '-L %s',
|
|
|
|
|
'btrfs': '-L %s',
|
|
|
|
|
'nilfs2': '-L %s',
|
|
|
|
|
'jfs': '-L %s',
|
|
|
|
|
'reiserfs': '-l %s',
|
|
|
|
|
'xfs': '-L %s',
|
|
|
|
|
'vfat': '-n %s',
|
|
|
|
|
'ntfs-3g': '-L %s',
|
|
|
|
|
'ntfs': '-L %s',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
formatId = {'ext2': '83',
|
|
|
|
|
'ext3': '83',
|
|
|
|
|
'ext4': '83',
|
|
|
|
|
'reiserfs': '83',
|
|
|
|
|
'btrfs': '83',
|
|
|
|
|
'nilfs2': '83',
|
|
|
|
|
'jfs': '83',
|
|
|
|
|
'xfs': '83',
|
|
|
|
|
'vfat': '0b',
|
|
|
|
|
'swap': '82'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
formatIdGpt = {'ext2': '8300',
|
|
|
|
|
'ext3': '8300',
|
|
|
|
|
'ext4': '8300',
|
|
|
|
|
'reiserfs': '8300',
|
|
|
|
|
'btrfs': '8300',
|
|
|
|
|
'nilfs2': '8300',
|
|
|
|
|
'jfs': '8300',
|
|
|
|
|
'xfs': '8300',
|
|
|
|
|
'vfat': '0700',
|
|
|
|
|
'swap': '8200'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def __init__(self,partition,parent=None,mdirectory=None,
|
|
|
|
|
check=False,multipartition=None,flagRemoveDir=True,
|
|
|
|
|
fileSystem="reiserfs", isFormat=True,systemId=None,
|
|
|
|
|
fileSystem="ext4", isFormat=True,systemId=None,
|
|
|
|
|
rootLabel="Calculate", partitionTable=None):
|
|
|
|
|
"""Initialize partition distributive
|
|
|
|
|
|
|
|
|
@ -803,7 +847,7 @@ class PartitionDistributive(Distributive):
|
|
|
|
|
Distributive.__init__(self,parent=parent)
|
|
|
|
|
self.partition = partition
|
|
|
|
|
self.fileSystem = fileSystem
|
|
|
|
|
self.mdirectory = mdirectory
|
|
|
|
|
self.mdirectory = mdirectory or DefaultMountPath.DefaultMount
|
|
|
|
|
self.multipartition = multipartition
|
|
|
|
|
self.flagRemoveDir = flagRemoveDir
|
|
|
|
|
self.isFormat = isFormat
|
|
|
|
@ -950,7 +994,7 @@ class PartitionDistributive(Distributive):
|
|
|
|
|
raise DistributiveError(
|
|
|
|
|
_("Failed to format %s: this partition is mounted")%dev)
|
|
|
|
|
|
|
|
|
|
def formatPartition(self, dev,format="reiserfs",label=""):
|
|
|
|
|
def formatPartition(self, dev,format="ext4",label=""):
|
|
|
|
|
"""Format partition"""
|
|
|
|
|
if not format in self.formatUtilities:
|
|
|
|
|
raise DistributiveError(
|
|
|
|
@ -1018,16 +1062,16 @@ class PartitionDistributive(Distributive):
|
|
|
|
|
pipe.stdin.close()
|
|
|
|
|
pipe.wait()
|
|
|
|
|
elif parttable == "gpt":
|
|
|
|
|
pipe = Popen([gdiskProg,deviceName],
|
|
|
|
|
stdin=PIPE, stdout=PIPE,stderr=PIPE)
|
|
|
|
|
pipe = Popen([gdiskProg, deviceName],
|
|
|
|
|
stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
|
|
|
|
if devicePartitionCount > 1:
|
|
|
|
|
pipe.stdin.write("t\n%s\n%s\nw\ny\n"%(partitionNumber,
|
|
|
|
|
systemid))
|
|
|
|
|
pipe.stdin.write("t\n%s\n%s\nw\ny\n" % (partitionNumber,
|
|
|
|
|
systemid))
|
|
|
|
|
else:
|
|
|
|
|
pipe.stdin.write("t\n%s\nw\ny\n"%systemid)
|
|
|
|
|
pipe.stdin.write("t\n%s\nw\ny\n" % systemid)
|
|
|
|
|
pipe.stdin.close()
|
|
|
|
|
pipe.wait()
|
|
|
|
|
for waittime in (0.1,0.2,0.5,1,2,4):
|
|
|
|
|
for waittime in (0.1, 0.2, 0.5, 1, 2, 4):
|
|
|
|
|
if path.exists(dev):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
@ -1072,7 +1116,7 @@ class PartitionDistributive(Distributive):
|
|
|
|
|
@classmethod
|
|
|
|
|
@Distributive.required("partition", "mdirectory", "flag_remove_directory")
|
|
|
|
|
def unserialize(self, data, parent=None):
|
|
|
|
|
ld = PartitionDistributive(data['directory'], parent=parent)
|
|
|
|
|
ld = PartitionDistributive(data['partition'], parent=parent)
|
|
|
|
|
ld.mdirectory = data['mdirectory']
|
|
|
|
|
ld.flagRemoveDir = data['flag_remove_directory']
|
|
|
|
|
ld.childs = [Distributive.unserialize(x, parent=ld) for x in
|
|
|
|
@ -1191,15 +1235,13 @@ class ArchiveDistributive(Distributive):
|
|
|
|
|
return ld
|
|
|
|
|
|
|
|
|
|
class SquashDistributive(Distributive):
|
|
|
|
|
def __init__(self,file,parent=None,mdirectory="/mnt/livecd",exclude=None,
|
|
|
|
|
def __init__(self, file, parent=None, mdirectory=None, exclude=None,
|
|
|
|
|
compress=""):
|
|
|
|
|
Distributive.__init__(self,parent=parent)
|
|
|
|
|
Distributive.__init__(self, parent=parent)
|
|
|
|
|
self.file = file
|
|
|
|
|
self.mdirectory = mdirectory
|
|
|
|
|
self.mdirectory = mdirectory or DefaultMountPath.SquashImage
|
|
|
|
|
self.exclude = exclude or []
|
|
|
|
|
self.compress = compress \
|
|
|
|
|
if compress and compress != "gzip" else \
|
|
|
|
|
""
|
|
|
|
|
self.compress = compress if compress and compress != "gzip" else ""
|
|
|
|
|
|
|
|
|
|
def getType(self):
|
|
|
|
|
return _("squash image %s")%self.file
|
|
|
|
@ -1230,27 +1272,35 @@ class SquashDistributive(Distributive):
|
|
|
|
|
self._umountSquash(child.directory)
|
|
|
|
|
child.directory = None
|
|
|
|
|
|
|
|
|
|
def packToSquash(self,directory,file):
|
|
|
|
|
def packToSquash(self,directory,file, **kwargs):
|
|
|
|
|
mksquashfsUtil = '/usr/bin/mksquashfs'
|
|
|
|
|
if not path.exists(mksquashfsUtil):
|
|
|
|
|
raise DistributiveError(_("Failed to create squash") +
|
|
|
|
|
" : %s"%_("command '%s' not found")%mksquashfsUtil)
|
|
|
|
|
cmd = [mksquashfsUtil, "%s/"%directory,file, "-no-progress"]
|
|
|
|
|
cmd = [mksquashfsUtil, "%s/"%directory,file,] # "-no-progress"]
|
|
|
|
|
if self.exclude:
|
|
|
|
|
cmd += ["-e"] + self.exclude
|
|
|
|
|
if self.compress:
|
|
|
|
|
cmd += ["-comp",self.compress]
|
|
|
|
|
processMkSquash = process(*cmd)
|
|
|
|
|
if processMkSquash.failed():
|
|
|
|
|
raise DistributiveError(_("Failed to create squashfs") +
|
|
|
|
|
" '%s':\n%s"%(file,processMkSquash.read()))
|
|
|
|
|
cmd += ["-progress"]
|
|
|
|
|
if path.exists('/var/calculate/vbox/livecd.squashfs'):
|
|
|
|
|
os.system('cp /var/calculate/vbox/livecd.squashfs %s'%file)
|
|
|
|
|
else:
|
|
|
|
|
callbackProgress = kwargs.get('callbackProgress',None)
|
|
|
|
|
processMkSquash = PercentProgress(*cmd, stderr=STDOUT, atty=True)
|
|
|
|
|
for perc in processMkSquash.progress():
|
|
|
|
|
if callbackProgress:
|
|
|
|
|
callbackProgress(perc)
|
|
|
|
|
if processMkSquash.failed():
|
|
|
|
|
raise DistributiveError(_("Failed to create squashfs") +
|
|
|
|
|
" '%s':\n%s"%(file,processMkSquash.read()))
|
|
|
|
|
|
|
|
|
|
def installFrom(self, source, **kwargs):
|
|
|
|
|
"""Install distributive to partition from source distributive"""
|
|
|
|
|
# get source distributive as directory distributive
|
|
|
|
|
dFrom = source.convertToDirectory()
|
|
|
|
|
# install into directroy distributive from source
|
|
|
|
|
self.packToSquash(dFrom.directory, self.file)
|
|
|
|
|
self.packToSquash(dFrom.directory, self.file, **kwargs)
|
|
|
|
|
|
|
|
|
|
def serialize(self):
|
|
|
|
|
d = {'type': Distributive.Type.SquashFS,
|
|
|
|
@ -1270,21 +1320,25 @@ class SquashDistributive(Distributive):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IsoDistributive(Distributive):
|
|
|
|
|
def __init__(self,file,parent=None,mdirectory="/mnt/cdrom",
|
|
|
|
|
bdirectory="/var/calculate/tmp/iso",exclude=None,
|
|
|
|
|
compress="gzip"):
|
|
|
|
|
Distributive.__init__(self,parent=parent)
|
|
|
|
|
def __init__(self, file, parent=None, mdirectory=None,
|
|
|
|
|
bdirectory=None, exclude=None, compress="gzip",
|
|
|
|
|
vol_id="CALCULATE"):
|
|
|
|
|
if bdirectory is None:
|
|
|
|
|
bdirectory = DefaultMountPath.BuildDirectory
|
|
|
|
|
Distributive.__init__(self, parent=parent)
|
|
|
|
|
self.file = file
|
|
|
|
|
self.vol_id = vol_id
|
|
|
|
|
if path.isdir(self.file):
|
|
|
|
|
self.mdirectory = self.file
|
|
|
|
|
else:
|
|
|
|
|
self.mdirectory = mdirectory
|
|
|
|
|
self.mdirectory = mdirectory or DefaultMountPath.IsoImage
|
|
|
|
|
if file == bdirectory:
|
|
|
|
|
self.bdirectory = file
|
|
|
|
|
else:
|
|
|
|
|
self.bdirectory = self._getMntDirectory(bdirectory)
|
|
|
|
|
self.exclude = [] if not exclude else exclude
|
|
|
|
|
self.compress = compress
|
|
|
|
|
self.eventPrepareIso = Signal()
|
|
|
|
|
|
|
|
|
|
def getType(self):
|
|
|
|
|
tf = typeFile(magic=MAGIC_COMPRESS|MAGIC_SYMLINK|MAGIC_CONTINUE)
|
|
|
|
@ -1336,8 +1390,8 @@ class IsoDistributive(Distributive):
|
|
|
|
|
raise DistributiveError(_("ISO %s contains no live image") %
|
|
|
|
|
self.file)
|
|
|
|
|
return SquashDistributive(path.join(mdirectory,fileLive),
|
|
|
|
|
parent=self,exclude=self.exclude,
|
|
|
|
|
compress=self.compress)
|
|
|
|
|
parent=self,exclude=self.exclude,
|
|
|
|
|
compress=self.compress)
|
|
|
|
|
|
|
|
|
|
def getIsoContentDirectory(self):
|
|
|
|
|
"""Return directory with content of iso image"""
|
|
|
|
@ -1353,7 +1407,16 @@ class IsoDistributive(Distributive):
|
|
|
|
|
def convertToDirectory(self):
|
|
|
|
|
return self.convertToSquash().convertToDirectory()
|
|
|
|
|
|
|
|
|
|
def packToIso(self,directory,file):
|
|
|
|
|
def _get_iso_util(self):
|
|
|
|
|
mkisoUtil = '/usr/bin/mkisofs'
|
|
|
|
|
if not path.exists(mkisoUtil):
|
|
|
|
|
raise DistributiveError(
|
|
|
|
|
"{errmess} : {errdescr}".format(
|
|
|
|
|
errmess=_("Failed to create the ISO image"),
|
|
|
|
|
errdescr=_("command '%s' not found") % mkisoUtil))
|
|
|
|
|
return mkisoUtil
|
|
|
|
|
|
|
|
|
|
def packToIso(self, directory, file, **kwargs):
|
|
|
|
|
# remove previous version of iso
|
|
|
|
|
try:
|
|
|
|
|
if path.exists(file):
|
|
|
|
@ -1365,27 +1428,34 @@ class IsoDistributive(Distributive):
|
|
|
|
|
raise DistributiveError(_("Failed to remove") +\
|
|
|
|
|
" %s:\n%s"%(file,str(e)))
|
|
|
|
|
|
|
|
|
|
mkisoUtil = '/usr/bin/mkisofs'
|
|
|
|
|
if not path.exists(mkisoUtil):
|
|
|
|
|
raise DistributiveError(_("Failed to create the ISO image") +
|
|
|
|
|
" : %s"%_("command '%s' not found")%mkisoUtil)
|
|
|
|
|
res,errmes = self.runOsCommand(
|
|
|
|
|
"%(progname)s %(params)s -o %(target)s %(source)s/"%
|
|
|
|
|
{'progname':mkisoUtil,
|
|
|
|
|
'params':" ".join(["-b isolinux/isolinux.bin","-no-emul-boot",
|
|
|
|
|
"-boot-load-size 4","-boot-info-table","-iso-level 4",
|
|
|
|
|
"-hide boot.catalog"]),
|
|
|
|
|
'target':file,
|
|
|
|
|
'source':directory})
|
|
|
|
|
if res == 0:
|
|
|
|
|
return True
|
|
|
|
|
mkisoUtil = self._get_iso_util()
|
|
|
|
|
if not path.exists(path.dirname(file)):
|
|
|
|
|
makeDirectory(path.dirname(file))
|
|
|
|
|
efi_image = 'boot/grub/efi.img'
|
|
|
|
|
if path.exists(path.join(directory, efi_image)):
|
|
|
|
|
params = ["-J", "-R", "-l", "-no-emul-boot", "-boot-load-size", "4",
|
|
|
|
|
"-udf", "-boot-info-table", "-b", "isolinux/isolinux.bin",
|
|
|
|
|
"-V", self.vol_id,
|
|
|
|
|
"-c", "isolinux/boot.cat", "-eltorito-alt-boot",
|
|
|
|
|
"-no-emul-boot", "-eltorito-platform", "efi",
|
|
|
|
|
"-eltorito-boot", efi_image]
|
|
|
|
|
else:
|
|
|
|
|
params = ["-b", "isolinux/isolinux.bin", "-no-emul-boot",
|
|
|
|
|
"-V", self.vol_id,
|
|
|
|
|
"-boot-load-size", "4",
|
|
|
|
|
"-boot-info-table", "-iso-level", "4",
|
|
|
|
|
"-hide", "boot.catalog"]
|
|
|
|
|
cmd = [mkisoUtil] + params + ["-o", file, "%s/" % directory]
|
|
|
|
|
callback_progress = kwargs.get('callbackProgress', None)
|
|
|
|
|
processMkIsoFs = PercentProgress(*cmd, stderr=STDOUT, atty=True)
|
|
|
|
|
for perc in processMkIsoFs.progress():
|
|
|
|
|
if callback_progress:
|
|
|
|
|
callback_progress(perc)
|
|
|
|
|
if processMkIsoFs.failed():
|
|
|
|
|
raise DistributiveError(_("Failed to create the ISO image") +
|
|
|
|
|
" %s:\n%s"%(file,errmes))
|
|
|
|
|
|
|
|
|
|
def prepareIso(self):
|
|
|
|
|
raise DistributiveError(
|
|
|
|
|
_("The ISO image cannot be created without overriding prepareIso"))
|
|
|
|
|
" %s:\n%s" % (file, processMkIsoFs.read()))
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def installFrom(self, source, **kwargs):
|
|
|
|
|
"""Install distributive to partition from source distributive"""
|
|
|
|
@ -1412,10 +1482,10 @@ class IsoDistributive(Distributive):
|
|
|
|
|
compress=self.compress)
|
|
|
|
|
squashDistr.installFrom(distDirectory,**kwargs)
|
|
|
|
|
# prepare iso
|
|
|
|
|
self.prepareIso(isoDirectory)
|
|
|
|
|
self.eventPrepareIso.emit(isoDirectory)
|
|
|
|
|
# pack iso
|
|
|
|
|
if self.bdirectory != self.file:
|
|
|
|
|
self.packToIso(isoDirectory, self.file)
|
|
|
|
|
self.packToIso(isoDirectory, self.file, **kwargs)
|
|
|
|
|
except DistributiveError,e:
|
|
|
|
|
raise e
|
|
|
|
|
except KeyboardInterrupt,e:
|
|
|
|
@ -1486,16 +1556,15 @@ class FlashDistributive(PartitionDistributive):
|
|
|
|
|
source.__class__.__name__)
|
|
|
|
|
|
|
|
|
|
class ScratchDistributive(Distributive):
|
|
|
|
|
def __init__(self,directory,parent=None,mdirectory="/mnt/install",
|
|
|
|
|
check=False):
|
|
|
|
|
Distributive.__init__(self,parent=parent)
|
|
|
|
|
def __init__(self, directory, parent=None, mdirectory=None, check=False):
|
|
|
|
|
Distributive.__init__(self, parent=parent)
|
|
|
|
|
self.directory = directory
|
|
|
|
|
self.mdirectory = mdirectory
|
|
|
|
|
if check and not (path.exists(path.join(directory,"workspace")) and \
|
|
|
|
|
path.exists(path.join(directory,"delta")) and \
|
|
|
|
|
path.exists(path.join(directory,"calculate"))):
|
|
|
|
|
self.mdirectory = mdirectory or DefaultMountPath.InstallMount
|
|
|
|
|
if check and not (path.exists(path.join(directory, "workspace")) and
|
|
|
|
|
path.exists(path.join(directory, "delta")) and
|
|
|
|
|
path.exists(path.join(directory, "calculate"))):
|
|
|
|
|
raise DistributiveError(
|
|
|
|
|
_("Wrong scratch distribution in '%s'")%directory)
|
|
|
|
|
_("Wrong scratch distribution in '%s'") % directory)
|
|
|
|
|
|
|
|
|
|
def _mountLayers(self,source,target):
|
|
|
|
|
"""Mount squashfs to directory"""
|
|
|
|
@ -1666,6 +1735,7 @@ class LayeredDistributive(Distributive):
|
|
|
|
|
"""
|
|
|
|
|
Каталог дистрибутива для сборки
|
|
|
|
|
"""
|
|
|
|
|
# TODO: True и удаление данных workdir на форматировании
|
|
|
|
|
needFormat = False
|
|
|
|
|
|
|
|
|
|
def __init__(self, mdirectory, diff_directory, image_file=None,
|
|
|
|
@ -1679,10 +1749,16 @@ class LayeredDistributive(Distributive):
|
|
|
|
|
super(LayeredDistributive, self).__init__(parent=parent)
|
|
|
|
|
self.mdirectory = mdirectory
|
|
|
|
|
self.diff_directory = diff_directory
|
|
|
|
|
self.workdir = "%s-work"%self.diff_directory
|
|
|
|
|
self.image_mount_dir = None
|
|
|
|
|
self.image_distro = None
|
|
|
|
|
self.image_file = image_file
|
|
|
|
|
|
|
|
|
|
def post_clear(self):
|
|
|
|
|
if path.exists(self.diff_directory):
|
|
|
|
|
self._removeDirectory(self.diff_directory)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def getType(self):
|
|
|
|
|
return _("layered '{file} {diff}'").format(
|
|
|
|
|
file=self.image_file,
|
|
|
|
@ -1697,14 +1773,19 @@ class LayeredDistributive(Distributive):
|
|
|
|
|
self._makeDirectory(target)
|
|
|
|
|
if not path.exists(self.diff_directory):
|
|
|
|
|
self._makeDirectory(self.diff_directory)
|
|
|
|
|
if not path.exists(self.workdir):
|
|
|
|
|
self._makeDirectory(self.workdir)
|
|
|
|
|
self._mountToDirectory("none", target, mountopts=(
|
|
|
|
|
"-t aufs -o udba=reval,br:%(work)s=rw:%(static)s=ro" %
|
|
|
|
|
{"work": self.diff_directory,
|
|
|
|
|
"-t overlay -o lowerdir=%(static)s,"
|
|
|
|
|
"upperdir=%(upper)s,workdir=%(workdir)s" %
|
|
|
|
|
{"upper": self.diff_directory,
|
|
|
|
|
"workdir": self.workdir,
|
|
|
|
|
"static": self.image_mount_dir}))
|
|
|
|
|
|
|
|
|
|
def _umountLayers(self, directory):
|
|
|
|
|
self._umountDirectory(directory)
|
|
|
|
|
self._removeDirectory(directory)
|
|
|
|
|
self._removeDirectory(self.workdir)
|
|
|
|
|
|
|
|
|
|
def _mountLiveImage(self):
|
|
|
|
|
"""Mount squashfs to directory"""
|
|
|
|
|