Добавлены действия: развертывание, прерывание и восстановлне.

Mike Khiretskiy 9 years ago
parent a466a26bf1
commit dc3c55e2f1

@ -1 +0,0 @@
__author__ = 'mhiretskiy'

@ -26,8 +26,9 @@ import time
from calculate.lib.configparser import ConfigParser
from calculate.lib.utils.files import (readFile, listDirectory, isMount,
writeFile)
from .builder import BuilderError
from .datavars import BuilderError
from calculate.lib.utils.tools import Locker, LockError
from .datavars import builder_data
setLocalTranslate('cl_builder3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
@ -48,6 +49,7 @@ class Build(object):
self.distributive = distributive
self.parent = parent
self.id = build_id
self.pkgdir = ""
self._hash = None
if not restore:
self.parent.reserve_id(self.id)
@ -84,7 +86,8 @@ class Build(object):
"""
Удалить сборку
"""
if self.status in (Build.Status.REGISTERED, Build.Status.WORKED):
if self.status in (Build.Status.REGISTERED, Build.Status.WORKED,
Build.Status.BROKEN):
self.parent.remove_build(self)
self.status = Build.Status.REMOVED
self.id = None
@ -110,7 +113,7 @@ class BuildStorage(object):
Хранилище в котором находится информация о собираемом дистрибутиве
"""
ini_file = "/etc/calculate/assemble.env"
data_dir = "/var/lib/calculate/calculate-assemble"
data_dir = path.join(builder_data, "mount")
def __init__(self, data_dir=None, ini_file=None):
if ini_file:
@ -118,7 +121,7 @@ class BuildStorage(object):
if data_dir:
self.data_dir = data_dir
if not path.exists(self.data_dir):
os.mkdir(self.data_dir)
os.makedirs(self.data_dir)
self.locker = Locker(fn=self.ini_file)
def _get_ini(self):
@ -163,9 +166,11 @@ class BuildStorage(object):
build_directory = build.distributive.getDirectory()
build_id = build.id
build_hash = build.build_hash
build_pkgdir = build.pkgdir
with self.modify_ini() as ini:
ini[build_id]['hash'] = build_hash
ini[build_id]['directory'] = build_directory
ini[build_id]['pkgdir'] = build_pkgdir
mount_dump_file = self.get_dump_name(build.build_hash)
with writeFile(mount_dump_file) as f:
@ -230,6 +235,7 @@ class BuildStorage(object):
build.status = build.Status.WORKED
else:
build.status = build.Status.BROKEN
build.pkgdir = ini.get(build_id, 'pkgdir', fallback=None)
return build
def remove_build(self, build):

@ -13,24 +13,53 @@
# 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 random
import sys
import os
from os import path
from calculate.lib.utils.tools import AddonError
from .build_storage import Build
from calculate.install.distr import Distributive
from .datavars import BuilderError
from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate,
RegexpLocalization, _)
from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate, _)
setLocalTranslate('cl_builder3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
class BuilderError(AddonError):
"""Builder Error"""
class Builder(object):
"""Основной объект для выполнения действий связанных со сборкой системы
"""
def init(self):
pass
def mount_target(self, target):
dir_distro = target.convertToDirectory()
dir_distro.mountSystemDirectories()
return True
def detach_target(self, target):
"""
@type target: Distributive
"""
if target:
target.reserve()
return True
def close_build(self, build, clear=False):
"""
@type build:Build
"""
if build:
build.remove()
build.close_distributive()
if clear:
build.distributive.post_clear()
return True
def restore_build(self, build):
if build:
build.restore()
return True
def save_build(self, build):
build.pkgdir = self.clVars.Get('cl_builder_pkgdir')
build.save()
return True

@ -13,21 +13,27 @@
# 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.
from version import __app__, __version__
import os
import sys
from calculate.lib.datavars import DataVars
from calculate.lib.utils.tools import AddonError
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_builder3',sys.modules[__name__])
builder_data = "/var/lib/calculate/calculate-builder"
class BuilderError(AddonError):
"""Builder Error"""
class DataVarsBuilder(DataVars):
"""Variable class for desktop package"""
var_module = "update"
var_module = "builder"
def importBuilder(self, **args):
"""Import desktop variables"""
self.importVariables()
self.importVariables('calculate.%s.variables'%self.var_module)
self.importVariables('calculate.%s.variables' % self.var_module)
self.defaultModule = self.var_module

@ -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')
}
]

@ -1,4 +1,4 @@
#-*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# Copyright 2015 Calculate Ltd. http://www.calculate-linux.org
#
@ -18,8 +18,9 @@ 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 ..builder import BuilderError
from ..datavars import BuilderError
from calculate.lib.utils.portage import GitError
from calculate.install.distr import DistributiveError
setLocalTranslate('cl_builder3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
@ -30,12 +31,47 @@ class ClBuilderCreateAction(Action):
Действие обновление конфигурационных файлов
"""
# ошибки, которые отображаются без подробностей
native_error = (FilesError, BuilderError, GitError)
native_error = (DistributiveError, FilesError, BuilderError, GitError)
successMessage = __("The profile was successfully updated")
failedMessage = __("Failed to update the profile")
interruptMessage = __("Profile update manually interrupted")
successMessage = __("Assemble prepared successfully")
failedMessage = __("Preparing the assemble is failed")
interruptMessage = __("Assemble manually interrupted")
# список задач для дейсвия
# список задач для действия
tasks = [
]
# форматирование раздела при необходимости
{'name': 'format',
'message': __("Formatting the partitions"),
'method': 'Install.format(cl_builder_target)',
'condition': lambda Get: Get('cl_builder_target').needFormat
},
# распаковка дистрибутива
{'name': 'unpack',
'message': __("Unpacking the system image to the target"),
'method': 'Install.unpack(cl_builder_source,cl_builder_target,'
'os_builder_linux_files)',
},
# подмонтировать необходимые данные
{'name': 'mount',
'message': __("Mounting resources"),
'method': 'Builder.mount_target(cl_builder_target)',
},
{'name': 'apply_template',
'message': __("Configuring build"),
# наложить шаблоны в развернутый дистрибутив
'method': 'Builder.applyTemplates(cl_builder_target,False,False,None)',
},
# save
{'name': 'save',
'method': 'Builder.save_build(cl_builder_build)',
},
# закрепить подключенные данные
{'name': 'detach',
'method': 'Builder.detach_target(cl_builder_target)',
},
{'name':'close_build',
'warning': _("Umount distributives"),
'method': 'Builder.close_build(cl_builder_build)',
'depend': Tasks.failed(),
'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)',
},
]

