You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-3-install/install/variables/distr.py

431 lines
17 KiB

#-*- coding: utf-8 -*-
# Copyright 2008-2012 Calculate Ltd. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
from os import path
import re
import operator
from calculate.lib.datavars import Variables,VariableError
from calculate.lib.utils.common import getSupportArch,getTupleVersion
from calculate.lib.utils.files import readLinesFile, listDirectory
from calculate.lib.variables import Linux
from calculate.install.cl_distr import Distributive
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install',sys.modules[__name__])
class Distro(Variables):
vars = ["cl_image","cl_image_path","cl_image_arch_machine",
"cl_image_linux_shortname","cl_image_linux_ver",
"cl_image_linux_build","cl_image_filename"]
# system image for installation
cl_image = {}
cl_image_filename = {'mode':'w',
'type':'choiceedit',
'opt':['--iso'],
'label':_("Installation image"),
'help':_("ISO image for installation")}
# filter by architecture
cl_image_arch_machine = {'mode':'w',
'type':'choice',
'opt':['--march'],
'label':_("Preferred processor architecture"),
'help':_("select the processor architecture")}
# filter by shortname
cl_image_linux_shortname = {'mode':'w',
'type':'choice',
'opt':['--os','-s'],
'label':_("Distributive"),
'help':_("select the operation system")}
# filter by version
cl_image_linux_ver = {'mode':'w',
'type':'string',
'label':_("Version"),
'value':"",
'help':_("select the operation system by version")}
# filter by build
cl_image_linux_build = {'mode':'w',
'type':'string',
'label':_("Build"),
'value':"",
'help':_("select the operation system by build")}
# path which contains images
cl_image_path = {'type':'list'}
def get_cl_image_arch_machine(self):
return self.Get('os_arch_machine')
def choice_cl_image_arch_machine(self):
return self.marches + ["auto"]
def set_cl_image_arch_machine(self,march):
if march == "auto":
march = getSupportArch()[-1]
return march
def get_cl_image_linux_shortname(self):
return self.Get('os_linux_shortname')
def choice_cl_image_linux_shortname(self):
return Linux.dictLinuxName.keys()
def get_cl_image_path(self):
"""Get available images search path"""
# if current distributive is live
if self.Get('os_root_type') == "livecd":
# if builder from flash then this source path '/mnt/flash'
# may be this path will be '/mnt/builder' for install
# modified system
if self.Get('os_scratch') == "on" and path.exists('/mnt/flash'):
livedistr = ['/mnt/flash']
# if system boot with kernel param 'docache'
elif path.exists('/mnt/squash'):
livedistr = ['/mnt/livecd']
# standard livecd
else:
livedistr = ['/mnt/cdrom']
else:
livedistr = []
# search all partition for source installation distributive
rootDev = self.Get('os_install_root_dev')
livedistr += \
map(lambda x:x[0],
filter(lambda x:" live" in x[1] and x[0] != rootDev,
zip(self.Get('os_disk_dev'),
self.Get('os_disk_content'))))
# add to standard path
return filter(path.exists,
['/var/calculate/remote/linux',
'/var/calculate/linux'] + livedistr)
def getImage(self,scratch,rootType,imagePath,march=None,
shortName=None,linuxVer=None,linuxBuild=None):
"""Get image by parameters"""
# exclude directory distributive for flash and scratch install
if scratch == "on" or rootType == "flash":
discardType = ["dir"]
else:
discardType = []
return self.getBestDistributive(imagePath,
march=march,
shortname=shortName,
discardType=discardType,
version=linuxVer,
build=linuxBuild)
def get_cl_image(self):
"""Get image file from distributive repository"""
if self.Get('cl_action') != 'system':
return Distributive.fromFile('/')
filename = self.Get('cl_image_filename')
if filename:
filename = Distributive.fromFile(filename)
return filename
def human_image_name(self,distroinfo,filepath):
distroinfo['name'] = distroinfo['name'].upper()
return "{name} {march} {build} ({filepath})".format(
filepath=filepath,**distroinfo)
def choice_cl_image_filename(self):
scratch = self.Get('os_install_scratch')
rootType = self.Get('os_install_root_type')
imagePath = self.Get('cl_image_path')
march = self.Get('cl_image_arch_machine')
shortName = self.Get('cl_image_linux_shortname')
linuxVer = self.Get('cl_image_linux_ver')
linuxBuild = self.Get('cl_image_linux_build')
if scratch == "on" or rootType == "flash":
discardType = ["dir"]
else:
discardType = []
distros = self.getAvailableDristibutives(imagePath,
march=march,
shortname=shortName,
discardType=discardType,
version=linuxVer,
build=linuxBuild)
return map(lambda x:(x,self.human_image_name(self._getDistrInfo(x),x)),
distros)
def get_cl_image_filename(self):
if self.Get('cl_action') != 'system':
return ""
return self.getImage(self.Get('os_install_scratch'),
self.Get('os_install_root_type'),
self.Get('cl_image_path'),
self.Get('cl_image_arch_machine'),
self.Get('cl_image_linux_shortname'),
self.Get('cl_image_linux_ver'),
self.Get('cl_image_linux_build'))
def human_cl_image(self):
filename = self.Get('cl_image')
if filename:
return filename.getType()
return filename
def check_cl_image_filename(self,isoimage):
"""Set image file"""
imageData = Distributive().getInfo(isoimage)
if not("name" in imageData and imageData.get('build','') and \
"march" in imageData):
raise VariableError(_("Wrong image file"))
contentCache = {}
marches = ['i686','x86_64']
extensiton = ['iso','tar.bz2','tar.gz','tar.7z','tar.lzma']
reDistName = re.compile("""
^.*/(?P<name>%(name)s)
-(?P<ver>%(ver)s)
-(?P<march>%(march)s)
.(?P<ext>%(ext)s)$""" %
{'name':"[a-z0-9]+",
'ver':r"(\d+\.)*\d+",
'march':"|".join(marches),
'ext':"|".join(extensiton)
}, re.X)
def _getDistrInfo(self,filename):
"""Get information by distributive"""
# if filename is directory
if not path.isfile(filename):
return Distributive().getInfo(filename)
else:
match = self.reDistName.match(filename)
if not match:
return {}
distdic = match.groupdict()
distdic["build"] = ""
if "ver" in distdic:
if re.match("^\d{8}$", distdic["ver"]):
distdic["build"] = distdic["ver"]
distdic["ver"] = ""
return distdic
def _getAvailableShortnames(self,dirs):
"""Get available distributives shortnames"""
distros = filter(lambda x:x,
map(self.reDistName.search,self._getAvailableDistributives(dirs)))
return sorted(list(set(map(lambda x:x.groupdict()['name'],distros))))
def opcompareByString(self,buf):
if buf:
reOp = re.compile("^(!=|=|==|<=|>=|>|<)?(\d+.*)$")
res = reOp.search(buf)
if res:
return ({'!=':operator.ne,
'=':operator.eq,
'==':operator.eq,
'>=':operator.ge,
'<=':operator.le,
'<':operator.lt,
'>':operator.gt}.get(res.group(1),operator.eq),
res.group(2))
else:
return operator.eq,buf
return None,None
def _getAvailableDistributives(self,dirs,system=None,shortname=None,march=None,
version=None,build=None):
"""Get all distributives by filter"""
def systemByName(name):
return Linux.dictNameSystem.get(name.upper(),"")
verCmp, version = self.opcompareByString(version)
if version:
version = getTupleVersion(version)
buildCmp, build = self.opcompareByString(build)
if build and build.isdigit():
build = int(build)
def distfilter(dist):
d = self._getDistrInfo(dist)
if not d:
return False
# check filter conditions
if system and systemByName(d['name']) != system:
return False
if not "name" in d or not "ver" in d:
return False
if shortname and d['name'].lower() != shortname.lower():
return False
if march and d['march'] != march:
return False
if version and not verCmp(getTupleVersion(d['ver']), version):
return False
if build and "build" in d and (not d['build'].isdigit() or
not buildCmp(int(d['build']),build)):
return False
return True
def listdistr(pathname):
if path.exists(path.join(pathname,'etc/make.profile')) or \
path.exists(path.join(pathname,'livecd')) or \
pathname.startswith('/dev/'):
return [pathname]
else:
# discard inner directories
return filter(lambda x:not path.isdir( path.join(pathname,x)),
listDirectory(pathname))
# get lists files in directories
allFiles = map(lambda x: map(lambda y: path.join(x,y),
listdistr(x)),
dirs)
# filter distributives
return filter(distfilter,
# join files lists to one list
reduce(lambda x,y: x + y,
allFiles, []))
def extcomparator(self,*exts):
"""Compare extensions"""
mapExts = {'iso':0,
'flash':-1,
'isodir':-2,
'partdir':-3,
'dir':-4}
return cmp(mapExts.get(exts[0],-4),mapExts.get(exts[1],-4))
def sortdistrfunc(self,x,y):
"""Func of comparing two distributive"""
ver1, ver2 = x[1].get('ver',""), y[1].get('ver',"")
if ver1 and ver2 and ver1 != "0" and ver2 != "0" and ver1 != ver2:
return cmpVersion(ver1,ver2)
build1 = getTupleVersion(x[1].get('build',""))
build2 = getTupleVersion(y[1].get('build',""))
if build1 != build2:
return cmp(build1,build2)
else:
ext1 = x[1].get('ext',"")
ext2 = y[1].get('ext',"")
return self.extcomparator(ext1,ext2)
def getAvailableDristibutives(self,dirs,system=None,shortname=None,
march=None, version=None, build=None,discardType=[]):
"""Get list available distributives"""
if shortname:
shortname = shortname.lower()
availDistrs = self._getAvailableDistributives(dirs,system,shortname,
march,version,
build)
availDistrs = filter(lambda x:x[1] and "ext" in x[1] and
not x[1]["ext"] in discardType,
map(lambda x:(x,self._getDistrInfo(x)),
availDistrs))
return map(lambda x:x[0],
sorted(availDistrs,self.sortdistrfunc,reverse=True))
def getBestDistributive(self,dirs,system=None,shortname=None,march=None,
version=None, build=None,discardType=[]):
"""Get the actualest distributive"""
availDistrs = self.getAvailableDristibutives(dirs,system,shortname,
march,version,build,discardType)
if availDistrs:
return availDistrs[0]
else:
return None
def _findLatestFile(self,dirs,reMatch,keyfunc):
"""Find latest file in dirs, which match by reMatch,
comparable part get by keyfunc"""
existsdirs = filter(path.exists,dirs)
listimgs = reduce(lambda x,y:x + \
map(lambda x:reMatch.search(path.join(y,x)),
listDirectory(y)),
existsdirs,[])
listimgs = filter(lambda x:x, listimgs)
if listimgs:
return max(listimgs,key=keyfunc).group()
return ""
def getBestStage(self,dirs,march=None,hardened=None):
"""Get latest stage by march"""
if march:
march = {'x86_64':'amd64'}.get(march,march)
else:
march = "[^-]+"
if hardened is None:
hardened = "(?:-hardened)?"
elif hardened == True:
hardened = "-hardened"
elif hardened == False:
hardened = ""
reStage = re.compile(r'^.*/stage3-%s%s-(\d+)\.tar\.bz2$'%
(march,hardened),re.S)
return self._findLatestFile(dirs,reStage,lambda x:x.groups()[0])
def choice_cl_image_arch_machine(self):
"""Get image arch"""
return ["i686","x86_64"]
def check_cl_image_linux_shortname(self,value):
if self.Get('cl_action') == 'system':
if not self.Get('cl_image'):
if not self.getImage(self.Get('os_install_scratch'),
self.Get('os_install_root_type'),
self.Get('cl_image_path'),
shortName=value):
raise VariableError(
_('Installation image of {0} not found').format(value))
def check_cl_image_arch_machine(self,value):
if self.Get('cl_action') == 'system':
if not self.Get('cl_image'):
if not self.getImage(self.Get('os_install_scratch'),
self.Get('os_install_root_type'),
self.Get('cl_image_path'),
march=value,
shortName=self.Get('cl_image_linux_shortname')):
raise VariableError(
_('Installation image of {distro} with '
"architecture '{arch}' not found").format(
distro=self.Get('cl_image_linux_shortname'),
arch=value))
def check_cl_image_linux_ver(self,value):
if self.Get('cl_action') == 'system':
if value and not self.Get('cl_image'):
if not self.getImage(self.Get('os_install_scratch'),
self.Get('os_install_root_type'),
self.Get('cl_image_path'),
march=self.Get('cl_image_arch_machine'),
shortName=self.Get('cl_image_linux_shortname'),
linuxVer=value):
raise VariableError(
_('Installation image of {distro} with '
"version '{ver}' not found").format(
distro="%s-%s"%
(self.Get('cl_image_linux_shortname'),
self.Get('cl_image_arch_machine')),
ver=value))
def check_cl_image_linux_build(self,value):
if self.Get('cl_action') == 'system':
if value and not self.Get('cl_image'):
raise VariableError(
_('Installation image with build {build} not found').format(
build=value))