#
from __future__ import with_statement
-import os, sys
+import os
import shutil
import subprocess
-import mic.utils.fs_related as fs_related
-import mic.utils.misc as misc
-import mic.utils.errors as errors
from mic import msger
+from mic.utils import misc, errors, runner, fs_related
chroot_lockfd = -1
chroot_lock = ""
if not os.path.exists(ftc):
continue
- filecmd = misc.find_binary_path("file")
-
- for line in subprocess.Popen([filecmd, ftc],
- stdout=subprocess.PIPE,
- stderr=dev_null).communicate()[0].strip().splitlines():
+ for line in runner.outs(['file', ftc]).splitlines():
if 'ARM' in line:
qemu_emulator = misc.setup_qemu_emulator(chrootdir, "arm")
architecture_found = True
globalmounts = setup_chrootenv(chrootdir, bindmounts)
subprocess.call(execute, preexec_fn = mychroot, shell=True)
- except OSError, (err, msg):
- raise errors.CreatorError("Failed to chroot: %s" % msg)
+ except OSError, err:
+ raise errors.CreatorError("chroot err: %s" % str(err))
finally:
cleanup_chrootenv(chrootdir, bindmounts, globalmounts)
# creator.py : ImageCreator and LoopImageCreator base classes
#
# Copyright 2007, Red Hat Inc.
+# Copyright 2009, 2010, 2011 Intel, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
import rpm
-from mic.utils.errors import CreatorError
-from mic.utils.misc import get_filesystem_avail, is_statically_linked,setup_qemu_emulator, create_release
-from mic.utils.fs_related import find_binary_path, makedirs, BindChrootMount
-from mic.utils import rpmmisc, runner
from mic import kickstart
from mic import msger
+from mic.utils.errors import CreatorError
+from mic.utils import misc, rpmmisc, runner, fs_related as fs
class BaseImageCreator(object):
"""Installs a system to a chroot directory.
# make sure the specified tmpdir and cachedir exist
if not os.path.exists(self.tmpdir):
- makedirs(self.tmpdir)
+ os.makedirs(self.tmpdir)
if not os.path.exists(self.cachedir):
- makedirs(self.cachedir)
+ os.makedirs(self.cachedir)
def set_target_arch(self, arch):
if arch not in rpmmisc.arches:
if dep == "extlinux":
self._dep_checks.remove(dep)
- if not os.path.exists("/usr/bin/qemu-arm") or not is_statically_linked("/usr/bin/qemu-arm"):
+ if not os.path.exists("/usr/bin/qemu-arm") or not misc.is_statically_linked("/usr/bin/qemu-arm"):
self._dep_checks.append("qemu-arm-static")
if os.path.exists("/proc/sys/vm/vdso_enabled"):
return True
-
def __del__(self):
self.cleanup()
# save package name list anyhow
if not os.path.exists(destdir):
- makedirs(destdir)
+ os.makedirs(destdir)
namefile = os.path.join(destdir, self.name + '-pkgs.txt')
f = open(namefile, "w")
self.cachedir = cachedir
else:
self.cachedir = self.__builddir + "/yum-cache"
- makedirs(self.cachedir)
+ fs.makedirs(self.cachedir)
return self.cachedir
def __sanity_check(self):
os.symlink(src, self._instroot + dest)
os.umask(origumask)
-
def mount(self, base_on = None, cachedir = None):
"""Setup the target filesystem in preparation for an install.
"""
self.__ensure_builddir()
- makedirs(self._instroot)
- makedirs(self._outdir)
+ fs.makedirs(self._instroot)
+ fs.makedirs(self._outdir)
self._mount_instroot(base_on)
for d in ("/dev/pts", "/etc", "/boot", "/var/log", "/var/cache/yum", "/sys", "/proc", "/usr/bin"):
- makedirs(self._instroot + d)
+ fs.makedirs(self._instroot + d)
if self.target_arch and self.target_arch.startswith("arm"):
- self.qemu_emulator = setup_qemu_emulator(self._instroot, self.target_arch)
+ self.qemu_emulator = misc.setup_qemu_emulator(self._instroot, self.target_arch)
self.get_cachedir(cachedir)
for (f, dest) in [("/sys", None), ("/proc", None), ("/proc/sys/fs/binfmt_misc", None),
("/dev/pts", None),
(self.get_cachedir(), "/var/cache/yum")]:
- self.__bindmounts.append(BindChrootMount(f, self._instroot, dest))
-
+ self.__bindmounts.append(fs.BindChrootMount(f, self._instroot, dest))
self._do_bindmounts()
self.__write_fstab()
# get size of available space in 'instroot' fs
- self._root_fs_avail = get_filesystem_avail(self._instroot)
+ self._root_fs_avail = misc.get_filesystem_avail(self._instroot)
def unmount(self):
"""Unmounts the target filesystem.
except OSError:
pass
-
self._undo_bindmounts()
-
self._unmount_instroot()
def cleanup(self):
"""
-
# initialize pkg list to install
if self.ks:
self.__sanity_check()
return None
gpgkeydir = "/etc/pki/rpm-gpg"
- makedirs(self._instroot + gpgkeydir)
+ fs.makedirs(self._instroot + gpgkeydir)
for repo in repodata:
if repo["repokey"]:
repokey = gpgkeydir + "/RPM-GPG-KEY-%s" % repo["name"]
""" Generate md5sum if /usr/bin/md5sum is available """
if os.path.exists("/usr/bin/md5sum"):
- p = subprocess.Popen(["/usr/bin/md5sum", "-b", image_name],
- stdout=subprocess.PIPE)
- (md5sum, errorstr) = p.communicate()
- if p.returncode != 0:
+ (rc, md5sum) = runner.runtool(["/usr/bin/md5sum", "-b", image_name])
+ if rc != 0:
msger.warning("Can't generate md5sum for image %s" % image_name)
else:
pattern = re.compile("\*.*$")
self._stage_final_image()
if not os.path.exists(destdir):
- makedirs(destdir)
+ fs.makedirs(destdir)
if self.__img_compression_method:
if not self._img_name:
raise CreatorError("Image name not set.")
rc = None
img_location = os.path.join(self._outdir,self._img_name)
if self.__img_compression_method == "bz2":
- bzip2 = find_binary_path('bzip2')
+ bzip2 = fs.find_binary_path('bzip2')
msger.info("Compressing %s with bzip2. Please wait..." % img_location)
rc = runner.show([bzip2, "-f", img_location])
if rc:
if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"):
destdir = os.path.join(destdir, "%s-%s" % (self.name, self.image_format))
msger.debug("creating destination dir: %s" % destdir)
- makedirs(destdir)
+ fs.makedirs(destdir)
# Ensure all data is flushed to _outdir
runner.quiet('sync')
def check_depend_tools(self):
for tool in self._dep_checks:
- find_binary_path(tool)
+ fs.find_binary_path(tool)
def package_output(self, image_format, destdir = ".", package="none"):
if not package or package == "none":
else:
os.remove(file)
-
tar.close()
'''All the file in outimage has been packaged into tar.* file'''
self.outimage = [dst]
def release_output(self, config, destdir, name, release):
- self.outimage = create_release(config, destdir, name, self.outimage, release)
+ self.outimage = misc.create_release(config, destdir, name, self.outimage, release)
def save_kernel(self, destdir):
if not os.path.exists(destdir):
- makedirs(destdir)
+ os.makedirs(destdir)
for kernel in glob.glob("%s/boot/vmlinuz-*" % self._instroot):
kernelfilename = "%s/%s-%s" % (destdir, self.name, os.path.basename(kernel))
shutil.copy(kernel, kernelfilename)
def get_pkg_manager(self, recording_pkgs=None):
return self.pkgmgr(creator = self, recording_pkgs = recording_pkgs)
-
-
import sys
import errno
import stat
-import subprocess
import random
import string
import time
resize2fs = find_binary_path("resize2fs")
return runner.quiet([resize2fs, fs, "%sK" % (size / 1024,)])
-def my_fuser(file):
- ret = False
+def my_fuser(fp):
fuser = find_binary_path("fuser")
- if not os.path.exists(file):
- return ret
+ if not os.path.exists(fp):
+ return False
- dev_null = os.open("/dev/null", os.O_WRONLY)
- rc = runner.quiet([fuser, "-s", file])
+ rc = runner.quiet([fuser, "-s", fp])
if rc == 0:
- fuser_proc = subprocess.Popen([fuser, file], stdout=subprocess.PIPE, stderr=dev_null)
- pids = fuser_proc.communicate()[0].strip().split()
- for pid in pids:
+ for pid in runner.outs([fuser, fp]).split():
fd = open("/proc/%s/cmdline" % pid, "r")
cmdline = fd.read()
fd.close()
if cmdline[:-1] == "/bin/bash":
- ret = True
- break
- os.close(dev_null)
- return ret
+ return True
+
+ # not found
+ return False
class BindChrootMount:
"""Represents a bind mount of a directory into a chroot."""
self.umountcmd = find_binary_path("umount")
def ismounted(self):
- ret = False
- dev_null = os.open("/dev/null", os.O_WRONLY)
- catcmd = find_binary_path("cat")
- args = [ catcmd, "/proc/mounts" ]
- proc_mounts = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=dev_null)
- outputs = proc_mounts.communicate()[0].strip().split("\n")
- for line in outputs:
- if line.split()[1] == os.path.abspath(self.dest):
- ret = True
- break
- os.close(dev_null)
- return ret
+ with open('/proc/mounts') as f:
+ for line in f:
+ if line.split()[1] == os.path.abspath(self.dest):
+ return True
+
+ return False
def has_chroot_instance(self):
lock = os.path.join(self.root, ".chroot.lock")
if self.losetup:
return
- losetupProc = subprocess.Popen([self.losetupcmd, "-f"],
- stdout=subprocess.PIPE)
- losetupOutput = losetupProc.communicate()[0]
-
- if losetupProc.returncode:
+ rc, losetupOutput = runner.runtool([self.losetupcmd, "-f"])
+ if rc != 0:
raise MountError("Failed to allocate loop device for '%s'" %
self.lofile)
if self.device is not None:
return
- losetupProc = subprocess.Popen([self.losetupcmd, "-f"],
- stdout=subprocess.PIPE)
- losetupOutput = losetupProc.communicate()[0]
-
- if losetupProc.returncode:
+ rc, losetupOutput = runner.runtool([self.losetupcmd, "-f"])
+ if rc != 0:
raise MountError("Failed to allocate loop device for '%s'" %
self.lofile)
if rc != 0:
raise MountError("Error creating %s filesystem on disk %s" % (self.fstype, self.disk.device))
- dev_null = os.open("/dev/null", os.O_WRONLY)
- try:
- out = subprocess.Popen([self.dumpe2fs, '-h', self.disk.device],
- stdout = subprocess.PIPE,
- stderr = dev_null).communicate()[0]
- finally:
- os.close(dev_null)
+ out = runner.outs([self.dumpe2fs, '-h', self.disk.device])
self.uuid = self.__parse_field(out, "Filesystem UUID")
msger.debug("Tuning filesystem on %s" % self.disk.device)
runner.show(["/sbin/e2fsck", "-f", "-y", self.disk.lofile])
def __get_size_from_filesystem(self):
- dev_null = os.open("/dev/null", os.O_WRONLY)
- try:
- out = subprocess.Popen([self.dumpe2fs, '-h', self.disk.lofile],
- stdout = subprocess.PIPE,
- stderr = dev_null).communicate()[0]
- finally:
- os.close(dev_null)
-
- return int(self.__parse_field(out, "Block count")) * self.blocksize
+ return int(self.__parse_field(runner.outs([self.dumpe2fs, '-h', self.disk.lofile]),
+ "Block count")) * self.blocksize
def __resize_to_minimal(self):
self.__fsck()
if rc != 0:
raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device))
- dev_null = os.open("/dev/null", os.O_WRONLY)
- try:
- out = subprocess.Popen([self.blkidcmd, self.disk.device],
- stdout = subprocess.PIPE,
- stderr = dev_null).communicate()[0]
- finally:
- os.close(dev_null)
-
- self.uuid = self.__parse_field(out, "UUID")
+ self.uuid = self.__parse_field(runner.outs([self.blkidcmd, self.disk.device]), "UUID")
def __resize_filesystem(self, size = None):
current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
if not self.__created:
return 0
- dev_null = os.open("/dev/null", os.O_WRONLY)
- try:
- out = subprocess.Popen([self.dmsetupcmd, "status", self.__name],
- stdout = subprocess.PIPE,
- stderr = dev_null).communicate()[0]
- finally:
- os.close(dev_null)
-
#
# dmsetup status on a snapshot returns e.g.
# "0 8388608 snapshot 416/1048576"
# "A B snapshot C/D"
# where C is the number of 512 byte sectors in use
#
+ out = runner.outs([self.dmsetupcmd, "status", self.__name])
try:
return int((out.split()[3]).split('/')[0]) * 512
except ValueError:
import os
import sys
-import subprocess
import tempfile
import re
import shutil
from errors import *
from fs_related import *
from proxy import get_proxy_for
+import runner
from mic import msger
if file_header[0:len(vdi_flag)] == vdi_flag:
return maptab["vdi"]
- dev_null = os.open("/dev/null", os.O_WRONLY)
- filecmd = find_binary_path("file")
- args = [ filecmd, path ]
- file = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=dev_null)
- output = file.communicate()[0]
- os.close(dev_null)
+ output = runner.outs(['file', path])
isoptn = re.compile(r".*ISO 9660 CD-ROM filesystem.*(bootable).*")
usbimgptn = re.compile(r".*x86 boot sector.*active.*")
rawptn = re.compile(r".*x86 boot sector.*")
def get_file_size(file):
"""Return size in MB unit"""
- du = find_binary_path("du")
- dev_null = os.open("/dev/null", os.O_WRONLY)
- duProc = subprocess.Popen([du, "-s", "-b", "-B", "1M", file],
- stdout=subprocess.PIPE, stderr=dev_null)
- duOutput = duProc.communicate()[0]
- if duProc.returncode:
+ rc, duOutput = runner.runtool(['du', "-s", "-b", "-B", "1M", file])
+ if rc != 0:
raise CreatorError("Failed to run %s" % du)
size1 = int(duOutput.split()[0])
- duProc = subprocess.Popen([du, "-s", "-B", "1M", file],
- stdout=subprocess.PIPE, stderr=dev_null)
- duOutput = duProc.communicate()[0]
- if duProc.returncode:
+ rc, duOutput = runner.runtool(['du', "-s", "-B", "1M", file])
+ if rc != 0:
raise CreatorError("Failed to run %s" % du)
size2 = int(duOutput.split()[0])
- os.close(dev_null)
if size1 > size2:
return size1
else:
else:
raise CreatorError("Invalid soure image format: %s" % srcfmt)
- rc = subprocess.call(argv)
+ rc = runner.show(argv)
if rc == 0:
msger.debug("convert successful")
if rc != 0:
"""Uncompress file system from squshfs image"""
unsquashfs = find_binary_path("unsquashfs")
args = [ unsquashfs, "-d", outdir, squashfsimg ]
- rc = subprocess.call(args)
+ rc = runner.show(args)
if (rc != 0):
raise SquashfsError("Failed to uncompress %s." % squashfsimg)
if filename.endswith(".gz"):
suffix = ".gz"
gunzip = find_binary_path('gunzip')
- subprocess.call([gunzip, "-f", filename])
+ runner.show([gunzip, "-f", filename])
elif filename.endswith(".bz2"):
suffix = ".bz2"
bunzip2 = find_binary_path('bunzip2')
- subprocess.call([bunzip2, "-f", filename])
+ runner.show([bunzip2, "-f", filename])
if suffix:
filename = filename.replace(suffix, "")
return filename
return None
def get_release_no(repometadata, distro="meego"):
+ import subprocess
+
cpio = find_binary_path("cpio")
rpm2cpio = find_binary_path("rpm2cpio")
release_pkg = get_package("%s-release" % distro, repometadata)
return pkglist
def is_statically_linked(binary):
- ret = False
- dev_null = os.open("/dev/null", os.O_WRONLY)
- filecmd = find_binary_path("file")
- args = [ filecmd, binary ]
- file = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=dev_null)
- output = file.communicate()[0]
- os.close(dev_null)
- if output.find(", statically linked, ") > 0:
- ret = True
- return ret
+ return ", statically linked, " in runner.outs(['file', binary])
def setup_qemu_emulator(rootdir, arch):
# mount binfmt_misc if it doesn't exist
if not os.path.exists("/proc/sys/fs/binfmt_misc"):
modprobecmd = find_binary_path("modprobe")
- subprocess.call([modprobecmd, "binfmt_misc"])
+ runner.show([modprobecmd, "binfmt_misc"])
if not os.path.exists("/proc/sys/fs/binfmt_misc/register"):
mountcmd = find_binary_path("mount")
- subprocess.call([mountcmd, "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc"])
+ runner.show([mountcmd, "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc"])
# qemu_emulator is a special case, we can't use find_binary_path
# qemu emulator should be a statically-linked executable file
# disable selinux, selinux will block qemu emulator to run
if os.path.exists("/usr/sbin/setenforce"):
- subprocess.call(["/usr/sbin/setenforce", "0"])
+ msger.info('Try to disable selinux')
+ runner.show(["/usr/sbin/setenforce", "0"])
node = "/proc/sys/fs/binfmt_misc/arm"
if is_statically_linked(qemu_emulator) and os.path.exists(node):
shutil.rmtree(thatsubdir, ignore_errors = True)
""" Create release directory and files """
- os.system ("cp %s %s/%s.ks" % (config, destdir, name))
+ runner.show("cp %s %s/%s.ks" % (config, destdir, name))
# When building a release we want to make sure the .ks
# file generates the same build even when --release= is not used.
fd = open(config, "r")
outimages.append("%s/%s.ks" % (destdir,name))
# Using system + mv, because of * in filename.
- os.system ("mv %s/*-pkgs.txt %s/%s.packages" % (destdir, destdir, name))
+ runner.show("mv %s/*-pkgs.txt %s/%s.packages" % (destdir, destdir, name))
outimages.append("%s/%s.packages" % (destdir,name))
- d = os.listdir(destdir)
- for f in d:
+ for f in os.listdir(destdir):
if f.endswith(".iso"):
ff = f.replace(".iso", ".img")
os.rename("%s/%s" %(destdir, f ), "%s/%s" %(destdir, ff))
os.rename("%s/%s" %(destdir, f ), "%s/%s" %(destdir, ff))
outimages.append("%s/%s" %(destdir, ff))
- fd = open(destdir + "/MANIFEST", "w")
- d = os.listdir(destdir)
- for f in d:
- if f == "MANIFEST":
- continue
- if os.path.exists("/usr/bin/md5sum"):
- p = subprocess.Popen(["/usr/bin/md5sum", "-b", "%s/%s" %(destdir, f )],
- stdout=subprocess.PIPE)
- (md5sum, errorstr) = p.communicate()
- if p.returncode != 0:
+ if os.path.exists("/usr/bin/md5sum"):
+ fd = open(destdir + "/MANIFEST", "w")
+ for f in os.listdir(destdir):
+ if f == "MANIFEST":
+ continue
+
+ rc, md5sum = runner.runtool(["/usr/bin/md5sum", "-b", "%s/%s" %(destdir, f )])
+ if rc != 0:
msger.warning("Can't generate md5sum for image %s/%s" %(destdir, f ))
else:
- md5sum = md5sum.split(" ")[0]
+ md5sum = md5sum.lstrip().split()[0]
fd.write(md5sum+" "+f+"\n")
outimages.append("%s/MANIFEST" % destdir)
# Copyright 2008, Daniel P. Berrange
# Copyright 2008, David P. Huff
#
+# Copyright 2009, 2010, 2011 Intel, Inc.
+#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import os
-import glob
-import shutil
-import subprocess
-import time
-from mic.utils.errors import *
-from mic.utils.fs_related import *
from mic import msger
+from mic.utils import runner
+from mic.utils.errors import MountError
+from mic.utils.fs_related import *
class PartitionedMount(Mount):
def __init__(self, disks, mountdir, skipformat = False):
part_cmd.extend(["%d" % start, "%d" % end])
msger.debug(part_cmd)
- p1 = subprocess.Popen(part_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- out = p1.communicate()[0].strip()
+ rc, out = runner.runtool(part_cmd, catch=3)
+ out = out.strip()
if out:
msger.debug('"parted" output: %s' % out)
- return p1.returncode
+ return rc
def __format_disks(self):
msger.debug("Assigning partitions to disks")
for dev in self.disks.keys():
d = self.disks[dev]
msger.debug("Initializing partition table for %s" % (d['disk'].device))
- p1 = subprocess.Popen([self.parted, "-s", d['disk'].device, "mklabel", "msdos"],
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- out = p1.communicate()[0].strip()
+ rc, out = runner.runtool([self.parted, "-s", d['disk'].device, "mklabel", "msdos"], catch=3)
+ out = out.strip()
if out:
msger.debug('"parted" output: %s' % out)
- if p1.returncode != 0:
+ if rc != 0:
# NOTE: We don't throw exception when return code is not 0, because
# parted always fails to reload part table with loop devices.
# This prevents us from distinguishing real errors based on return code.
msger.debug("Setting boot flag for partition '%s' on disk '%s'." % (p['num'],d['disk'].device))
boot_cmd = [self.parted, "-s", d['disk'].device, "set", "%d" % p['num'], "boot", "on"]
msger.debug(boot_cmd)
- p1 = subprocess.Popen(boot_cmd,
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- (out,err) = p1.communicate()
- msger.debug(out)
+ rc = runner.show(boot_cmd)
- if p1.returncode != 0:
+ if rc != 0:
# NOTE: We don't throw exception when return code is not 0, because
# parted always fails to reload part table with loop devices.
# This prevents us from distinguishing real errors based on return code.
- msger.debug("WARNING: parted returned '%s' instead of 0 when adding boot flag for partition '%s' disk '%s'." % (p1.returncode,p['num'],d['disk'].device))
+ msger.warning("parted returned '%s' instead of 0 when adding boot flag for partition '%s' disk '%s'." % (rc,p['num'],d['disk'].device))
def __map_partitions(self):
"""Load it if dm_snapshot isn't loaded"""
load_module("dm_snapshot")
- dev_null = os.open("/dev/null", os.O_WRONLY)
for dev in self.disks.keys():
d = self.disks[dev]
if d['mapped']:
continue
msger.debug("Running kpartx on %s" % d['disk'].device )
- kpartx = subprocess.Popen([self.kpartx, "-l", "-v", d['disk'].device],
- stdout=subprocess.PIPE, stderr=dev_null)
+ rc, kpartxOutput = runner.runtool([self.kpartx, "-l", "-v", d['disk'].device])
+ kpartxOutput = kpartxOutput.splitlines()
- kpartxOutput = kpartx.communicate()[0].strip().split("\n")
-
- if kpartx.returncode:
- os.close(dev_null)
+ if rc != 0:
raise MountError("Failed to query partition mapping for '%s'" %
d['disk'].device)
# our expectation. If it doesn't, someone broke the code
# further up
if len(kpartxOutput) != d['numpart']:
- os.close(dev_null)
raise MountError("Unexpected number of partitions from kpartx: %d != %d" %
(len(kpartxOutput), d['numpart']))
os.symlink(mapperdev, loopdev)
msger.debug("Adding partx mapping for %s" % d['disk'].device)
- p1 = subprocess.Popen([self.kpartx, "-v", "-a", d['disk'].device],
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ rc = runner.show([self.kpartx, "-v", "-a", d['disk'].device])
- (out,err) = p1.communicate()
- msger.debug(out)
-
- if p1.returncode != 0:
+ if rc != 0:
# Make sure that the device maps are also removed on error case.
# The d['mapped'] isn't set to True if the kpartx fails so
# failed mapping will not be cleaned on cleanup either.
- subprocess.call([self.kpartx, "-d", d['disk'].device],
- stdout=dev_null, stderr=dev_null)
- os.close(dev_null)
+ runner.quiet([self.kpartx, "-d", d['disk'].device])
raise MountError("Failed to map partitions for '%s'" %
d['disk'].device)
- d['mapped'] = True
- os.close(dev_null)
+ d['mapped'] = True
def __unmap_partitions(self):
- dev_null = os.open("/dev/null", os.O_WRONLY)
for dev in self.disks.keys():
d = self.disks[dev]
if not d['mapped']:
self.partitions[pnum]['device'] = None
msger.debug("Unmapping %s" % d['disk'].device)
- rc = subprocess.call([self.kpartx, "-d", d['disk'].device],
- stdout=dev_null, stderr=dev_null)
+ rc = runner.quiet([self.kpartx, "-d", d['disk'].device])
if rc != 0:
- os.close(dev_null)
raise MountError("Failed to unmap partitions for '%s'" %
d['disk'].device)
d['mapped'] = False
- os.close(dev_null)
-
def __calculate_mountorder(self):
msger.debug("Calculating mount order")
if not self.btrfscmd:
self.btrfscmd=find_binary_path("btrfs")
argv = [ self.btrfscmd, "subvolume", "list", rootpath ]
- p1 = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- (out,err) = p1.communicate()
+
+ rc, out = runner.runtool(argv)
msger.debug(out)
- if p1.returncode != 0:
- raise MountError("Failed to get subvolume id from %s', return code: %d." % (rootpath, p1.returncode))
+
+ if rc != 0:
+ raise MountError("Failed to get subvolume id from %s', return code: %d." % (rootpath, rc))
+
subvolid = -1
- for line in out.split("\n"):
+ for line in out.splitlines():
if line.endswith(" path %s" % subvol):
- subvolid = line.split(" ")[1]
+ subvolid = line.split()[1]
if not subvolid.isdigit():
raise MountError("Invalid subvolume id: %s" % subvolid)
subvolid = int(subvolid)
def __create_subvolume_metadata(self, p, pdisk):
if len(self.subvolumes) == 0:
return
+
argv = [ self.btrfscmd, "subvolume", "list", pdisk.mountdir ]
- p1 = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- (out,err) = p1.communicate()
+ rc, out = runner.runtool(argv)
msger.debug(out)
- if p1.returncode != 0:
- raise MountError("Failed to get subvolume id from %s', return code: %d." % (pdisk.mountdir, p1.returncode))
- subvolid_items = out.split("\n")
+
+ if rc != 0:
+ raise MountError("Failed to get subvolume id from %s', return code: %d." % (pdisk.mountdir, rc))
+
+ subvolid_items = out.splitlines()
subvolume_metadata = ""
for subvol in self.subvolumes:
for line in subvolid_items:
if line.endswith(" path %s" % subvol["subvol"]):
- subvolid = line.split(" ")[1]
+ subvolid = line.split()[1]
if not subvolid.isdigit():
raise MountError("Invalid subvolume id: %s" % subvolid)
+
subvolid = int(subvolid)
opts = subvol["fsopts"].split(",")
for opt in opts:
break
fsopts = ",".join(opts)
subvolume_metadata += "%d\t%s\t%s\t%s\n" % (subvolid, subvol["subvol"], subvol['mountpoint'], fsopts)
+
if subvolume_metadata:
fd = open("%s/.subvolume_metadata" % pdisk.mountdir, "w")
fd.write(subvolume_metadata)
subvolume_metadata_file = "%s/.subvolume_metadata" % pdisk.mountdir
if not os.path.exists(subvolume_metadata_file):
return
+
fd = open(subvolume_metadata_file, "r")
content = fd.read()
fd.close()
- for line in content.split("\n"):
+
+ for line in content.splitlines():
items = line.split("\t")
if items and len(items) == 4:
self.subvolumes.append({'size': 0, # In sectors
def __create_subvolumes(self, p, pdisk):
""" Create all the subvolumes """
+
for subvol in self.subvolumes:
argv = [ self.btrfscmd, "subvolume", "create", pdisk.mountdir + "/" + subvol["subvol"]]
- p1 = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- (out,err) = p1.communicate()
- msger.debug(out)
- if p1.returncode != 0:
- raise MountError("Failed to create subvolume '%s', return code: %d." % (subvol["subvol"], p1.returncode))
+
+ rc = runner.show(argv)
+ if rc != 0:
+ raise MountError("Failed to create subvolume '%s', return code: %d." % (subvol["subvol"], rc))
""" Set default subvolume, subvolume for "/" is default """
subvol = None
if subvolume["mountpoint"] == "/" and p["disk"] == subvolume["disk"]:
subvol = subvolume
break
+
if subvol:
""" Get default subvolume id """
subvolid = self. __get_subvolume_id(pdisk.mountdir, subvol["subvol"])
""" Set default subvolume """
if subvolid != -1:
- argv = [ self.btrfscmd, "subvolume", "set-default", "%d" % subvolid, pdisk.mountdir]
- p1 = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- (out,err) = p1.communicate()
- msger.debug(out)
- if p1.returncode != 0:
- raise MountError("Failed to set default subvolume id: %d', return code: %d." % (subvolid, p1.returncode))
+ rc = runner.show([ self.btrfscmd, "subvolume", "set-default", "%d" % subvolid, pdisk.mountdir])
+ if rc != 0:
+ raise MountError("Failed to set default subvolume id: %d', return code: %d." % (subvolid, rc))
self.__create_subvolume_metadata(p, pdisk)
return
""" Remount to make default subvolume mounted """
- rc = subprocess.call([self.umountcmd, pdisk.mountdir])
+ rc = runner.show([self.umountcmd, pdisk.mountdir])
if rc != 0:
raise MountError("Failed to umount %s" % pdisk.mountdir)
- rc = subprocess.call([self.mountcmd, "-o", pdisk.fsopts, pdisk.disk.device, pdisk.mountdir])
+
+ rc = runner.show([self.mountcmd, "-o", pdisk.fsopts, pdisk.disk.device, pdisk.mountdir])
if rc != 0:
raise MountError("Failed to umount %s" % pdisk.mountdir)
+
for subvol in self.subvolumes:
if subvol["mountpoint"] == "/":
continue
subvol['fsopts'] = fsopts
mountpoint = self.mountdir + subvol['mountpoint']
makedirs(mountpoint)
- rc = subprocess.call([self.mountcmd, "-o", fsopts, pdisk.disk.device, mountpoint])
+ rc = runner.show([self.mountcmd, "-o", fsopts, pdisk.disk.device, mountpoint])
if rc != 0:
raise MountError("Failed to mount subvolume %s to %s" % (subvol["subvol"], mountpoint))
subvol["mounted"] = True
if not subvol["mounted"]:
continue
mountpoint = self.mountdir + subvol['mountpoint']
- rc = subprocess.call([self.umountcmd, mountpoint])
+ rc = runner.show([self.umountcmd, mountpoint])
if rc != 0:
raise MountError("Failed to unmount subvolume %s from %s" % (subvol["subvol"], mountpoint))
subvol["mounted"] = False
def __create_subvolume_snapshots(self, p, pdisk):
+ import time
+
if self.snapshot_created:
return
""" Remount with subvolid=0 """
- rc = subprocess.call([self.umountcmd, pdisk.mountdir])
+ rc = runner.show([self.umountcmd, pdisk.mountdir])
if rc != 0:
raise MountError("Failed to umount %s" % pdisk.mountdir)
if pdisk.fsopts:
mountopts = pdisk.fsopts + ",subvolid=0"
else:
mountopts = "subvolid=0"
- rc = subprocess.call([self.mountcmd, "-o", mountopts, pdisk.disk.device, pdisk.mountdir])
+ rc = runner.show([self.mountcmd, "-o", mountopts, pdisk.disk.device, pdisk.mountdir])
if rc != 0:
raise MountError("Failed to umount %s" % pdisk.mountdir)
for subvol in self.subvolumes:
subvolpath = pdisk.mountdir + "/" + subvol["subvol"]
snapshotpath = subvolpath + "_%s-1" % snapshotts
- argv = [ self.btrfscmd, "subvolume", "snapshot", subvolpath, snapshotpath ]
- p1 = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- (out,err) = p1.communicate()
- msger.debug(out)
- if p1.returncode != 0:
- raise MountError("Failed to create subvolume snapshot '%s' for '%s', return code: %d." % (snapshotpath, subvolpath, p1.returncode))
+ rc = runner.show([ self.btrfscmd, "subvolume", "snapshot", subvolpath, snapshotpath ])
+ if rc != 0:
+ raise MountError("Failed to create subvolume snapshot '%s' for '%s', return code: %d." % (snapshotpath, subvolpath, rc))
+
self.snapshot_created = True
def mount(self):
break
if mp == 'swap':
- subprocess.call([self.mkswap, p['device']])
+ runner.show([self.mkswap, p['device']])
continue
rmmountdir = False
def do_chroot(self, target):#chroot.py parse opts&args
try:
chroot.chroot(target, None, "/bin/env HOME=/root /bin/bash")
- except:
- msger.warning("Failed to chroot to %s." % target)
finally:
chroot.cleanup_after_chroot("dir", None, None, None)
return 1
@classmethod
def do_chroot(cls, target):
- import subprocess
-
img = target
imgsize = misc.get_file_size(img) * 1024L * 1024L
partedcmd = fs_related.find_binary_path("parted")
# Check the partitions from raw disk.
root_mounted = False
partition_mounts = 0
- for line in subprocess.Popen([partedcmd,"-s",img,"unit","B","print"],
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\
- .communicate()[0]\
- .strip()\
- .splitlines():
-
+ for line in runner.outs([partedcmd,"-s",img,"unit","B","print"]).splitlines():
line = line.strip()
# Lines that start with number are the partitions,