@ -15,5 +15,7 @@
# limitations under the License.
import action
import builder
import linux
section = "builder"

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org
# 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.
@ -14,32 +14,54 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
from os import path
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_builder3',sys.modules[__name__])
class VariableAcBuilderSquash(ReadonlyVariable):
"""
Action variable which has value "on" for package install and
install this package
Action variable which has value "on" for prepare squash
"""
def get(self):
action = self.Get("cl_action")
if action in ("squash",):
image_action = self.Get('cl_builder_action')
if action == 'image' and image_action == "squash":
return "on"
return "off"
class VariableAcBuilderIso(ReadonlyVariable):
"""
Action variable which has value "on" for package install and
install this package
Action variable which has value "on" for prepare iso
"""
def get(self):
action = self.Get("cl_action")
if action in ("iso",):
image_action = self.Get('cl_builder_action')
if action == 'image' and image_action == "iso":
return "on"
return "off"
class VariableAcBuilderSetup(ReadonlyVariable):
"""
Action variable which has value "on" for setup build directory
"""
def get(self):
action = self.Get('cl_action')
if action in ("create",):
return "on"
return "off"
class VariableAcBuilderPrepare(ReadonlyVariable):
"""
Action variable which has value "on" for setup build directory
"""
def get(self):
action = self.Get('cl_action')
if action in ("create",):
return "on"
return "off"

@ -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"

