|
|
|
@ -39,6 +39,11 @@ from server.utils import dialogYesNo
|
|
|
|
|
import cl_install
|
|
|
|
|
import cl_overriding
|
|
|
|
|
|
|
|
|
|
def DEBUG(msg):
|
|
|
|
|
if "DEBUG" in os.environ:
|
|
|
|
|
sys.stderr.write("%s\n"%msg)
|
|
|
|
|
sys.stderr.flush()
|
|
|
|
|
|
|
|
|
|
class printNoColor:
|
|
|
|
|
def colorPrint(self,attr,fg,bg,string):
|
|
|
|
|
sys.stdout.write(string)
|
|
|
|
@ -195,7 +200,7 @@ class cl_assemble(color_print):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def configureFunc(self,force=False):
|
|
|
|
|
def configureFunc(self,force=False,nounmount=False):
|
|
|
|
|
rootPartdev = self.clVars.Get('os_assemble_root_dev')
|
|
|
|
|
formatId = PartitionDistributive.formatId
|
|
|
|
|
fileSystem = self.clVars.Get('os_assemble_root_format')
|
|
|
|
@ -208,6 +213,7 @@ class cl_assemble(color_print):
|
|
|
|
|
mdirectory=self.clVars.Get('cl_assemble_path'),
|
|
|
|
|
check=True, fileSystem=fileSystem, isFormat=True,
|
|
|
|
|
systemId=formatId.get(fileSystem,"83"),
|
|
|
|
|
flagRemoveDir=False,
|
|
|
|
|
rootLabel="%s-%s"%
|
|
|
|
|
(self.clVars.Get('os_assemble_linux_shortname'),
|
|
|
|
|
self.clVars.Get('os_assemble_linux_ver')))
|
|
|
|
@ -239,6 +245,8 @@ class cl_assemble(color_print):
|
|
|
|
|
self.printMessageForTest(_("Unpacking portage"))
|
|
|
|
|
assemblePath = \
|
|
|
|
|
self.targetDistr.convertToDirectory().getDirectory()
|
|
|
|
|
if nounmount:
|
|
|
|
|
self.targetDistr = None
|
|
|
|
|
self.clVars.Set('cl_assemble_path', assemblePath, True)
|
|
|
|
|
portageSources = ArchiveDistributive(stageName)
|
|
|
|
|
portageTarget = DirectoryDistributive(
|
|
|
|
@ -260,22 +268,170 @@ class cl_assemble(color_print):
|
|
|
|
|
target = pathJoin(assemblePath,target)
|
|
|
|
|
if not path.exists(target):
|
|
|
|
|
os.makedirs(target,mode=0755)
|
|
|
|
|
if source == isMount(target):
|
|
|
|
|
continue
|
|
|
|
|
args = ["mount"]+opts.split()+[str(source).lower(),target]
|
|
|
|
|
mountProcess = process(*args)
|
|
|
|
|
if mountProcess.failed():
|
|
|
|
|
raise AssembleError(_("Can not mount %(from)s to %(to)s")%
|
|
|
|
|
{'from':source,'to':target})
|
|
|
|
|
if not nounmount:
|
|
|
|
|
DirectoryDistributive(target,parent=self.targetDistr)
|
|
|
|
|
self.printByResult(True)
|
|
|
|
|
|
|
|
|
|
emergeSync = "emerge --sync"
|
|
|
|
|
self.printMessageForTest(_("Executing %s")%emergeSync)
|
|
|
|
|
self.runChroot(emergeSync)
|
|
|
|
|
|
|
|
|
|
emergeLayman = "emerge layman"
|
|
|
|
|
self.printMessageForTest(_("Executing %s")%emergeLayman)
|
|
|
|
|
self.runChroot(emergeLayman)
|
|
|
|
|
|
|
|
|
|
self.printMessageForTest(_("Loading calculate overlay"))
|
|
|
|
|
if filter(lambda x:"calculate" in x,self.runChroot("layman -l")):
|
|
|
|
|
self.runChroot("layman -s calculate")
|
|
|
|
|
else:
|
|
|
|
|
self.runChroot("layman -L")
|
|
|
|
|
self.runChroot("layman -a calculate")
|
|
|
|
|
|
|
|
|
|
self.clVars.Set('cl_action',"setup",True)
|
|
|
|
|
self.printMessageForTest(_("Update configuration of assembling system"))
|
|
|
|
|
self.applyConfigureTemplates(assemblePath)
|
|
|
|
|
|
|
|
|
|
# TODO: temporary manual set link to profile
|
|
|
|
|
try:
|
|
|
|
|
makeProfilePath=pathJoin(assemblePath,"etc/make.profile")
|
|
|
|
|
if path.lexists(makeProfilePath):
|
|
|
|
|
os.unlink(makeProfilePath)
|
|
|
|
|
os.symlink("../var/lib/layman/calculate/profiles/calculate"
|
|
|
|
|
"/%s/%s/%s%s"%(
|
|
|
|
|
self.clVars.Get('os_assemble_linux_system'),
|
|
|
|
|
self.clVars.Get('os_assemble_linux_shortname'),
|
|
|
|
|
self.clVars.Get('os_assemble_gentoo_arch'),
|
|
|
|
|
self.clVars.Get('os_assemble_developer_profile')),
|
|
|
|
|
makeProfilePath)
|
|
|
|
|
except (OSError,IOError),e:
|
|
|
|
|
raise AssembleError(_("Can not change system profile"))
|
|
|
|
|
|
|
|
|
|
emergePortage = "emerge sys-apps/portage"
|
|
|
|
|
self.printMessageForTest(_("Executing %s")%emergePortage)
|
|
|
|
|
self.runChroot(emergePortage)
|
|
|
|
|
|
|
|
|
|
emergeSources = "USE='-vmlinuz' emerge sys-kernel/calculate-sources"
|
|
|
|
|
self.printMessageForTest(_("Receiving kernel sources"))
|
|
|
|
|
self.runChroot(emergeSources)
|
|
|
|
|
|
|
|
|
|
emergeV86d = "emerge sys-apps/v86d"
|
|
|
|
|
self.printMessageForTest(_("Executing %s")%emergeV86d)
|
|
|
|
|
self.runChroot(emergeV86d)
|
|
|
|
|
|
|
|
|
|
self.printMessageForTest(
|
|
|
|
|
_("Updating baselayout and compiling openrc"))
|
|
|
|
|
removeBaselayout = "CLEAN_DELAY=0 emerge -C --backtrack=0 " \
|
|
|
|
|
"sys-apps/baselayout sys-apps/sysvinit"
|
|
|
|
|
self.runChroot(removeBaselayout)
|
|
|
|
|
self._removeFiles("/etc/init.d/depscan.sh","/etc/init.d/functions.sh",
|
|
|
|
|
"/etc/init.d/runscript.sh",
|
|
|
|
|
prefix=assemblePath,
|
|
|
|
|
errormsg=_("Can not remove files from baselayout"))
|
|
|
|
|
self.runChroot("emerge sys-apps/openrc sys-apps/sysvinit "
|
|
|
|
|
"sys-fs/udev sys-fs/e2fsprogs")
|
|
|
|
|
self._removeFiles("/etc/runlevels/boot/network",
|
|
|
|
|
prefix=assemblePath)
|
|
|
|
|
if self.Get('os_assemble_linux_system') == "server" or \
|
|
|
|
|
self.Get('os_assemble_linux_shortname') != "CLS":
|
|
|
|
|
self._removeFiles("/etc/init.d/net.eth0",prefix=assemblePath)
|
|
|
|
|
self.printByResult(True)
|
|
|
|
|
|
|
|
|
|
self.groupAdd(35,"games")
|
|
|
|
|
self.groupAdd(440,"plugdev")
|
|
|
|
|
self.groupAdd(441,"scanner")
|
|
|
|
|
self.userAdd(100,"p2p",mode=0700,chown=(100,0),
|
|
|
|
|
home="/home/p2p",groups=["100","wheel"],
|
|
|
|
|
comment="added by Calculate for p2p",
|
|
|
|
|
shell="/bin/bash",prefix=assemblePath)
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def configureSystem(self,force):
|
|
|
|
|
def userAdd(self,userid,username,mode=0755,chown=(0,0),home=None,
|
|
|
|
|
groups=[],comment="",shell="/bin/bash",prefix="/"):
|
|
|
|
|
"""Check exists user and create new"""
|
|
|
|
|
if self.runChroot("id %s"%username,raiseError=False).failed():
|
|
|
|
|
self.printMessageForTest(
|
|
|
|
|
_("Creating %(user)s(%(id)d) user")%
|
|
|
|
|
{'user':username,'id':userid})
|
|
|
|
|
command = "useradd -u %d %s"%(userid,username)
|
|
|
|
|
if groups:
|
|
|
|
|
command += " -g %s"%groups[0]
|
|
|
|
|
if len(groups)>1:
|
|
|
|
|
command += " -G %s"%",".join(groups[1:])
|
|
|
|
|
if comment:
|
|
|
|
|
command += " -c '%s'"%comment
|
|
|
|
|
if shell:
|
|
|
|
|
command += " -s %s"%shell
|
|
|
|
|
self.runChroot(command)
|
|
|
|
|
try:
|
|
|
|
|
os.makedirs(pathJoin(prefix,home),mode=mode)
|
|
|
|
|
os.chown(pathJoin(prefix,home),chown[0],chown[1])
|
|
|
|
|
except (OSError,IOError),e:
|
|
|
|
|
raise AssembleError(
|
|
|
|
|
_("Can not create home directory for %s")%username)
|
|
|
|
|
|
|
|
|
|
def groupAdd(self,groupid,groupname):
|
|
|
|
|
"""Check exists group and create new"""
|
|
|
|
|
if self.runChroot("groupmems -l -g %s"
|
|
|
|
|
%groupname,raiseError=False).failed():
|
|
|
|
|
self.printMessageForTest(
|
|
|
|
|
_("Creating %(name)s(%(id)d) group")%
|
|
|
|
|
{'name':groupname,'id':groupid})
|
|
|
|
|
self.runChroot("groupadd -g %d %s"%(groupid,groupname))
|
|
|
|
|
self.printByResult(True)
|
|
|
|
|
|
|
|
|
|
def _removeFiles(self,*files,**kwarg):
|
|
|
|
|
"""Remove files specified by files list"""
|
|
|
|
|
prefix = kwarg.get("prefix","/")
|
|
|
|
|
errormsg = kwarg.get("errormsg",None)
|
|
|
|
|
try:
|
|
|
|
|
rmFile = ""
|
|
|
|
|
for fileName in removeFiles:
|
|
|
|
|
rmFile = pathJoin(prefix,fileName)
|
|
|
|
|
if path.lexists(rmFile):
|
|
|
|
|
os.unlink(rmFile)
|
|
|
|
|
except (OSError,IOError),e:
|
|
|
|
|
if errormsg is None:
|
|
|
|
|
raise AssembleError(_("Can not remove '%s'")%rmFile)
|
|
|
|
|
else:
|
|
|
|
|
raise AssembleError(errormsg)
|
|
|
|
|
|
|
|
|
|
def _getCommand(self,commandlist):
|
|
|
|
|
return " ".join(map(lambda x:'"%s"'%x if " " in x else x,commandlist))
|
|
|
|
|
|
|
|
|
|
def runChroot(self,command,raiseError=True):
|
|
|
|
|
"""Run command in chroot specified by cl_assemble_path"""
|
|
|
|
|
try:
|
|
|
|
|
chrootCommand = process("chroot",
|
|
|
|
|
self.clVars.Get('cl_assemble_path'),
|
|
|
|
|
"/bin/bash","-c",command)
|
|
|
|
|
DEBUG(self._getCommand(chrootCommand.command))
|
|
|
|
|
if raiseError and chrootCommand.failed():
|
|
|
|
|
raise AssembleError(
|
|
|
|
|
_("An error occurred during the command executing")+
|
|
|
|
|
":\n %s"%self._getCommand(chrootCommand.command))
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
chrootCommand.kill()
|
|
|
|
|
self.defaultPrint("\b\b")
|
|
|
|
|
raise AssembleError(
|
|
|
|
|
_("An interrupt occurred during the command executing")+
|
|
|
|
|
":\n %s"%self._getCommand(chrootCommand.command))
|
|
|
|
|
return chrootCommand
|
|
|
|
|
|
|
|
|
|
def configureSystem(self,force,nounmount):
|
|
|
|
|
"""Unpack stage or cls|css and prepare for assemble"""
|
|
|
|
|
self.msgOperationComplete = \
|
|
|
|
|
_("System was have prepared for assembling successfully")
|
|
|
|
|
self.msgOperationFailed = \
|
|
|
|
|
_("Preparing for assembling failed")
|
|
|
|
|
return self.make(self.configureFunc,force)
|
|
|
|
|
return self.make(self.configureFunc,force,nounmount)
|
|
|
|
|
|
|
|
|
|
def breakFunc(self,force):
|
|
|
|
|
rootPartdev = self.clVars.Get('os_assemble_root_dev')
|
|
|
|
@ -306,7 +462,7 @@ class cl_assemble(color_print):
|
|
|
|
|
if umountProcess.failed():
|
|
|
|
|
raise AssembleError(_("Can not umount %s")%target)
|
|
|
|
|
self.printByResult(True)
|
|
|
|
|
self.targetDistr = PartitionDistributive(rootPartdev)
|
|
|
|
|
self.targetDistr = PartitionDistributive(rootPartdev,flagRemoveDir=False)
|
|
|
|
|
dd = DirectoryDistributive(mp,parent=self.targetDistr)
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
@ -351,6 +507,10 @@ class cl_assemble(color_print):
|
|
|
|
|
self.printMessageForTest(
|
|
|
|
|
_("Releasing partition for assembling"))
|
|
|
|
|
self.targetDistr.close()
|
|
|
|
|
assemblePath = self.clVars.Get('cl_assemble_path')
|
|
|
|
|
if assemblePath.startswith('/mnt/builder'):
|
|
|
|
|
if path.exists(assemblePath):
|
|
|
|
|
os.rmdir(assemblePath)
|
|
|
|
|
self.printByResult(True)
|
|
|
|
|
if self.sourceDistr:
|
|
|
|
|
self.printMessageForTest(_("Releasing source data"))
|
|
|
|
|