[PATCH rhel6-branch] Increment MD container child counter even if its volumes are ignored (#1120640)
by Artur Paszkiewicz
Volumes which are not selected in Specialized Storage Devices are
ignored in addUdevDevice. This causes that their parent container
won't have its child counter incremented, which can later cause an
incorrect unusedRaidMembersWarning.
Resolves: rhbz#1120640
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz(a)intel.com>
---
storage/devicetree.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/storage/devicetree.py b/storage/devicetree.py
index 4045cdf..b9ea399 100644
--- a/storage/devicetree.py
+++ b/storage/devicetree.py
@@ -1328,6 +1328,13 @@ class DeviceTree(object):
# slice off the "/dev/" part, lvm filter cares only about the rest
partitions_paths = [p[5:] for p in partitions_paths]
map(lvm.lvm_cc_addFilterRejectRegexp, partitions_paths)
+
+ if udev_device_get_md_container(info):
+ parentName = devicePathToName(udev_device_get_md_container(info))
+ container = self.getDeviceByName(parentName)
+ if container:
+ container.addChild()
+
return
log.debug("scanning %s (%s)..." % (name, sysfs_path))
--
1.8.4.5
8 years, 3 months
[f21-branch][PATCH] clean up stage1 volume check, check format as well as mountpoint
by Adam Williamson
This is a follow-on from e2d10a04. To reduce the change from
the previous behaviour and minimize the chance of any strange
corner-case breakage, this sorts the disk list, rather than
filtering it.
It also now checks the format_type constraint as well as the
mountpoint constraint. There are platforms (PPC) which use a
volume as the stage1 target, but don't require it to be mounted;
this handles those as well as platforms which require the target
volume to be mounted to a specific location.
It's also slightly re-arranged to flow better with the existing
check that filters out protected, hidden and unusable disks.
The overall behaviour change can be described as: on platforms
which require the stage1 target to be a volume, use the first
enumerated disk which contains a potentially valid volume as
the 'boot disk' if the user does not explicitly specify one,
rather than just using the first enumerated disk and failing
if it does not contain a valid stage1 target volume (#1168118).
This also debug logs the result of the 'disks with potential
stage1 targets' check.
---
pyanaconda/kickstart.py | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index d44b349..4aa4fd8 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -379,22 +379,30 @@ class Bootloader(commands.bootloader.F21_Bootloader):
if self.timeout is not None:
storage.bootloader.timeout = self.timeout
- # try to reduce the set of possible 'boot disks' to the disks containing
- # a valid stage1 mount point, if there are any, because those disks
- # should be searched for a stage1_valid device
- disks = storage.disks
- if platform.bootStage1ConstraintDict["mountpoints"]:
- disks = [p.disk for p in storage.devices if getattr(p.format, "mountpoint", None) in platform.bootStage1ConstraintDict["mountpoints"]]
- if not disks:
- # but if not, just go ahead and use the set of all disks or
- # else we'll error out later
- disks = storage.disks
-
# Throw out drives specified that don't exist or cannot be used (iSCSI
# device on an s390 machine)
- disk_names = [d.name for d in disks
- if not d.format.hidden and not d.protected and
- (not blivet.arch.isS390() or not isinstance(d, blivet.devices.iScsiDiskDevice))]
+ disks = [d for d in storage.disks
+ if not d.format.hidden and not d.protected and
+ (not blivet.arch.isS390() or not isinstance(d, blivet.devices.iScsiDiskDevice))]
+ if platform.bootStage1ConstraintDict["format_types"]:
+ # sort the list of disks with those that contain possibly-valid
+ # stage1 partitions first, so we'll pick a disk with one as
+ # bootDrive if it has not been explicitly set: RHBZ #1168118
+ s1vols = [vol for vol in storage.devices if
+ getattr(vol.format, "type", None) in
+ platform.bootStage1ConstraintDict["format_types"]]
+ if platform.bootStage1ConstraintDict["mountpoints"]:
+ # further sort by volumes with valid mount points, if
+ # the platform requires this
+ s1disks = [vol.disk for vol in s1vols if
+ getattr(vol.format, "mountpoint", None) in
+ platform.bootStage1ConstraintDict["mountpoints"]]
+ else:
+ s1disks = [vol.disk for vol in s1vols]
+ log.debug("Disks with potentially valid stage1 volumes: %s",
+ ' '.join([d.name for d in s1disks]))
+ disks.sort(key=lambda x: x in s1disks, reverse=True)
+ disk_names = [d.name for d in disks]
diskSet = set(disk_names)
for drive in self.driveorder[:]:
--
2.1.0
9 years, 2 months
[master] Strip lvm WARNING: lines from output (#1157864)
by Brian C. Lane
LVM has started including a pile of WARNING: lines in its output. These
need to be removed before the return value lvm() is used.
---
blivet/devicelibs/lvm.py | 41 ++++++++++++++++++++++++++---------------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/blivet/devicelibs/lvm.py b/blivet/devicelibs/lvm.py
index 09a4956..c521248 100644
--- a/blivet/devicelibs/lvm.py
+++ b/blivet/devicelibs/lvm.py
@@ -216,13 +216,22 @@ def is_valid_thin_pool_chunk_size(size, discard=False):
else:
return (size % LVM_THINP_MIN_CHUNK_SIZE == 0)
+def strip_lvm_warnings(buf):
+ """ Strip out lines starting with WARNING:
+
+ :param str buf: A string returned from lvm
+ :returns: A list of strings
+ :rtype: list
+ """
+ return [l for l in buf.splitlines() if l and not l.strip().startswith("WARNING:")]
+
def lvm(args, capture=False, ignore_errors=False):
""" Runs lvm with specified arguments.
:param bool capture: if True, return the output of the command.
:param bool ignore_errors: if True, do not raise LVMError on failure
- :returns: the output of the command or None
- :rtype: str or NoneType
+ :returns: list of strings from the output of the command or None
+ :rtype: list or NoneType
:raises: LVMError if command fails
"""
argv = ["lvm"] + args + _getConfigArgs(args)
@@ -230,7 +239,7 @@ def lvm(args, capture=False, ignore_errors=False):
if ret and not ignore_errors:
raise LVMError("running "+ " ".join(argv) + " failed")
if capture:
- return out
+ return strip_lvm_warnings(out)
def pvcreate(device):
# we force dataalignment=1024k since we cannot get lvm to tell us what
@@ -324,9 +333,9 @@ def pvinfo(device=None):
if device:
args.append(device)
- buf = lvm(args, capture=True, ignore_errors=True)
+ lines = lvm(args, capture=True, ignore_errors=True)
pvs = {}
- for line in buf.splitlines():
+ for line in lines:
info = parse_lvm_vars(line)
if len(info.keys()) != 11:
log.warning("ignoring pvs output line: %s", line)
@@ -421,8 +430,12 @@ def vginfo(vg_name):
"-o", "uuid,size,free,extent_size,extent_count,free_count,pv_count",
vg_name]
- buf = lvm(args, capture=True, ignore_errors=True)
- info = parse_lvm_vars(buf)
+ lines = lvm(args, capture=True, ignore_errors=True)
+ try:
+ info = parse_lvm_vars(lines[0])
+ except IndexError:
+ info = {}
+
if len(info.keys()) != 7:
raise LVMError(_("vginfo failed for %s") % vg_name)
@@ -444,9 +457,9 @@ def lvs(vg_name=None):
if vg_name:
args.append(vg_name)
- buf = lvm(args, capture=True, ignore_errors=True)
+ lines = lvm(args, capture=True, ignore_errors=True)
logvols = {}
- for line in buf.splitlines():
+ for line in lines:
info = parse_lvm_vars(line)
if len(info.keys()) != 6:
log.debug("ignoring lvs output line: %s", line)
@@ -461,10 +474,9 @@ def lvorigin(vg_name, lv_name):
args = ["lvs", "--noheadings", "-o", "origin"] + \
["%s/%s" % (vg_name, lv_name)]
- buf = lvm(args, capture=True, ignore_errors=True)
-
+ lines = lvm(args, capture=True, ignore_errors=True)
try:
- origin = buf.splitlines()[0].strip()
+ origin = lines[0].strip()
except IndexError:
origin = ''
@@ -608,10 +620,9 @@ def thinlvpoolname(vg_name, lv_name):
args = ["lvs", "--noheadings", "-o", "pool_lv"] + \
["%s/%s" % (vg_name, lv_name)]
- buf = lvm(args, capture=True, ignore_errors=True)
-
+ lines = lvm(args, capture=True, ignore_errors=True)
try:
- pool = buf.splitlines()[0].strip()
+ pool = lines[0].strip()
except IndexError:
pool = ''
--
1.9.3
9 years, 3 months
[blivet:master 00/20] Patches related to _resizefsUnit
by Anne Mulhern
This turns out to be actually quite a lot of patches about Sizes.
The first 8 patches are minor fixes for little things that I ran into
while worrying about Sizes.
With "Make _Prefix entries..." I'm starting to try to set things up so that
it is possible to have some kind of values that represent units to pass
to convertTo() and roundToNearest(). By using string specifiers of units
as arguments to these methods, we end up using _parseUnits() to find out
the units. This is kind of a mistake, because it is a method that is
really designed for parsing human input size strings, so it is
unnecessarily heavyweight for a context where the units is precisely known
and specified explicitly in the program.
"Do not even pretend..." patch is a bit of a one off. I really think we can
get rid of that code, about the only thing it is likely ever to do for us
is halt some install sometime (if it is ever run).
Then come three patches about resizeArgs() and _resizefsUnit. The last
two of these may be somewhat controversial. Here's my take on things:
Without the "Use _resizefsUnit in resizeArgs()..." patch a developer has to
have or somehow obtain some knowledge about the connection between
the unit in resizeArgs() and the one in getMinSize(). Let's suppose they
change _resizefsUnit (because they want to change how getMinSize() behaves).
They can:
(1) Fail to realize that they need to change resizeArgs() as well. If they
are lucky, and they changed _resizefsUnit to a multiple of the units in
resizeArgs() there may or not appear to be a problem. If they are unlucky
and they changd _resizefsUnit to something other than a multiple, then
the result of the resize operation will most likely be wrong. That would
be a bug.
(2) Realize that they need to change the units of resizeArgs() correspondingly.
If so, they ought to have the good sense to look at the containing
expression, and infer that they need to change the format string as well.
With the "Use _resizefsUnit in resizeArgs()..." patch a developer does not
need to know any secret lore. Being conscientious, they do a search for the
string _resizefsUnit and find it in resizeArgs(). They know there is a
connection and only possibility (2) from above is available.
My patch eliminates the possibility of bugs arising from situation (1).
I realize it relies on the programmer being able to realize that if the
units of the size change, so should the format string, but I _think_
that's not hard.
Finally, there are two patches about Size.__new__. The motivation
for these two is to avoid running the _parseSpec() method from
Size.__new__() as _parseSpec() is really designed to handle
user-input strings. It is far too general for literals specified in the
program and is correspondingly busy. The locale stuff, the regular
expression matching, iterating through a list dynamically calculating
string specs and comparing them with the string given is huge overkill
when the unit required is already known at compile time.
This approach is less invasive than some others and does not _require_
any change to user code. I think that ideally user input parsing would
be handled in anaconda, since that is not really blivet's job at all, but
I think that would be in the far future, so might as well do this for now.
This approach speeds construction of Size() object up by a factor of 3 or 4,
suprisingly little. But it seems like the more correct thing. If everybody
accepts it, I'll also convert the Size literals in tests subdirectory to
use tuples.
mulhern (20):
Get rid of unnecessary use of long.
Make possiblePhysicalExtents() a bit more direct.
Do not compare the same two values twice.
Do not calculate Sizes unless they are needed.
Avoid using Size constant in FileDevice._create().
Eliminate redundant test.
Comment _prefixTestHelper() and eliminate some redundancies.
Hoist _BINARY_FACTOR * min_value calculation out of loop.
Make _Prefix entries named constants.
Add unitStr() method.
Make _parseUnits() return a unit constant, rather than a number.
Get whole unit tuple in loop when searching for correct units.
Do not even pretend that ReiserFS is resizable.
Change convertTo() and roundToNearest() so each takes a units
specifier.
Use convertTo in humanReadable().
Do not supply a default implementation for the resizeArgs() method.
Use _resizefsUnit in resizeArgs() method implementations.
Add _resizefsUnit to TmpFS and use in appropriate places.
Add a new way of specifying Sizes().
Use tuples to construct Sizes() wherever units are known.
blivet/devicefactory.py | 6 +-
blivet/devicelibs/btrfs.py | 4 +-
blivet/devicelibs/crypto.py | 4 +-
blivet/devicelibs/lvm.py | 45 +++++-----
blivet/devicelibs/mdraid.py | 10 +--
blivet/devicelibs/swap.py | 15 ++--
blivet/devices/file.py | 8 +-
blivet/devices/lvm.py | 16 ++--
blivet/devices/partition.py | 12 +--
blivet/formats/biosboot.py | 6 +-
blivet/formats/fs.py | 77 ++++++++---------
blivet/formats/prepboot.py | 6 +-
blivet/formats/swap.py | 4 +-
blivet/partitioning.py | 6 +-
blivet/platform.py | 22 ++---
blivet/size.py | 168 ++++++++++++++++++++------------------
blivet/udev.py | 12 +--
blivet/util.py | 6 +-
tests/devicelibs_test/lvm_test.py | 5 --
tests/size_test.py | 96 +++++++++++-----------
tests/storagetestcase.py | 4 +-
21 files changed, 261 insertions(+), 271 deletions(-)
--
1.9.3
9 years, 4 months
[PATCH 1/2 livemedia-creator atomic] Add --make-pxe-live target and --ostree flag for Atomic Host.
by Radek Vykydal
Generate live squashfs and initrd for pxe live install.
Also generate pxe config template.
To be used with virt installation with /boot on separate partition (the only
way supported by Anaconda currently). Content of boot partition is added to
live root fs so that ostree can find deployment by boot configuration.
--ostree flag ensures using deployment root instead of physical root of
installed disk image where needed.
---
docs/rhel-atomic-pxe-live.ks | 39 +++++++
src/sbin/livemedia-creator | 238 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 274 insertions(+), 3 deletions(-)
create mode 100644 docs/rhel-atomic-pxe-live.ks
diff --git a/docs/rhel-atomic-pxe-live.ks b/docs/rhel-atomic-pxe-live.ks
new file mode 100644
index 0000000..324dad2
--- /dev/null
+++ b/docs/rhel-atomic-pxe-live.ks
@@ -0,0 +1,39 @@
+# Kickstart to be used to genrate pxe to live atomic image using --pxe-to-live and --ostree options
+lang en_US.UTF-8
+keyboard us
+timezone America/New_York
+clearpart --all --initlabel
+network --bootproto=dhcp --device=link --activate
+rootpw --plaintext atomic
+
+# We are only able to install atomic with separate /boot partition currently
+part / --fstype="ext4" --size=6000
+part /boot --size=500 --fstype="ext4"
+
+shutdown
+
+services --disabled=cloud-init,cloud-init-local,cloud-final,cloud-config,docker-storage-setup
+
+# Regenerating initramfs requires dracut-network package in repo, relabeling rootfs requires policycoreutils
+#ostreesetup --osname=rhel-atomic-host --remote=rhel-atomic-host --url=http://10.34.102.90:8000/repo --ref=rhel-atomic-host/7.0-buildmaster/x86_64/standard --nogpg
+ostreesetup --osname=rhel-atomic-host --remote=rhel-atomic-host --url=http://10.34.102.90:8000/repo --ref=rhel-atomic-host/7.0-buildmaster/x86_64/live-selinux --nogpg
+
+# We throw away separate /boot partition when building live squashfs image,
+# and we don't want systemd to try to mount it when pxe booting
+%post
+cat /dev/null > /etc/fstab
+%end
+
+# This comes from interactive-defaults.ks of installer.iso with included ostree repo
+%post --erroronfail
+rm -f /etc/ostree/remotes.d/rhel-atomic-host.conf
+%end
+
+# This comes from interactive-defaults.ks of installer.iso with included ostree repo
+%post --erroronfail
+rm -f /etc/ostree/remotes.d/*.conf
+echo 'unconfigured-state=This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.' >> $(ostree admin --print-current-dir).origin
+%end
+
+
+
diff --git a/src/sbin/livemedia-creator b/src/sbin/livemedia-creator
index e25d422..e25291c 100755
--- a/src/sbin/livemedia-creator
+++ b/src/sbin/livemedia-creator
@@ -37,6 +37,7 @@ import shutil
import argparse
import hashlib
import re
+import glob
# Use pykickstart to calculate disk image size
from pykickstart.parser import KickstartParser
@@ -52,9 +53,9 @@ from pylorax.treebuilder import TreeBuilder, RuntimeBuilder, udev_escape
from pylorax.treebuilder import findkernels
from pylorax.sysutils import joinpaths, remove
from pylorax.imgutils import PartitionMount, mksparse, mkext4img, loop_detach
-from pylorax.imgutils import get_loop_name, dm_detach, mount, umount, Mount
+from pylorax.imgutils import get_loop_name, dm_detach, mount, umount, Mount, LoopDev
from pylorax.imgutils import mksquashfs, mkqcow2, mktar
-from pylorax.executils import execWithRedirect, execWithCapture
+from pylorax.executils import execWithRedirect, execWithCapture, runcmd
# no-virt mode doesn't need libvirt, so make it optional
try:
@@ -414,6 +415,21 @@ def is_image_mounted(disk_img):
return True
return False
+def find_ostree_root(phys_root):
+ """
+ Find root of ostree deployment
+
+ :param str phys_root: Path to physical root
+ :returns: Relative path of ostree deployment root
+ :rtype: str
+ """
+ ostree_root = ""
+ ostree_sysroots = glob.glob(joinpaths(phys_root, "ostree/boot.0/*/*/0"))
+ if ostree_sysroots:
+ if len(ostree_sysroots) > 1:
+ log.error("Too many deployment roots found: %s" % ostree_sysroots)
+ ostree_root = os.path.relpath(ostree_sysroots[0], phys_root)
+ return ostree_root
def get_arch(mount_dir):
"""
@@ -499,7 +515,6 @@ def make_fsimage(diskimage, fsimage, img_size=None, label="Anaconda"):
mkext4img(img_mount.mount_dir, fsimage, size=img_size, label=label)
-
def make_runtime(opts, mount_dir, work_dir):
"""
Make the squashfs image from a directory
@@ -527,6 +542,118 @@ def make_runtime(opts, mount_dir, work_dir):
log.info("Creating runtime")
rb.create_runtime(joinpaths(work_dir, RUNTIME), size=None)
+def make_live_rootfs(mount_dir, image_path, size=2, sys_root=""):
+ """
+ Make rootfs image from a directory
+
+ :param str mount_dir: Root directory
+ :param str image_path: Path of output image file
+ :param int size: Size of the image, if None computed automatically
+ :param str sys_root: path to system (deployment) root relative to physical root
+ """
+ if size:
+ fssize = size * (1024*1024*1024) # 2GB sparse file compresses down to nothin'
+ else:
+ fssize = None # Let mkext4img figure out the needed size
+
+ mkext4img(mount_dir, image_path, label="LiveOS", size=fssize)
+ # Reset selinux context on new rootfs
+ with LoopDev(image_path) as loopdev:
+ with Mount(loopdev) as mnt:
+ cmd = [ "setfiles", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/install",
+ "/etc/selinux/targeted/contexts/files/file_contexts", "/"]
+ root = joinpaths(mnt, sys_root.lstrip("/"))
+ runcmd(cmd, root=root)
+
+def rebuild_initrds_for_live(opts, sys_root_dir, results_dir):
+ """
+ Rebuild intrds for pxe live image (root=live:http://)
+
+ :param opts: options passed to livemedia-creator
+ :type opts: argparse options
+ :param str sys_root_dir: Path to root of the system
+ :param str results_dir: Path of directory for storing results
+ """
+ if not opts.dracut_args:
+ dracut_args = DRACUT_DEFAULT
+ else:
+ dracut_args = []
+ for arg in opts.dracut_args:
+ dracut_args += arg.split(" ", 1)
+ log.info("dracut args = {0}".format(dracut_args))
+
+ dracut = ["dracut", "--nomdadmconf", "--nolvmconf"] + dracut_args
+
+ kdir = "boot"
+ if opts.ostree:
+ kernels_dir = glob.glob(joinpaths(sys_root_dir, "boot/ostree/*"))[0]
+ kdir = os.path.relpath(kernels_dir, sys_root_dir)
+
+ kernels = [kernel for kernel in findkernels(sys_root_dir, kdir)
+ if hasattr(kernel, "initrd")]
+ if not kernels:
+ raise Exception("No initrds found, cannot rebuild_initrds")
+
+ # Hush some dracut warnings. TODO: bind-mount proc in place?
+ open(joinpaths(sys_root_dir,"/proc/modules"),"w")
+
+ if opts.ostree:
+ # Dracut assumes to have some dirs in disk image
+ # /var/tmp for temp files
+ vartmp_dir = joinpaths(sys_root_dir, "var/tmp")
+ if not os.path.isdir(vartmp_dir):
+ os.mkdir(vartmp_dir)
+ # /root (maybe not fatal)
+ root_dir = joinpaths(sys_root_dir, "var/roothome")
+ if not os.path.isdir(root_dir):
+ os.mkdir(root_dir)
+ # /tmp (maybe not fatal)
+ tmp_dir = joinpaths(sys_root_dir, "sysroot/tmp")
+ if not os.path.isdir(tmp_dir):
+ os.mkdir(tmp_dir)
+
+ for kernel in kernels:
+
+ outfile = kernel.initrd.path + ".live"
+ log.info("rebuilding %s", outfile)
+
+ kver = kernel.version
+
+ cmd = dracut + [outfile, kver]
+ runcmd(cmd, root=sys_root_dir)
+
+ new_initrd_path = joinpaths(results_dir, os.path.basename(kernel.initrd.path))
+ shutil.move(joinpaths(sys_root_dir, outfile), new_initrd_path)
+ shutil.copy2(joinpaths(sys_root_dir, kernel.path), results_dir)
+
+ os.unlink(joinpaths(sys_root_dir,"/proc/modules"))
+
+def create_pxe_config(images_dir, live_image_name, add_args = None):
+ """
+ Create template for pxe to live configuration
+
+ :param str images_dir: Path of directory with images to be used
+ :param str live_image_name: Name of live rootfs image file
+ :param list add_args: Arguments to be added to initrd= pxe config
+ """
+
+ add_args = add_args or []
+
+ kernels = [kernel for kernel in findkernels(images_dir, kdir="")
+ if hasattr(kernel, "initrd")]
+ if not kernels:
+ return
+
+ kernel = kernels[0]
+
+ add_args_str = " ".join(add_args)
+
+ buf = """# PXE configuration template generated by livemedia-creator
+kernel <PXE_DIR>%s
+append initrd=<PXE_DIR>%s root=live:<URL>/%s %s
+""" % (kernel.path, kernel.initrd.path, live_image_name, add_args_str)
+ with open (joinpaths(images_dir, "PXE_CONFIG"), "w") as f:
+ f.write(buf)
def make_livecd(opts, mount_dir, work_dir):
"""
@@ -588,6 +715,34 @@ def make_livecd(opts, mount_dir, work_dir):
return work_dir
+def mount_boot_part_over_root(img_mount):
+ """
+ Mount boot partition to /boot of root fs mounted in img_mount
+
+ Used for OSTree so it finds deployment configurations on live rootfs
+
+ param img_mount: object with mounted disk image root partition
+ type img_mount: imgutils.PartitionMount
+ """
+ root_dir = img_mount.mount_dir
+ is_boot_part = lambda dir: os.path.exists(dir+"/loader.0")
+ tmp_mount_dir = tempfile.mkdtemp()
+ sys_root = find_ostree_root(root_dir)
+ sys_root_bootdir = None
+ for dev, size in img_mount.loop_devices:
+ try:
+ mount("/dev/mapper/"+dev, mnt=tmp_mount_dir)
+ if is_boot_part(tmp_mount_dir):
+ umount(tmp_mount_dir)
+ sysroot_boot_dir = joinpaths(joinpaths(root_dir, sys_root), "boot")
+ mount("/dev/mapper/"+dev, mnt=sysroot_boot_dir)
+ break
+ else:
+ umount(tmp_mount_dir)
+ except subprocess.CalledProcessError as e:
+ log.debug("Looking for boot partition error: %s", e)
+ remove(tmp_mount_dir)
+ return sysroot_boot_dir
def novirt_install(opts, disk_img, disk_size, repo_url):
"""
@@ -840,6 +995,52 @@ def make_image(opts, ks):
log.info("Disk Image install successful")
return disk_img
+def make_live_images(opts, work_dir, root_dir, rootfs_image=None):
+ """
+ Create live images from direcory or rootfs image
+
+ :param opts: options passed to livemedia-creator
+ :type opts: argparse options
+ :param str work_dir: Directory for storing results
+ :param str root_dir: Root directory of live filesystem tree
+ :param str rootfs_image: Path to live rootfs image to be used
+ :returns: Path of directory with created images
+ :rtype: str
+ """
+ sys_root = ""
+ if opts.ostree:
+ sys_root = find_ostree_root(root_dir)
+
+ squashfs_root_dir = joinpaths(work_dir, "squashfs_root")
+ liveos_dir = joinpaths(squashfs_root_dir, "LiveOS")
+ os.makedirs(liveos_dir)
+
+ if rootfs_image:
+ rc = execWithRedirect("/bin/ln", [rootfs_image, joinpaths(liveos_dir, "rootfs.img")])
+ if rc != 0:
+ shutil.copy2(rootfs_image, joinpaths(liveos_dir, "rootfs.img"))
+ else:
+ log.info("Creating live rootfs image")
+ make_live_rootfs(root_dir, joinpaths(liveos_dir, "rootfs.img"), size=None, sys_root=sys_root)
+
+ log.info("Packing live rootfs image")
+ add_pxe_args = []
+ live_image_name = "live-rootfs.squashfs.img"
+ mksquashfs(squashfs_root_dir,
+ joinpaths(work_dir, live_image_name),
+ opts.compression,
+ opts.compress_args)
+
+ remove(squashfs_root_dir)
+
+ log.info("Rebuilding initramfs for live")
+ rebuild_initrds_for_live(opts, joinpaths(root_dir, sys_root), work_dir)
+
+ if opts.ostree:
+ add_pxe_args.append("ostree=/%s" % sys_root)
+ create_pxe_config(work_dir, live_image_name, add_pxe_args)
+
+ return work_dir
def setup_logging(opts):
"""
@@ -892,6 +1093,8 @@ def main():
help="Build an ami image")
action.add_argument("--make-tar", action="store_true",
help="Build a tar of the root filesystem")
+ action.add_argument("--make-pxe-live", action="store_true",
+ help="Build live in squashfs and initrd for pxe boot")
parser.add_argument("--iso", type=os.path.abspath,
help="Anaconda installation .iso path to use for virt-install")
@@ -914,6 +1117,9 @@ def main():
help="location of iso directory tree with initrd.img "
"and vmlinuz. Used to run virt-install with a "
"newer initrd than the iso.")
+ parser.add_argument("--ostree", action="store_true",
+ help="Ostree (Atomic) installation")
+
parser.add_argument("--logfile", default="./livemedia.log",
type=os.path.abspath,
@@ -1165,6 +1371,32 @@ def main():
make_appliance(opts.disk_image or disk_img, opts.app_name,
opts.app_template, opts.app_file, networks, opts.ram,
opts.vcpus, opts.arch, opts.title, opts.project, opts.releasever)
+ elif opts.make_pxe_live:
+
+ work_dir = tempfile.mkdtemp()
+ log.info("working dir is {0}".format(work_dir))
+
+ if (opts.fs_image or opts.no_virt) and not opts.disk_image:
+ # Create pxe live images from a filesystem image
+ disk_img = opts.fs_image or disk_img
+ with Mount(disk_img, opts="loop") as mnt_dir:
+ result_dir = make_live_images(opts, work_dir, mnt_dir, rootfs_image=disk_img)
+ else:
+ # Create pxe live images from a partitioned disk image
+ disk_img = opts.disk_image or disk_img
+ is_root_part = None
+ if opts.ostree:
+ is_root_part = lambda dir: os.path.exists(dir+"/ostree/deploy")
+ with PartitionMount(disk_img, mount_ok=is_root_part) as img_mount:
+ if img_mount and img_mount.mount_dir:
+
+ mounted_sysroot_boot_dir = None
+ if opts.ostree:
+ mounted_sysroot_boot_dir = mount_boot_part_over_root(img_mount)
+
+ result_dir = make_live_images(opts, work_dir, img_mount.mount_dir)
+ if mounted_sysroot_boot_dir:
+ umount(mounted_sysroot_boot_dir)
if opts.result_dir and result_dir:
shutil.copytree(result_dir, opts.result_dir)
--
1.9.3
9 years, 4 months
[rhel6-branch] Detect and show a warning for LDL DASDs. (#1144979)
by Samantha N. Bueno
Check if any of the DASDs on an s390x system are LDL formatted. If they
are, show a warning to users and give them the option to run dasdfmt
against them, which will (re-)format them as CDL DASDs.
Resolves: rhbz#1144979
---
installinterfacebase.py | 4 ++--
storage/dasd.py | 21 +++++++++++++++------
2 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/installinterfacebase.py b/installinterfacebase.py
index d4f20fa..6d454e0 100644
--- a/installinterfacebase.py
+++ b/installinterfacebase.py
@@ -80,12 +80,12 @@ class InstallInterfaceBase(object):
title = P_("Unformatted DASD Device Found",
"Unformatted DASD Devices Found", c)
msg = P_("Format uninitialized DASD device?\n\n"
- "There is %d uninitialized DASD device on this "
+ "There is %d uninitialized or LDL DASD device on this "
"system. To continue installation, the device must "
"be formatted. Formatting will remove any data on "
"this device." % c,
"Format uninitialized DASD devices?\n\n"
- "There are %d uninitialized DASD devices on this "
+ "There are %d uninitialized or LDL DASD devices on this "
"system. To continue installation, the devices must "
"be formatted. Formatting will remove any data on "
"these devices." % c,
diff --git a/storage/dasd.py b/storage/dasd.py
index 3a20b16..1576048 100644
--- a/storage/dasd.py
+++ b/storage/dasd.py
@@ -20,6 +20,7 @@
#
import iutil
+import isys
import sys
import os
from storage.errors import DasdFormatError
@@ -59,6 +60,9 @@ class DASD:
def startup(self, intf, exclusiveDisks, zeroMbr):
""" Look for any unformatted DASDs in the system and offer the user
the option for format them with dasdfmt or exit the installer.
+
+ Also check if any DASDs are LDL formatted and show a warning to
+ users, since these disks will not be usable during installation.
"""
if self.started:
return
@@ -73,7 +77,7 @@ class DASD:
# Trigger udev data about the dasd devices on the system
udev_trigger(action="change", name="dasd*")
- log.info("Checking for unformatted DASD devices:")
+ log.info("Checking for unformatted and LDL DASD devices:")
for device in os.listdir("/sys/block"):
if not device.startswith("dasd"):
@@ -87,18 +91,23 @@ class DASD:
status = f.read().strip()
f.close()
- if status in ["unformatted"] and device not in exclusiveDisks:
- bypath = deviceNameToDiskByPath(device)
- if not bypath:
- bypath = "/dev/" + device
+ bypath = deviceNameToDiskByPath(device)
+ if not bypath:
+ bypath = "/dev/" + device
+ if status in ["unformatted"] and device not in exclusiveDisks:
log.info(" %s (%s) status is %s, needs dasdfmt" % (device,
bypath,
status,))
self._dasdlist.append((device, bypath))
+ elif isys.isLdlDasd(device):
+ log.info(" %s (%s) is an LDL DASD, needs dasdfmt" % (device,
+ bypath))
+ self._dasdlist.append((device, bypath))
+
if not len(self._dasdlist):
- log.info(" no unformatted DASD devices found")
+ log.info(" no unformatted or LDL DASD devices found")
return
askUser = True
--
1.9.3
9 years, 4 months
[PATCH] Mount efivarfs under /mnt/sysimage on appropriate platforms
by Peter Jones
Bug 1129435 was fixed in the efibootmgr code, but that code only works
if we've got the newer kernel interface available, which requires
mounting it. If we don't mount it, we hit the old code path, which
doesn't allow us to create device paths > 1024 bytes.
Signed-off-by: Peter Jones <pjones(a)redhat.com>
---
blivet/__init__.py | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/blivet/__init__.py b/blivet/__init__.py
index 210d3c6..2c8d26b 100644
--- a/blivet/__init__.py
+++ b/blivet/__init__.py
@@ -85,6 +85,7 @@ from . import util
from . import arch
from .flags import flags
from .platform import platform as _platform
+from .platform import EFI
from .size import Size
from .i18n import _
@@ -2260,6 +2261,7 @@ class FSSet(object):
self._devshm = None
self._usb = None
self._selinux = None
+ self._efivars = None
self._run = None
self._fstab_swaps = set()
self.preserveLines = [] # lines we just ignore and preserve
@@ -2310,6 +2312,12 @@ class FSSet(object):
return self._selinux
@property
+ def efivars(self):
+ if not self._efivars:
+ self._efivars = NoDevice(fmt=getFormat("efivarfs", device="efivarfs", mountpoint="/sys/firmware/efi/efivars"))
+ return self._efivars
+
+ @property
def run(self):
if not self._run:
self._run = DirectoryDevice("/run",
@@ -2386,7 +2394,8 @@ class FSSet(object):
device=device.path,
exists=True)
elif mountpoint in ("/proc", "/sys", "/dev/shm", "/dev/pts",
- "/sys/fs/selinux", "/proc/bus/usb"):
+ "/sys/fs/selinux", "/proc/bus/usb",
+ "/sys/firmware/efi/efivars"):
# drop these now -- we'll recreate later
return None
else:
@@ -2554,6 +2563,8 @@ class FSSet(object):
devices = list(self.mountpoints.values()) + self.swapDevices
devices.extend([self.dev, self.devshm, self.devpts, self.sysfs,
self.proc, self.selinux, self.usb, self.run])
+ if isinstance(_platform, EFI):
+ devices.append(self.efivars)
devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
for device in devices:
@@ -2611,6 +2622,8 @@ class FSSet(object):
devices = list(self.mountpoints.values()) + self.swapDevices
devices.extend([self.dev, self.devshm, self.devpts, self.sysfs,
self.proc, self.usb, self.selinux, self.run])
+ if isinstance(_platform, EFI):
+ devices.append(self.efivars)
devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
devices.reverse()
for device in devices:
--
2.1.0
9 years, 4 months
[PATCH] Start the network before the display (#1167103)
by David Shea
Sometimes the display is on the network.
If there is a kickstart file containing a static network configuration,
and dracut started the network using dhcp (for example, vnc was on the
command line but no ip arguments were), it's possible to change
addresses after VNC has started, which doesn't work real well.
---
anaconda | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/anaconda b/anaconda
index 80b39f6..4ded503 100755
--- a/anaconda
+++ b/anaconda
@@ -1215,6 +1215,12 @@ if __name__ == "__main__":
import blivet
blivet.enable_installer_mode()
+ # Initialize the network now, in case the display needs it
+ from pyanaconda.network import networkInitialize, wait_for_connecting_NM_thread
+
+ networkInitialize(ksdata)
+ threadMgr.add(AnacondaThread(name=constants.THREAD_WAIT_FOR_CONNECTING_NM, target=wait_for_connecting_NM_thread, args=(ksdata,)))
+
# now start the interface
setupDisplay(anaconda, opts, addon_paths)
@@ -1266,7 +1272,6 @@ if __name__ == "__main__":
from blivet import storageInitialize
from pyanaconda.packaging import payloadMgr
- from pyanaconda.network import networkInitialize, wait_for_connecting_NM_thread
from pyanaconda.timezone import time_initialize
if flags.rescue_mode:
@@ -1274,14 +1279,12 @@ if __name__ == "__main__":
else:
cleanPStore()
- networkInitialize(ksdata)
if not flags.dirInstall:
threadMgr.add(AnacondaThread(name=constants.THREAD_STORAGE, target=storageInitialize,
args=(anaconda.storage, ksdata, anaconda.protected)))
threadMgr.add(AnacondaThread(name=constants.THREAD_TIME_INIT, target=time_initialize,
args=(ksdata.timezone, anaconda.storage, anaconda.bootloader)))
- threadMgr.add(AnacondaThread(name=constants.THREAD_WAIT_FOR_CONNECTING_NM, target=wait_for_connecting_NM_thread, args=(ksdata,)))
# Fallback to default for interactive or for a kickstart with no installation method.
fallback = not (flags.automatedInstall and ksdata.method.method)
--
2.1.0
9 years, 4 months
[blivet:master] Use _resizefsUnit in resizeArgs() method.
by Anne Mulhern
The reason it is used elsewhere, i.e., when calculating minimum size
is because of the constraint on the resizeArgs() method to use the
units defined by _resizefsUnit. This patch makes that explicit.
Also, get rid of realistic FS.resizeArgs() implementation and make clear
that it needs to be overridden for subclasses that have resize functionality.
Add a resizefsUnit to ReiserFS and use it appropriately. ReiserFS._resizable
is False, so this makes no difference in operation.
This patch doesn't change behavior, it mostly replaces a literal with an
already defined constant in appropriate places.
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
blivet/formats/fs.py | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py
index 07a383a..73a7d59 100644
--- a/blivet/formats/fs.py
+++ b/blivet/formats/fs.py
@@ -431,8 +431,14 @@ class FS(DeviceFormat):
@property
def resizeArgs(self):
- argv = [self.device, "%d" % (self.targetSize.convertTo("MiB"),)]
- return argv
+ """ Returns the arguments for resizing the filesystem.
+
+ Must be overridden by every class that has non-None _resizefs.
+
+ :returns: arguments for resizing a filesystem.
+ :rtype: list of str
+ """
+ return []
def doResize(self):
""" Resize this filesystem based on this instance's targetSize attr.
@@ -1041,7 +1047,7 @@ class Ext2FS(FS):
@property
def resizeArgs(self):
- argv = ["-p", self.device, "%dM" % (self.targetSize.convertTo("MiB"))]
+ argv = ["-p", self.device, "%dM" % (self.targetSize.convertTo(self._resizefsUnit))]
return argv
register_device_format(Ext2FS)
@@ -1239,6 +1245,7 @@ class ReiserFS(FS):
_type = "reiserfs"
_mkfs = "mkreiserfs"
_resizefs = "resize_reiserfs"
+ _resizefsUnit = "MiB"
_labelfs = fslabeling.ReiserFSLabeling()
_modules = ["reiserfs"]
_defaultFormatOptions = ["-f", "-f"]
@@ -1263,7 +1270,7 @@ class ReiserFS(FS):
@property
def resizeArgs(self):
- argv = ["-s", "%dM" % (self.targetSize.convertTo(spec="MiB"),), self.device]
+ argv = ["-s", "%dM" % (self.targetSize.convertTo(spec=self._resizefsUnit),), self.device]
return argv
register_device_format(ReiserFS)
@@ -1446,7 +1453,7 @@ class NTFS(FS):
def resizeArgs(self):
# You must supply at least two '-f' options to ntfsresize or
# the proceed question will be presented to you.
- argv = ["-ff", "-s", "%d" % self.targetSize.convertTo(spec="b"),
+ argv = ["-ff", "-s", "%d" % self.targetSize.convertTo(spec=self._resizefsUnit),
self.device]
return argv
@@ -1556,6 +1563,7 @@ class TmpFS(NoDevFS):
# remounting can be used to change
# the size of a live tmpfs mount
_resizefs = "mount"
+ _resizefsUnit = "MiB"
# as tmpfs is part of the Linux kernel,
# it is Linux-native
_linuxNative = True
@@ -1593,7 +1601,7 @@ class TmpFS(NoDevFS):
self._options = fsoptions
if self._size:
# absolute size for the tmpfs mount has been specified
- self._size_option = "size=%dm" % self._size.convertTo(spec="MiB")
+ self._size_option = "size=%dm" % self._size.convertTo(spec=self._resizefsUnit)
else:
# if no size option is specified, the tmpfs mount size will be 50%
# of system RAM by default
@@ -1675,7 +1683,7 @@ class TmpFS(NoDevFS):
# the mount command
# add the remount flag, size and any options
- remount_options = 'remount,size=%dm' % self.targetSize.convertTo(spec="MiB")
+ remount_options = 'remount,size=%dm' % self.targetSize.convertTo(spec=self._resizefsUnit)
# if any mount options are defined, append them
if self._options:
remount_options = "%s,%s" % (remount_options, self._options)
@@ -1695,7 +1703,7 @@ class TmpFS(NoDevFS):
# update the size option string
# -> please note that resizing always sets the
# size of this tmpfs mount to an absolute value
- self._size_option = "size=%dm" % self._size.convertTo(spec="MiB")
+ self._size_option = "size=%dm" % self._size.convertTo(spec=self._resizefsUnit)
register_device_format(TmpFS)
--
1.9.3
9 years, 4 months