@ -19,10 +19,13 @@ import sys
from calculate.lib.datavars import VariableError,DataVarsError,DataVars
from calculate.core.server.func import WsdlBase
from calculate.install.install import InstallError
from .builder import BuilderError, Builder
from calculate.install.install import InstallError, Install
from .builder import Builder
from .datavars import BuilderError
from calculate.lib.utils.portage import GitError
from utils.cl_builder_create import ClBuilderCreateAction
from utils.cl_builder_break import ClBuilderBreakAction
from utils.cl_builder_restore import ClBuilderRestoreAction
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate
setLocalTranslate('cl_builder3',sys.modules[__name__])
__ = getLazyLocalTranslate(_)
@ -49,7 +52,8 @@ class Wsdl(WsdlBase):
# права для запуска метода
'rights': ['build'],
# объект содержащий модули для действия
'logic': {'Builder': Builder},
'logic': {'Builder': Builder,
'Install': Install},
# описание действия
'action': ClBuilderCreateAction,
# объект переменных
@ -57,14 +61,129 @@ class Wsdl(WsdlBase):
'native_error': (VariableError, DataVarsError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'create'},
'setvars': {'cl_action!': 'create',
'cl_dispatch_conf': 'usenew'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Create the system"),
normal=(),
expert=(
'cl_templates_locate',
'cl_verbose_set', 'cl_dispatch_conf'),
normal=('cl_builder_source_filename',
'cl_builder_new_id',
'cl_builder_disk_dev',
'cl_builder_layered_set'),
expert=('cl_templates_locate',
'cl_verbose_set',
'cl_dispatch_conf'),
hide=('cl_templates_locate',
'cl_verbose_set',
'cl_dispatch_conf'),
brief=('os_builder_linux_ver',
'cl_builder_disk_size',
'cl_builder_profile_name'),
next_label=_("Perform"))],
'brief': {'next': __("Perform"),
'name': __("Create the system")},
},
{
# идентификатор метода
'method_name': "builder_break",
# категория метода
'category': __('Builder'),
# заголовок метода
'title': __("Break the assemble"),
# иконка для графической консоли
'image': 'calculate-update',
# метод присутствует в графической консоли
'gui': True,
# консольная команда
'command': 'cl-builder-break',
# права для запуска метода
'rights': ['build'],
# объект содержащий модули для действия
'logic': {'Builder': Builder,
'Install': Install},
# описание действия
'action': ClBuilderBreakAction,
# объект переменных
'datavars': "builder",
'native_error': (VariableError, DataVarsError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'break'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Break the assemble"),
normal=('cl_builder_prepared_id',
'cl_builder_clear_set'),
expert=('cl_templates_locate',
'cl_verbose_set', 'cl_dispatch_conf'),
next_label=_("Perform"))]
},
{
# идентификатор метода
'method_name': "builder_restore",
# категория метода
'category': __('Builder'),
# заголовок метода
'title': __("Restore the assemble"),
# иконка для графической консоли
'image': 'calculate-update',
# метод присутствует в графической консоли
'gui': True,
# консольная команда
'command': 'cl-builder-restore',
# права для запуска метода
'rights': ['build'],
# объект содержащий модули для действия
'logic': {'Builder': Builder,
'Install': Install},
# описание действия
'action': ClBuilderRestoreAction,
# объект переменных
'datavars': "builder",
'native_error': (VariableError, DataVarsError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'restore'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Break the assemble"),
normal=('cl_builder_broken_id',),
expert=('cl_templates_locate',
'cl_verbose_set', 'cl_dispatch_conf'),
next_label=_("Perform"))]
},
{
# идентификатор метода
'method_name': "builder_image",
# категория метода
'category': __('Builder'),
# заголовок метода
'title': __("Create the image"),
# иконка для графической консоли
'image': 'calculate-update',
# метод присутствует в графической консоли
'gui': True,
# консольная команда
'command': 'cl-builder-image',
# права для запуска метода
'rights': ['build'],
# объект содержащий модули для действия
'logic': {'Builder': Builder,
'Install': Install},
# описание действия
'action': ClBuilderImageAction,
# объект переменных
'datavars': "builder",
'native_error': (VariableError, DataVarsError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'image'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Break the assemble"),
normal=('cl_builder_broken_id',),
expert=('cl_templates_locate',
'cl_verbose_set', 'cl_dispatch_conf'),
next_label=_("Perform"))]
}
]

Loading…
Cancel
Save