|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
# Copyright 2010-2016 Mir Calculate. 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 re
|
|
|
import sys
|
|
|
import time
|
|
|
from os import path
|
|
|
from random import choice
|
|
|
import string
|
|
|
import glob
|
|
|
import shutil
|
|
|
from time import sleep
|
|
|
from calculate.core.server.func import MethodsInterface
|
|
|
from calculate.core.server.admin import Admins
|
|
|
from calculate.lib.utils.mount import isMount
|
|
|
from calculate.lib.utils.files import (pathJoin,
|
|
|
process, listDirectory,
|
|
|
checkUtils, readFile, find, copyWithPath,
|
|
|
readLinesFile, getProgPath)
|
|
|
import calculate.lib.utils.device as device
|
|
|
from calculate.lib.utils.device import (detectDeviceForPartition,
|
|
|
countPartitions)
|
|
|
from datavars import DataVarsInstall
|
|
|
from calculate.install.variables.autopartition import AutoPartition
|
|
|
|
|
|
from distr import DistributiveError
|
|
|
from subprocess import Popen, PIPE, STDOUT
|
|
|
from itertools import *
|
|
|
|
|
|
|
|
|
class InstallError(Exception):
|
|
|
"""Installation Error"""
|
|
|
|
|
|
|
|
|
from migrate_users import migrate
|
|
|
|
|
|
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
|
|
|
|
|
|
setLocalTranslate('cl_install3', sys.modules[__name__])
|
|
|
__ = getLazyLocalTranslate(_)
|
|
|
|
|
|
|
|
|
class Install(MethodsInterface):
|
|
|
"""Primary class for templates applying and system installation"""
|
|
|
|
|
|
def __init__(self):
|
|
|
self.clVars = None
|
|
|
# refresh information about LVM
|
|
|
device.lvm.refresh()
|
|
|
# refresh information about device in udevadm info
|
|
|
device.udev.refresh()
|
|
|
|
|
|
def initVars(self, datavars=None):
|
|
|
"""Primary initialization of variables"""
|
|
|
if not datavars:
|
|
|
self.clVars = DataVarsInstall()
|
|
|
self.clVars.importInstall()
|
|
|
self.clVars.flIniFile()
|
|
|
else:
|
|
|
self.clVars = datavars
|
|
|
|
|
|
def canInstallGrub2(self, target):
|
|
|
"""Check that system has grub2 in current and installed system"""
|
|
|
if self.clVars.Get('os_grub2_path'):
|
|
|
return bool(
|
|
|
filter(lambda x: (x.startswith('grub-1.99') or
|
|
|
x.startswith('grub-2')),
|
|
|
listDirectory('/var/db/pkg/sys-boot')))
|
|
|
return False
|
|
|
|
|
|
def prepareBoot(self, target_distr):
|
|
|
"""Prepare system for boot"""
|
|
|
if self.clVars.Get('os_install_root_type') == "flash":
|
|
|
self.installSyslinuxBootloader(target_distr)
|
|
|
else:
|
|
|
if self.canInstallGrub2(target_distr):
|
|
|
self.installGrub2Bootloader(target_distr)
|
|
|
else:
|
|
|
self.installLegacyGrubBootloader(target_distr)
|
|
|
return True
|
|
|
|
|
|
def setActivePartition(self, partition):
|
|
|
"""
|
|
|
Установка активного раздела для dos и gpt таблицы разделов
|
|
|
"""
|
|
|
device_name = detectDeviceForPartition(partition)
|
|
|
if device_name is None:
|
|
|
raise DistributiveError(
|
|
|
_("Failed to determine the parent device for %s") % partition)
|
|
|
# device hasn't any partition
|
|
|
elif device_name == "":
|
|
|
return True
|
|
|
fdisk_cmd, gdisk_cmd, parted_cmd = checkUtils('/sbin/fdisk',
|
|
|
'/usr/sbin/gdisk',
|
|
|
'/usr/sbin/parted')
|
|
|
|
|
|
disk = self.clVars.Select('os_install_disk_parent',
|
|
|
where='os_install_disk_dev', eq=partition,
|
|
|
limit=1)
|
|
|
partition_table = self.clVars.Select('os_device_table',
|
|
|
where='os_device_dev',
|
|
|
eq=disk, limit=1)
|
|
|
info = device.udev.get_device_info(name=partition)
|
|
|
partition_number = (
|
|
|
info.get('ID_PART_ENTRY_NUMBER', '') or
|
|
|
info.get('UDISKS_PARTITION_NUMBER', ''))
|
|
|
|
|
|
device_partition_count = countPartitions(device_name)
|
|
|
if device_name and not partition_number:
|
|
|
raise DistributiveError(
|
|
|
_("Failed to determine the partition number for %s")
|
|
|
% partition)
|
|
|
boot_flag = "boot" if partition_table == "dos" else "legacy_boot"
|
|
|
if partition_table == "dos":
|
|
|
fdisk = process(fdisk_cmd, "-l", device_name)
|
|
|
DEVICENUM, AFLAG = 0, 1
|
|
|
change_active = map(
|
|
|
lambda x: x[DEVICENUM],
|
|
|
filter(
|
|
|
lambda x: (x[DEVICENUM] != partition_number and
|
|
|
x[AFLAG] == "*" or
|
|
|
x[DEVICENUM] == partition_number and
|
|
|
not x[AFLAG] == "*"),
|
|
|
list(map(
|
|
|
lambda x: [str(x[0]), x[1][1].strip()],
|
|
|
# enumerate partitions
|
|
|
enumerate(filter(None, map(
|
|
|
lambda x: x.split()[:2],
|
|
|
# drop string before information about partitions
|
|
|
dropwhile(
|
|
|
lambda x: not x.lstrip().startswith(
|
|
|
"Device"),
|
|
|
fdisk.readlines()))))))[1:]))
|
|
|
else:
|
|
|
parted = process(parted_cmd, "-m", device_name, "print")
|
|
|
DEVICENUM, FLAGS = 0, 6
|
|
|
change_active = map(
|
|
|
lambda x: x[DEVICENUM], filter(
|
|
|
lambda x: (x[DEVICENUM] != partition_number and
|
|
|
boot_flag in x[FLAGS].strip(';').split(', ') or
|
|
|
x[DEVICENUM] == partition_number and
|
|
|
boot_flag not in
|
|
|
x[FLAGS].strip(';').split(', ')),
|
|
|
filter(lambda x: len(x) >= 7,
|
|
|
map(lambda x: x.split(':'),
|
|
|
parted.readlines()[2:]))))
|
|
|
if not change_active:
|
|
|
return True
|
|
|
if partition_table == "dos":
|
|
|
pipe = Popen([fdisk_cmd, device_name],
|
|
|
stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
|
|
for part_num in change_active:
|
|
|
pipe.stdin.write("a\n%s\n" % part_num)
|
|
|
pipe.stdin.write("w\n")
|
|
|
pipe.stdin.close()
|
|
|
pipe.wait()
|
|
|
elif partition_table == "gpt":
|
|
|
pipe = Popen([gdisk_cmd, device_name],
|
|
|
stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
|
|
if device_partition_count > 1:
|
|
|
pipe.stdin.write("x\n")
|
|
|
for part_num in change_active:
|
|
|
pipe.stdin.write("a\n%s\n2\n\n" % part_num)
|
|
|
pipe.stdin.write("w\nY\n")
|
|
|
else:
|
|
|
pipe.stdin.write("x\na\n2\n\nw\nY\n")
|
|
|
pipe.stdin.close()
|
|
|
pipe.wait()
|
|
|
for wait_time in (0.1, 0.2, 0.5, 1, 2, 4):
|
|
|
if path.exists(partition):
|
|
|
return True
|
|
|
else:
|
|
|
sleep(wait_time)
|
|
|
raise InstallError(
|
|
|
_("Failed to find partition %s after changing the activity") %
|
|
|
partition)
|
|
|
|
|
|
def installSyslinuxBootloader(self, target):
|
|
|
"""
|
|
|
Установить syslinux загрузчик (используется для flash)
|
|
|
"""
|
|
|
if not self.clVars.Get('os_install_mbr'):
|
|
|
return
|
|
|
# прописать MBR
|
|
|
dd_process = process("/bin/dd", "if=/usr/share/syslinux/mbr.bin",
|
|
|
"of=%s" % self.clVars.Get('os_install_mbr')[0],
|
|
|
stderr=STDOUT)
|
|
|
if dd_process.failed():
|
|
|
raise DistributiveError(
|
|
|
_("Failed to write the master boot record\n%s") %
|
|
|
dd_process.read())
|
|
|
target.close()
|
|
|
# выполнить установку syslinux загрузчика
|
|
|
install_root_dev = self.clVars.Get('os_install_root_dev')
|
|
|
syslinux_process = process("/usr/bin/syslinux",
|
|
|
install_root_dev, stderr=STDOUT)
|
|
|
if syslinux_process.failed():
|
|
|
raise DistributiveError(_("Failed to install syslinux\n%s") %
|
|
|
syslinux_process.read())
|
|
|
# установить загрузочный раздел активным
|
|
|
return self.setActivePartition(self.clVars.Get('os_install_root_dev'))
|
|
|
|
|
|
def installGrub2Bootloader(self, target):
|
|
|
"""
|
|
|
Установка GRUB2 загрузчика
|
|
|
"""
|
|
|
# проверить наличие grub2
|
|
|
cmd_grub_install = self.clVars.Get('os_grub2_path')
|
|
|
if not cmd_grub_install:
|
|
|
raise DistributiveError(_("Failed to install the bootloader"))
|
|
|
process("sync").success()
|
|
|
# если установка GRUB2 производится на текущую систему
|
|
|
# загруженную в builder режиме
|
|
|
if (self.clVars.Get('os_install_scratch') == "on" and
|
|
|
self.clVars.Get('cl_action') != "system"):
|
|
|
prefix_boot = "/mnt/scratch"
|
|
|
else:
|
|
|
prefix_boot = "/"
|
|
|
# установка UEFI
|
|
|
if self.clVars.GetBool('os_install_uefi_set'):
|
|
|
self.install_grub_uefi(cmd_grub_install, prefix_boot, target)
|
|
|
# не UEFI установка
|
|
|
else:
|
|
|
self.install_grub_biosboot(cmd_grub_install, prefix_boot, target)
|
|
|
|
|
|
def install_grub_biosboot(self, cmd_grub_install, prefix_boot, target):
|
|
|
"""
|
|
|
Установить GRUB, загрузчик MBR (GPT)
|
|
|
"""
|
|
|
# получить загрузочный раздел (если есть /boot, то
|
|
|
# он является загрузочным иначе корень)
|
|
|
for boot_path in ("/boot", "/"):
|
|
|
boot_disk = self.clVars.Select("os_install_disk_dev",
|
|
|
where="os_install_disk_mount",
|
|
|
eq=boot_path, limit=1)
|
|
|
if boot_disk:
|
|
|
self.setActivePartition(boot_disk)
|
|
|
break
|
|
|
|
|
|
# если GRUB2 версии 2.00 и выше, обычная установка требует
|
|
|
# параметра --target=i386-pc, иначе GRUB2 может попытаться
|
|
|
# прописать себя как UEFI
|
|
|
if filter(lambda x: "2." in x,
|
|
|
process(cmd_grub_install, '--version')):
|
|
|
platform = ["--target=i386-pc"]
|
|
|
else:
|
|
|
platform = []
|
|
|
# прописать GRUB2 на все указанные диски
|
|
|
for mbr_disk in self.clVars.Get('os_install_mbr'):
|
|
|
grub_process = process(cmd_grub_install,
|
|
|
"--boot-directory=%s" % pathJoin(
|
|
|
prefix_boot,
|
|
|
target.getBootDirectory()),
|
|
|
mbr_disk, "--force", *platform,
|
|
|
stderr=STDOUT, envdict=os.environ)
|
|
|
if grub_process.failed():
|
|
|
raise DistributiveError(
|
|
|
_("Failed to install the bootloader"))
|
|
|
|
|
|
def install_grub_uefi(self, cmd_grub_install, prefix_boot, target):
|
|
|
"""
|
|
|
Установить grub с UEFI загрузчиком
|
|
|
"""
|
|
|
grub_params = [
|
|
|
"--boot-directory=%s" % pathJoin(
|
|
|
prefix_boot,
|
|
|
target.getBootDirectory()),
|
|
|
"--target=x86_64-efi",
|
|
|
"--efi-directory=%s" %
|
|
|
target.getEfiDirectory(),
|
|
|
"--force"]
|
|
|
# проверяем наличие в nv-ram нужной нам записи для исключения повтора
|
|
|
efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr')
|
|
|
efi_disk = self.clVars.Select("os_install_disk_dev",
|
|
|
where="os_install_disk_mount",
|
|
|
eq="/boot/efi", limit=1)
|
|
|
if efi_disk:
|
|
|
efi_uuid = device.udev.get_device_info(
|
|
|
name=efi_disk).get("ID_PART_ENTRY_UUID", "")
|
|
|
if efi_uuid:
|
|
|
p_efibootmgr = process(efi_boot_mgr, "-v")
|
|
|
data = p_efibootmgr.read()
|
|
|
if re.search(r"Boot.*calculate.*GPT,{uuid}.*{efipath}".format(
|
|
|
uuid=efi_uuid,
|
|
|
efipath=r"\\EFI\\calculate\\grubx64.efi"),
|
|
|
data, flags=re.M | re.I):
|
|
|
grub_params.append("--no-nvram")
|
|
|
# в случае установки на usb-hdd EFI загрузчик не прописывается
|
|
|
# в efivars
|
|
|
if self.clVars.Get('os_install_root_type') == 'usb-hdd':
|
|
|
grub_params.append("--removable")
|
|
|
if self.clVars.Get('cl_action') != "system" and \
|
|
|
not isMount('/boot/efi'):
|
|
|
raise DistributiveError(_("Failed to install the bootloader. "
|
|
|
"/boot/efi is not mounted."))
|
|
|
grub_process = process(cmd_grub_install,
|
|
|
*grub_params, stderr=STDOUT,
|
|
|
envdict=os.environ)
|
|
|
if grub_process.failed():
|
|
|
raise DistributiveError(_("Failed to install the bootloader"))
|
|
|
# проверяем успешность создания загрузочной записи
|
|
|
# если среди загрузочных записей отсутствует запись
|
|
|
# calculate и dmesg содержит сообщение об ошибке efivars -
|
|
|
# запись создать не удалось
|
|
|
dmesg = getProgPath('/bin/dmesg')
|
|
|
if efi_boot_mgr and dmesg:
|
|
|
if not re.search('Boot.*calculate',
|
|
|
process(efi_boot_mgr).read(), re.M) and \
|
|
|
re.search('efivars.*set_variable.*failed',
|
|
|
process(dmesg).read(), re.M):
|
|
|
raise DistributiveError(
|
|
|
_("Failed to create the UEFI boot record"))
|
|
|
|
|
|
def installLegacyGrubBootloader(self, target):
|
|
|
"""
|
|
|
Install legecy grub boot loader
|
|
|
|
|
|
Perform grub installation to disk, which has root partition
|
|
|
"""
|
|
|
cmd_grub = getProgPath('/sbin/grub')
|
|
|
if not cmd_grub:
|
|
|
raise DistributiveError(_("Failed to install the bootloader"))
|
|
|
grub_process = process(
|
|
|
cmd_grub,
|
|
|
"--device-map=%s/boot/grub/device.map" % target.getDirectory(),
|
|
|
"--batch", stderr=STDOUT)
|
|
|
boot_disk = self.clVars.Select('os_install_disk_grub',
|
|
|
where='os_install_disk_mount',
|
|
|
_in=('/', '/boot'),
|
|
|
sort='DESC', limit=1)
|
|
|
if not boot_disk:
|
|
|
raise DistributiveError(_("Failed to determine the boot disk"))
|
|
|
self.setActivePartition(boot_disk)
|
|
|
for mbr_disk in self.clVars.Get('os_install_mbr'):
|
|
|
mbr_disk_num = self.clVars.Select("os_device_map",
|
|
|
where="os_device_dev",
|
|
|
eq=mbr_disk)
|
|
|
if not mbr_disk_num and mbr_disk_num != 0:
|
|
|
raise DistributiveError(_("Failed to determine mbr"))
|
|
|
for line in ("root (hd%s)" % boot_disk,
|
|
|
"setup (hd%d)" % mbr_disk_num,
|
|
|
"quit"):
|
|
|
grub_process.write("%s\n" % line)
|
|
|
if grub_process.failed():
|
|
|
raise DistributiveError(_("Failed to install the bootloader"))
|
|
|
|
|
|
def setupOpenGL(self):
|
|
|
"""
|
|
|
Выполнить выбор opengl для текущего видеодрайвера
|
|
|
"""
|
|
|
default_gl = "xorg-x11"
|
|
|
path_gl_modules = path.join(self.clVars.Get('cl_chroot_path'),
|
|
|
'usr/lib/opengl')
|
|
|
open_gl_env = path.join(self.clVars.Get('cl_chroot_path'),
|
|
|
'etc/env.d/03opengl')
|
|
|
|
|
|
open_gl_mods = filter(lambda x: x != "global",
|
|
|
listDirectory(path_gl_modules))
|
|
|
map_gl_drivers = {'fglrx': ("ati" if "ati" in open_gl_mods
|
|
|
else default_gl),
|
|
|
'nvidia': "nvidia" if "nvidia" in open_gl_mods
|
|
|
else default_gl}
|
|
|
x11_driver = self.clVars.Get('os_install_x11_video_drv')
|
|
|
if x11_driver in map_gl_drivers:
|
|
|
new_module_name = map_gl_drivers[x11_driver]
|
|
|
else:
|
|
|
new_module_name = default_gl
|
|
|
current_module_name = map(
|
|
|
lambda x: x.strip().rpartition('=')[-1].strip('"\''),
|
|
|
filter(lambda x: x.startswith("OPENGL_PROFILE="),
|
|
|
readLinesFile(open_gl_env)))
|
|
|
if current_module_name:
|
|
|
current_module_name = current_module_name[-1]
|
|
|
else:
|
|
|
current_module_name = ""
|
|
|
if current_module_name == new_module_name:
|
|
|
return True
|
|
|
return process('/usr/bin/eselect', 'opengl', 'set',
|
|
|
new_module_name).success()
|
|
|
|
|
|
def checkVideoDriver(self):
|
|
|
"""
|
|
|
Проверить видео драйвер, и если это nvidia, то
|
|
|
обновить маску на пакет видеодрайвера
|
|
|
"""
|
|
|
if self.clVars.Get('hr_video') != 'nvidia':
|
|
|
return True
|
|
|
mask_file = '/etc/portage/package.mask'
|
|
|
nvidia_mask_file = path.join(mask_file, 'nvidia')
|
|
|
# если package.mask является файлом - делаем его директорией
|
|
|
if path.isfile(mask_file):
|
|
|
os.rename(mask_file, mask_file + "2")
|
|
|
os.mkdir(mask_file, mode=0755)
|
|
|
os.rename(mask_file + "2", path.join(mask_file, "default"))
|
|
|
current_nvidia_mask = readFile(nvidia_mask_file).strip()
|
|
|
new_nvidia_mask = self.clVars.Get('os_nvidia_mask')
|
|
|
if new_nvidia_mask == current_nvidia_mask:
|
|
|
return True
|
|
|
open(nvidia_mask_file, 'w').write(new_nvidia_mask)
|
|
|
return True
|
|
|
|
|
|
def changeScheduler(self, scheduler):
|
|
|
"""
|
|
|
Изменить текущий IO планировщик
|
|
|
"""
|
|
|
root_dev = self.clVars.Select('os_disk_parent',
|
|
|
where='os_disk_mount',
|
|
|
eq='/', limit=1)
|
|
|
try:
|
|
|
sysname = device.udev.get_syspath(name=root_dev)
|
|
|
if device.sysfs.exists(sysname, device.sysfs.Path.BlockScheduler):
|
|
|
device.sysfs.write(
|
|
|
sysname, device.sysfs.Path.BlockScheduler, scheduler)
|
|
|
except Exception:
|
|
|
raise InstallError(_("Unable to change the I/O scheduler"))
|
|
|
return True
|
|
|
|
|
|
def autopartition(self, table, devices, data, lvm, lvm_vgname, bios_grub,
|
|
|
bios_grub_size):
|
|
|
"""
|
|
|
Авторазметка диска с таблицей разделов 'table', диски указываются
|
|
|
'device', параметры таблицы 'data', 'lvm' использование LVM,
|
|
|
'lvm_vgname' название группы томов LVM, bios_grub - создавать
|
|
|
bios_grub раздел, bios_grub_size - раздел bios grub раздела в байтах
|
|
|
"""
|
|
|
ap = AutoPartition()
|
|
|
ap.clearLvm(devices, self.clVars)
|
|
|
ap.clearRaid(devices, self.clVars)
|
|
|
ap.recreateSpace(table, devices, data, lvm,
|
|
|
lvm_vgname, bios_grub, bios_grub_size)
|
|
|
return True
|
|
|
|
|
|
def format(self, target):
|
|
|
"""
|
|
|
Форматировать разделы для 'target' дистрибутива
|
|
|
"""
|
|
|
target.performFormat()
|
|
|
return True
|
|
|
|
|
|
def unpack(self, source, target, files_num):
|
|
|
"""
|
|
|
Распаковать 'source' в 'target', 'filesnum' количество копируемых файлов
|
|
|
"""
|
|
|
self.addProgress()
|
|
|
if files_num.isdigit():
|
|
|
files_num = int(files_num)
|
|
|
else:
|
|
|
files_num = 0
|
|
|
target.installFrom(source, callbackProgress=self.setProgress,
|
|
|
filesnum=files_num)
|
|
|
return True
|
|
|
|
|
|
def copyClt(self, source, target, cltpath):
|
|
|
"""
|
|
|
Скопировать clt шаблоны из 'cltpath' в 'target' дистрибутив из
|
|
|
'source' дистрибутива
|
|
|
"""
|
|
|
target_dir = target.getDirectory()
|
|
|
source_dir = source.getDirectory()
|
|
|
for f in filter(lambda x: x.endswith('.clt'),
|
|
|
chain(*map(lambda x: find(pathJoin(source_dir, x),
|
|
|
filetype="f"),
|
|
|
cltpath))):
|
|
|
copyWithPath(f, target_dir, prefix=source_dir)
|
|
|
return True
|
|
|
|
|
|
def copyOther(self, source, target):
|
|
|
"""
|
|
|
Скопировать прочие настройки из текущей системы в новую
|
|
|
"""
|
|
|
file_mask = re.compile("(/etc/ssh/ssh_host_.*|"
|
|
|
"/root/.ssh/(id_.*|known_hosts))")
|
|
|
target_dir = target.getDirectory()
|
|
|
source_dir = source.getDirectory()
|
|
|
for f in filter(file_mask.search,
|
|
|
chain(*map(lambda x: find(pathJoin(source_dir, x),
|
|
|
filetype="f"),
|
|
|
["/etc", "/root/.ssh"]))):
|
|
|
copyWithPath(f, target_dir, prefix=source_dir)
|
|
|
return True
|
|
|
|
|
|
def rndString(self):
|
|
|
"""
|
|
|
Получить произвольную строку из 8 символов
|
|
|
"""
|
|
|
"""Get random string with len 8 char"""
|
|
|
return "".join([choice(string.ascii_letters + string.digits)
|
|
|
for i in xrange(0, 8)])
|
|
|
|
|
|
def _getFreeDirectory(self, directory):
|
|
|
"""
|
|
|
Получить название директории
|
|
|
"""
|
|
|
new_dir_name = directory
|
|
|
while path.exists(new_dir_name):
|
|
|
new_dir_name = "%s.%s" % (directory, self.rndString())
|
|
|
return new_dir_name
|
|
|
|
|
|
def remountNTFS(self):
|
|
|
"""
|
|
|
Перемонтировать NTFS разделы для работы os-prober
|
|
|
"""
|
|
|
res = True
|
|
|
for disk in self.clVars.Select('os_disk_dev',
|
|
|
where='os_disk_format', like='ntfs'):
|
|
|
mount_dir = self._getFreeDirectory('/var/lib/calculate/mount.ntfs')
|
|
|
try:
|
|
|
os.mkdir(mount_dir)
|
|
|
except (OSError, IOError):
|
|
|
continue
|
|
|
if process('/bin/mount', disk, mount_dir).success():
|
|
|
for i in (0.2, 0.5, 1, 2, 4, 5):
|
|
|
if process('/bin/umount', mount_dir).success():
|
|
|
break
|
|
|
time.sleep(i)
|
|
|
else:
|
|
|
self.printWARNING(_("Unable to umount %s") % mount_dir)
|
|
|
res = False
|
|
|
try:
|
|
|
os.rmdir(mount_dir)
|
|
|
except (OSError, IOError):
|
|
|
self.printWARNING(
|
|
|
_("Unable to remove directory %s") % mount_dir)
|
|
|
return False
|
|
|
return res
|
|
|
|
|
|
def mountBind(self, target):
|
|
|
"""
|
|
|
Подключить bind точки монтирования у дистрибутива
|
|
|
"""
|
|
|
target.postinstallMountBind()
|
|
|
return True
|
|
|
|
|
|
def userMigrate(self, target, migrate_data, root_pwd):
|
|
|
"""
|
|
|
Перенос текущих пользователей в новую систему,
|
|
|
установка пароля пользователя root
|
|
|
"""
|
|
|
migrator = migrate(target.getDirectory())
|
|
|
|
|
|
if not migrator.migrate([[x[0],x[2],x[3]] for x in migrate_data if x],
|
|
|
root_pwd, [], [], ):
|
|
|
raise InstallError(_("Failed to migrate users onto the new system"))
|
|
|
return True
|
|
|
|
|
|
def umount(self, distr):
|
|
|
"""
|
|
|
Отключить дистрибутив
|
|
|
"""
|
|
|
distr.close()
|
|
|
return True
|
|
|
|
|
|
def drop_xorg_logs(self):
|
|
|
"""
|
|
|
Сбросить логи загрузки xorg сервера
|
|
|
"""
|
|
|
for fn in glob.glob("/var/log/Xorg.*.log"):
|
|
|
new_name = "%s.old" % fn
|
|
|
if path.exists(new_name):
|
|
|
os.unlink(new_name)
|
|
|
shutil.move(fn, new_name)
|
|
|
return True
|
|
|
|
|
|
def update_admin_ini(self):
|
|
|
"""
|
|
|
Обновить список локальных администраторов при установке
|
|
|
"""
|
|
|
aliases = {
|
|
|
'update': 'system_update',
|
|
|
}
|
|
|
install_admin = Admins(self.clVars, chroot=True)
|
|
|
install_admin.clear()
|
|
|
for k,v in self.clVars.select('install.cl_migrate_user',
|
|
|
'install.cl_migrate_admin',
|
|
|
install_cl_migrate_admin__ne=""):
|
|
|
install_admin[k] = aliases.get(v,v)
|
|
|
install_admin.save()
|
|
|
return True
|
|
|
|
|
|
def init_themes(self):
|
|
|
self.clVars.Get('cl_splash_image_hash')
|
|
|
self.clVars.Get('cl_grub_image_hash')
|
|
|
return True
|