parent
a466a26bf1
commit
dc3c55e2f1
@ -1 +0,0 @@
|
|||||||
__author__ = 'mhiretskiy'
|
|
@ -0,0 +1,71 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2015 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 sys
|
||||||
|
from os import path
|
||||||
|
from calculate.lib.utils.files import isMount
|
||||||
|
from calculate.lib.utils.tools import Locker, LockError
|
||||||
|
from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate, _)
|
||||||
|
from .datavars import builder_data
|
||||||
|
import hashlib
|
||||||
|
import random
|
||||||
|
|
||||||
|
setLocalTranslate('cl_builder3', sys.modules[__name__])
|
||||||
|
__ = getLazyLocalTranslate(_)
|
||||||
|
|
||||||
|
|
||||||
|
class DriveSpool(object):
|
||||||
|
"""
|
||||||
|
Объект содержит спул устройств на которые можно устанавливать систему
|
||||||
|
"""
|
||||||
|
spool_data = path.join('/run/calculate/drives_lock')
|
||||||
|
|
||||||
|
def __init__(self, devices, shuf=True):
|
||||||
|
self.devices = devices
|
||||||
|
if shuf:
|
||||||
|
random.shuffle(self.devices)
|
||||||
|
self.devices = iter(self.devices)
|
||||||
|
self.lockers = []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def device_id(device_name):
|
||||||
|
return device_name.replace('/', "_").lstrip("_")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_device(device):
|
||||||
|
return path.exists(device)
|
||||||
|
|
||||||
|
def lock_device(self, device):
|
||||||
|
if self.check_device(device) and not isMount(device):
|
||||||
|
device_hashfn = path.join(self.spool_data, self.device_id(device))
|
||||||
|
locker = Locker(fn=device_hashfn, timeout=0)
|
||||||
|
try:
|
||||||
|
locker.acquire()
|
||||||
|
self.lockers.append(locker)
|
||||||
|
return True
|
||||||
|
except LockError as e:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
for device in self.devices:
|
||||||
|
if self.lock_device(device):
|
||||||
|
return device
|
||||||
|
return None
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
for locker in self.lockers:
|
||||||
|
locker.remove()
|
||||||
|
self.lockers = []
|
@ -0,0 +1,47 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2015 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 sys
|
||||||
|
from calculate.core.server.func import Action, Tasks
|
||||||
|
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
|
||||||
|
from calculate.lib.utils.files import FilesError
|
||||||
|
from ..datavars import BuilderError
|
||||||
|
from calculate.lib.utils.portage import GitError
|
||||||
|
from calculate.install.distr import DistributiveError
|
||||||
|
|
||||||
|
setLocalTranslate('cl_builder3', sys.modules[__name__])
|
||||||
|
__ = getLazyLocalTranslate(_)
|
||||||
|
|
||||||
|
|
||||||
|
class ClBuilderBreakAction(Action):
|
||||||
|
"""
|
||||||
|
Действие обновление конфигурационных файлов
|
||||||
|
"""
|
||||||
|
# ошибки, которые отображаются без подробностей
|
||||||
|
native_error = (DistributiveError, FilesError, BuilderError, GitError)
|
||||||
|
|
||||||
|
successMessage = __("Assemble broken successfully")
|
||||||
|
failedMessage = __("Breaking the assemble is failed")
|
||||||
|
interruptMessage = __("Breaking manually interrupted")
|
||||||
|
|
||||||
|
# список задач для действия
|
||||||
|
tasks = [
|
||||||
|
{'name': 'close_build',
|
||||||
|
'message': __("Breaking {cl_builder_id} assemble"),
|
||||||
|
'method': 'Builder.close_build(cl_builder_build,cl_builder_clear_set)',
|
||||||
|
'condition': lambda Get: Get('cl_builder_build')
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,61 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2015 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 sys
|
||||||
|
from calculate.core.server.func import Action
|
||||||
|
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
|
||||||
|
from calculate.lib.utils.files import FilesError
|
||||||
|
from ..datavars import BuilderError
|
||||||
|
from calculate.lib.utils.portage import GitError
|
||||||
|
from calculate.install.distr import DistributiveError
|
||||||
|
|
||||||
|
setLocalTranslate('cl_builder3', sys.modules[__name__])
|
||||||
|
__ = getLazyLocalTranslate(_)
|
||||||
|
|
||||||
|
|
||||||
|
class ClBuilderRestoreAction(Action):
|
||||||
|
"""
|
||||||
|
Действие обновление конфигурационных файлов
|
||||||
|
"""
|
||||||
|
# ошибки, которые отображаются без подробностей
|
||||||
|
native_error = (DistributiveError, FilesError, BuilderError, GitError)
|
||||||
|
|
||||||
|
successMessage = __("Assemble broken successfully")
|
||||||
|
failedMessage = __("Breaking the assemble is failed")
|
||||||
|
interruptMessage = __("Breaking manually interrupted")
|
||||||
|
|
||||||
|
# список задач для действия
|
||||||
|
tasks = [
|
||||||
|
{'name': 'restore_build',
|
||||||
|
'message': __("Restoring {cl_builder_id} assemble"),
|
||||||
|
'method': 'Builder.restore_build(cl_builder_build)'
|
||||||
|
},
|
||||||
|
# подмонтировать необходимые данные
|
||||||
|
{'name': 'mount',
|
||||||
|
'message': __("Mounting target"),
|
||||||
|
'method': 'Builder.mount_target(cl_builder_target)',
|
||||||
|
},
|
||||||
|
# save
|
||||||
|
{'name': 'save',
|
||||||
|
'message': __("Save distro"),
|
||||||
|
'method': 'Builder.save_build(cl_builder_build)',
|
||||||
|
},
|
||||||
|
# закрепить подключенные данные
|
||||||
|
{'name': 'detach',
|
||||||
|
'message': __("Detach target"),
|
||||||
|
'method': 'Builder.detach_target(cl_builder_target)',
|
||||||
|
},
|
||||||
|
]
|
@ -0,0 +1,480 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2015 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 sys
|
||||||
|
from os import path
|
||||||
|
from calculate.install.distr import (Distributive, DistributiveError,
|
||||||
|
LayeredDistributive, DefaultMountPath, PartitionDistributive,
|
||||||
|
DirectoryDistributive)
|
||||||
|
from calculate.lib.utils.device import getUdevDeviceInfo, humanreadableSize
|
||||||
|
from calculate.lib.utils.files import isMount, process
|
||||||
|
from ..build_storage import BuildStorage, Build
|
||||||
|
from ..drive_spool import DriveSpool
|
||||||
|
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable
|
||||||
|
|
||||||
|
from calculate.lib.cl_lang import setLocalTranslate
|
||||||
|
setLocalTranslate('cl_builder3',sys.modules[__name__])
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderStorage(ReadonlyVariable):
|
||||||
|
type = "object"
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return BuildStorage()
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderAvailableDev(Variable):
|
||||||
|
"""
|
||||||
|
Список дисков, которые можно использовать для сборки
|
||||||
|
"""
|
||||||
|
type = "list"
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderDeviceSpool(ReadonlyVariable):
|
||||||
|
"""
|
||||||
|
Стэк дисков, которые можно использовать для сборки
|
||||||
|
"""
|
||||||
|
type = "object"
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
ds = DriveSpool(self.Get('cl_builder_available_dev'))
|
||||||
|
return ds
|
||||||
|
|
||||||
|
|
||||||
|
class BaseBuildId(Variable):
|
||||||
|
"""
|
||||||
|
Базовый класс для переменной id
|
||||||
|
"""
|
||||||
|
opt = ["--id"]
|
||||||
|
metavalue = "ID"
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
self.label = _("Build ID")
|
||||||
|
self.help = _("build ID")
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderSourceFilename(Variable):
|
||||||
|
"""
|
||||||
|
Названия файла исходного дистрибутива
|
||||||
|
"""
|
||||||
|
opt = ["--source"]
|
||||||
|
value = ""
|
||||||
|
metavalue = "SOURCE"
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
self.label = _("Source distribution")
|
||||||
|
self.help = _("source distribution")
|
||||||
|
|
||||||
|
def check(self, isoimage):
|
||||||
|
"""Set image file"""
|
||||||
|
if self.Get('cl_action') == 'create' and not isoimage:
|
||||||
|
raise VariableError(_("You need to select a source image"))
|
||||||
|
imageData = Distributive().getInfo(isoimage)
|
||||||
|
if not("os_linux_shortname" in imageData and
|
||||||
|
imageData.get('os_linux_build','') and
|
||||||
|
"os_arch_machine" in imageData):
|
||||||
|
raise VariableError(_("Wrong image file"))
|
||||||
|
|
||||||
|
def humanReadable(self):
|
||||||
|
fullname = self.Get('os_builder_linux_name')
|
||||||
|
subname = self.Get('os_builder_linux_subname')
|
||||||
|
if subname:
|
||||||
|
subname = " %s" % subname
|
||||||
|
arch = self.Get('os_builder_arch_machine')
|
||||||
|
build = self.Get('os_builder_linux_build')
|
||||||
|
ver = self.Get('os_builder_linux_ver')
|
||||||
|
|
||||||
|
return "{fullname} {ver} {arch} {build}".format(
|
||||||
|
fullname="%s%s" % (fullname, subname),
|
||||||
|
build=build, ver=ver, arch=arch)
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderSource(ReadonlyVariable):
|
||||||
|
"""
|
||||||
|
Объект исходного дистрибутива для разворачивания сборки
|
||||||
|
"""
|
||||||
|
type = "object"
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
"""Get image file from distributive repository"""
|
||||||
|
try:
|
||||||
|
filename = self.Get('cl_builder_source_filename')
|
||||||
|
if filename:
|
||||||
|
return Distributive.fromFile(filename)
|
||||||
|
except DistributiveError:
|
||||||
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def humanReadable(self):
|
||||||
|
filename = self.Get('cl_builder_source')
|
||||||
|
if filename:
|
||||||
|
return filename.getType()
|
||||||
|
return filename
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderDiskDev(Variable):
|
||||||
|
"""
|
||||||
|
Диск или директория, куда будет развёрнут образ
|
||||||
|
"""
|
||||||
|
untrusted = True
|
||||||
|
opt = ["-d", "--disk"]
|
||||||
|
metavalue = "DEST"
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
self.label = _("Assemble location")
|
||||||
|
self.help = _("partition or directory intended for assemble")
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
ds = self.Get('cl_builder_device_spool')
|
||||||
|
return ds.get().next()
|
||||||
|
|
||||||
|
def check(self, value):
|
||||||
|
if value.startswith("/dev"):
|
||||||
|
cnDisk = getUdevDeviceInfo(name=value).get('DEVNAME', value)
|
||||||
|
if cnDisk not in self.Get('install.os_disk_dev'):
|
||||||
|
raise VariableError(_("Wrong device '%s'") % value)
|
||||||
|
if not value.startswith('/'):
|
||||||
|
raise VariableError(
|
||||||
|
_("Wrong directory '%s'") % value)
|
||||||
|
if isMount(value):
|
||||||
|
raise VariableError(
|
||||||
|
_("Destination '%s' is already in use") % value)
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderDiskSize(ReadonlyVariable):
|
||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
type = "int"
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
self.label = _("Free disk space")
|
||||||
|
|
||||||
|
def get_free_for(self, dn):
|
||||||
|
try:
|
||||||
|
for dfdn in (dn, path.dirname(dn)):
|
||||||
|
dfProcess = process("/bin/df", "--output=avail", dfdn)
|
||||||
|
data = dfProcess.readlines()
|
||||||
|
if len(data) > 1:
|
||||||
|
return int(data[1].strip()) * 1024
|
||||||
|
except ValueError:
|
||||||
|
return 0
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def get_create(self):
|
||||||
|
device = self.Get('cl_builder_disk_dev')
|
||||||
|
if device:
|
||||||
|
if device.startswith('/dev/'):
|
||||||
|
return self.Select('install.os_disk_size',
|
||||||
|
where='install.os_disk_dev',
|
||||||
|
eq=device, limit=1) or "0"
|
||||||
|
else:
|
||||||
|
return str(self.get_free_for(device))
|
||||||
|
return "0"
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
action = self.Get('cl_action')
|
||||||
|
if action == 'create':
|
||||||
|
return self.get_create()
|
||||||
|
elif action in ('break', 'repair'):
|
||||||
|
return
|
||||||
|
|
||||||
|
def humanReadable(self):
|
||||||
|
return humanreadableSize(int(self.Get()))
|
||||||
|
|
||||||
|
class VariableClBuilderLayeredSet(Variable):
|
||||||
|
"""
|
||||||
|
Сборка будет выполняться в слое
|
||||||
|
"""
|
||||||
|
type = "bool"
|
||||||
|
opt = ["--layered"]
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
self.help = _("use layer for build")
|
||||||
|
self.label = _("Use layer for build")
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return "off"
|
||||||
|
|
||||||
|
def check(self, value):
|
||||||
|
if self.Get('cl_builder_disk_dev').startswith('/dev'):
|
||||||
|
raise VariableError(
|
||||||
|
_("Layers are used for building in a directory only"))
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderPath(ReadonlyVariable):
|
||||||
|
"""
|
||||||
|
Путь, где будет собираться дистрбутив
|
||||||
|
"""
|
||||||
|
def get(self):
|
||||||
|
image = self.Get('cl_builder_target')
|
||||||
|
if image:
|
||||||
|
return image.getDirectory()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderTarget(Variable):
|
||||||
|
"""
|
||||||
|
Объект собираемого дистрибутива
|
||||||
|
"""
|
||||||
|
type = "object"
|
||||||
|
|
||||||
|
def get_create(self):
|
||||||
|
builder_disk_dev = self.Get('cl_builder_disk_dev')
|
||||||
|
if not builder_disk_dev:
|
||||||
|
return ""
|
||||||
|
buildid = self.Get('cl_builder_id')
|
||||||
|
mountdir = path.join(DefaultMountPath.BaseMountPath, buildid)
|
||||||
|
source = self.Get('cl_builder_source_filename')
|
||||||
|
if self.GetBool('cl_builder_layered_set'):
|
||||||
|
distr = LayeredDistributive(mountdir, builder_disk_dev, source)
|
||||||
|
return distr
|
||||||
|
else:
|
||||||
|
if builder_disk_dev.startswith('/dev'):
|
||||||
|
distr = PartitionDistributive(builder_disk_dev,
|
||||||
|
mdirectory=mountdir)
|
||||||
|
return distr
|
||||||
|
else:
|
||||||
|
distr = DirectoryDistributive(builder_disk_dev,
|
||||||
|
mdirectory=mountdir)
|
||||||
|
return distr
|
||||||
|
|
||||||
|
def get_worked(self):
|
||||||
|
build = self.Get('cl_builder_build')
|
||||||
|
if build:
|
||||||
|
return build.distributive
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
if self.Get('cl_action') == 'create':
|
||||||
|
return self.get_create()
|
||||||
|
elif self.Get('cl_action') in ('break', 'restore'):
|
||||||
|
return self.get_worked()
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderClearSet(Variable):
|
||||||
|
"""
|
||||||
|
Очистить дистрибутив при отключении сборки
|
||||||
|
"""
|
||||||
|
type = "bool"
|
||||||
|
value = "off"
|
||||||
|
opt = ["--clear"]
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
self.label = _("Clear after unmount")
|
||||||
|
self.help = _("clear data after unmount")
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderBuild(Variable):
|
||||||
|
"""
|
||||||
|
Объект сборки
|
||||||
|
"""
|
||||||
|
type = "object"
|
||||||
|
|
||||||
|
def get_create(self):
|
||||||
|
distr = self.Get('cl_builder_target')
|
||||||
|
if not distr:
|
||||||
|
return ""
|
||||||
|
storage = self.Get('cl_builder_storage')
|
||||||
|
buildid = self.Get('cl_builder_id')
|
||||||
|
build = Build(buildid, distr, storage)
|
||||||
|
return build
|
||||||
|
|
||||||
|
def get_worked(self):
|
||||||
|
storage = self.Get('cl_builder_storage')
|
||||||
|
buildid = self.Get('cl_builder_id')
|
||||||
|
build = storage.get_build(buildid)
|
||||||
|
return build or ""
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
if self.Get('cl_action') == 'create':
|
||||||
|
return self.get_create()
|
||||||
|
if self.Get('cl_action') in ('break', 'restore'):
|
||||||
|
return self.get_worked()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderNewId(BaseBuildId):
|
||||||
|
"""
|
||||||
|
Id сборки при развертывании
|
||||||
|
"""
|
||||||
|
value = ""
|
||||||
|
untrusted = True
|
||||||
|
|
||||||
|
def check(self, value):
|
||||||
|
if not value:
|
||||||
|
raise VariableError(_("Please specify the id"))
|
||||||
|
if value in self.Get('cl_builder_storage'):
|
||||||
|
raise VariableError(_("Assemble %s already exists")%value)
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderPreparedId(BaseBuildId):
|
||||||
|
"""
|
||||||
|
Id развёрнутой сборки
|
||||||
|
"""
|
||||||
|
type = "choice"
|
||||||
|
untrusted = True
|
||||||
|
|
||||||
|
def available(self):
|
||||||
|
bs = self.Get('cl_builder_storage')
|
||||||
|
action = self.Get('cl_action')
|
||||||
|
for x in bs:
|
||||||
|
build = bs.get_build(x)
|
||||||
|
if action == 'break' or build.status == Build.Status.WORKED:
|
||||||
|
yield x
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
l = list(self.available())
|
||||||
|
if l and len(l) == 1:
|
||||||
|
return l[0]
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def choice(self):
|
||||||
|
def generator():
|
||||||
|
bs = self.Get('cl_builder_storage')
|
||||||
|
for x in bs:
|
||||||
|
build = bs.get_build(x)
|
||||||
|
if build.status == Build.Status.BROKEN:
|
||||||
|
yield (x, "%s (%s)" % (x, _("broken")))
|
||||||
|
else:
|
||||||
|
yield (x, x)
|
||||||
|
|
||||||
|
return list(generator())
|
||||||
|
|
||||||
|
def check(self, value):
|
||||||
|
if not value:
|
||||||
|
raise VariableError(_("Please select the assemble id"))
|
||||||
|
l = self.available()
|
||||||
|
if not l:
|
||||||
|
raise VariableError(_("Assemble %s is not found") % value)
|
||||||
|
if (self.Get('cl_builder_build').status == Build.Status.BROKEN and
|
||||||
|
self.Get('cl_action') != 'break'):
|
||||||
|
raise VariableError(
|
||||||
|
_("Assemble %s is broken, try to restore build") % value)
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderBrokenId(BaseBuildId):
|
||||||
|
"""
|
||||||
|
Id развёрнутой сборки
|
||||||
|
"""
|
||||||
|
type = "choice"
|
||||||
|
untrusted = True
|
||||||
|
|
||||||
|
def available(self):
|
||||||
|
bs = self.Get('cl_builder_storage')
|
||||||
|
for x in bs:
|
||||||
|
build = bs.get_build(x)
|
||||||
|
if build.status == Build.Status.BROKEN:
|
||||||
|
yield x
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
l = list(self.available())
|
||||||
|
if l and len(l) == 1:
|
||||||
|
return l[0]
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def choice(self):
|
||||||
|
def generator():
|
||||||
|
bs = self.Get('cl_builder_storage')
|
||||||
|
for x in bs:
|
||||||
|
build = bs.get_build(x)
|
||||||
|
if build.status == Build.Status.BROKEN:
|
||||||
|
yield (x, "%s (%s)" % (x, _("broken")))
|
||||||
|
|
||||||
|
return list(generator())
|
||||||
|
|
||||||
|
def check(self, value):
|
||||||
|
if not value:
|
||||||
|
raise VariableError(_("Please select the assemble id"))
|
||||||
|
l = list(self.available())
|
||||||
|
if not l:
|
||||||
|
raise VariableError(_("Assemble %s is not found") % value)
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderId(ReadonlyVariable):
|
||||||
|
"""
|
||||||
|
Общий id сборки
|
||||||
|
"""
|
||||||
|
def get(self):
|
||||||
|
action = self.Get('cl_action')
|
||||||
|
if action == 'create':
|
||||||
|
return self.Get('cl_builder_new_id')
|
||||||
|
elif action == 'break':
|
||||||
|
return self.Get('cl_builder_prepared_id')
|
||||||
|
elif action == 'restore':
|
||||||
|
return self.Get('cl_builder_broken_id')
|
||||||
|
|
||||||
|
|
||||||
|
class VariableOsBuilderMakeopts(Variable):
|
||||||
|
"""
|
||||||
|
Параметры MAKEOPTS
|
||||||
|
"""
|
||||||
|
def get(self):
|
||||||
|
return self.Get('install.os_install_makeopts')
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderBuildpkgSet(Variable):
|
||||||
|
"""
|
||||||
|
Собирать бинарные пакеты в сборке
|
||||||
|
"""
|
||||||
|
type = "bool"
|
||||||
|
value = "off"
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderBasePath(Variable):
|
||||||
|
"""
|
||||||
|
Базовый путь до сборок (директория, куда будут помещены готовые
|
||||||
|
iso образы, бинарные пакеты и т.д.)
|
||||||
|
"""
|
||||||
|
value = "/var/calculate/remote/assemble"
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderParentPath(ReadonlyVariable):
|
||||||
|
"""
|
||||||
|
Путь в ".." до родительской системы
|
||||||
|
"""
|
||||||
|
def get(self):
|
||||||
|
builder_path = self.Get('cl_builder_path')
|
||||||
|
return ("../"*len(filter(None,
|
||||||
|
builder_path.split('/'))))[:-1]
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderPkgdir(Variable):
|
||||||
|
"""
|
||||||
|
Путь собираемых бинарных архивов
|
||||||
|
"""
|
||||||
|
def fallback(self):
|
||||||
|
return path.join(self.Get('cl_builder_base_path'),
|
||||||
|
self.Get('cl_builder_id'), "packages")
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
action = self.Get('cl_action')
|
||||||
|
if action == 'create':
|
||||||
|
return self.fallback()
|
||||||
|
elif action in ('restore',):
|
||||||
|
build = self.Get('cl_builder_build')
|
||||||
|
return build.pkgdir or self.fallback()
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderAction(ReadonlyVariable):
|
||||||
|
"""
|
||||||
|
Дополнительное действие по созданию образа: iso, squash.
|
||||||
|
"""
|
||||||
|
value = ""
|
@ -0,0 +1,115 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2015 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 sys
|
||||||
|
import os
|
||||||
|
from os import path
|
||||||
|
from calculate.lib.datavars import ReadonlyVariable
|
||||||
|
|
||||||
|
from calculate.lib.cl_lang import setLocalTranslate
|
||||||
|
|
||||||
|
setLocalTranslate('cl_builder3', sys.modules[__name__])
|
||||||
|
|
||||||
|
|
||||||
|
class BuilderLinux(ReadonlyVariable):
|
||||||
|
# variable for get current system info (example: os_linux_shortname)
|
||||||
|
variable = ""
|
||||||
|
# field of distroinfo (name,ver,build,march and etc)
|
||||||
|
distroinfo_field = ""
|
||||||
|
|
||||||
|
def source_data(self):
|
||||||
|
image = self.Get('cl_builder_source')
|
||||||
|
if image:
|
||||||
|
d = image.getInfo()
|
||||||
|
res = d.get(self.variable, "")
|
||||||
|
return str(res()) if callable(res) else res
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def target_data(self):
|
||||||
|
image = self.Get('cl_builder_target')
|
||||||
|
if image:
|
||||||
|
d = image.getInfo()
|
||||||
|
res = d.get(self.variable, "")
|
||||||
|
return str(res()) if callable(res) else res
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
"""Get by distroinfo or current info"""
|
||||||
|
if self.Get('cl_action') == 'create':
|
||||||
|
return self.source_data()
|
||||||
|
elif self.Get('cl_action') in ('break', 'restore'):
|
||||||
|
return self.target_data()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
class VariableOsBuilderLinuxShortname(BuilderLinux):
|
||||||
|
"""Shortname of system"""
|
||||||
|
variable = "os_linux_shortname"
|
||||||
|
|
||||||
|
|
||||||
|
class VariableOsBuilderLinuxVer(BuilderLinux):
|
||||||
|
"""Shortname of system"""
|
||||||
|
variable = "os_linux_ver"
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
self.label = _("Building system version")
|
||||||
|
|
||||||
|
class VariableOsBuilderLinuxBuild(BuilderLinux):
|
||||||
|
"""Shortname of system"""
|
||||||
|
variable = "os_linux_build"
|
||||||
|
|
||||||
|
|
||||||
|
class VariableOsBuilderArchMachine(BuilderLinux):
|
||||||
|
"""Shortname of system"""
|
||||||
|
variable = "os_arch_machine"
|
||||||
|
|
||||||
|
|
||||||
|
class VariableOsBuilderLinuxFiles(BuilderLinux):
|
||||||
|
"""Shortname of system"""
|
||||||
|
variable = "os_linux_files"
|
||||||
|
|
||||||
|
|
||||||
|
class VariableOsBuilderLinuxName(BuilderLinux):
|
||||||
|
"""
|
||||||
|
Install distro name
|
||||||
|
"""
|
||||||
|
variable = "os_linux_name"
|
||||||
|
|
||||||
|
|
||||||
|
class VariableOsBuilderLinuxSystem(BuilderLinux):
|
||||||
|
"""
|
||||||
|
Install system name
|
||||||
|
"""
|
||||||
|
variable = "os_linux_system"
|
||||||
|
|
||||||
|
|
||||||
|
class VariableOsBuilderLinuxSubname(BuilderLinux):
|
||||||
|
"""
|
||||||
|
Install subname
|
||||||
|
"""
|
||||||
|
variable = "os_linux_subname"
|
||||||
|
|
||||||
|
|
||||||
|
class VariableClBuilderProfileName(BuilderLinux):
|
||||||
|
"""
|
||||||
|
Install subname
|
||||||
|
"""
|
||||||
|
def init(self):
|
||||||
|
self.label = _("System profile")
|
||||||
|
|
||||||
|
variable = "cl_profile_name"
|
Loading…
Reference in new issue