Compare commits

..

25 Commits

Author SHA1 Message Date
Marek Marczykowski-Górecki 9593f58731
anaconda 25.20.9-17, qubes-anaconda-addon 4.0.11-1
4 years ago
Marek Marczykowski-Górecki 9c8a8d2fb4
anaconda-addon: run salt into VMs too
4 years ago
Marek Marczykowski-Górecki 967c9caa7c
Prefer createrepo_c over createrepo
4 years ago
Marek Marczykowski-Górecki 87116a2094
anaconda: allow user setup durign initial-setup phase, if kickstart wishes so
4 years ago
Marek Marczykowski-Górecki 32b3a210e0
Make proper text-based initial setup UI
4 years ago
Marek Marczykowski-Górecki 556b584f74
Move applying configuration to kickstart addon
4 years ago
Marek Marczykowski-Górecki 0ec125b967
anaconda 25.20.9-16, blivet 2.1.11-6
5 years ago
Marek Marczykowski-Górecki 91728177c2
anaconda: fix required disk space reporting in reclaim space dialog
5 years ago
Marek Marczykowski-Górecki 12cc054a74
blivet: do not mount pre-existing partitions and do not detect OS there
5 years ago
Marek Marczykowski-Górecki 1abde9cad3
anaconda: do not drop /boot from automatic partitioning
5 years ago
Marek Marczykowski-Górecki 40a1574500
blivet: Double default LVM thin pool metadata size
5 years ago
Marek Marczykowski-Górecki 7c2d9b37e3
blivet: update to 2.1.11
5 years ago
Frédéric Pierret (fepitre) 70d4252d91
travis: switch to bionic
5 years ago
Marek Marczykowski-Górecki a089792060
anaconda 25.20.9-15, lorax-templates-qubes 4.0.6, qubes-anaconda-addon 4.0.10
5 years ago
Marek Marczykowski-Górecki 3541eda275
comps: update debian template description
5 years ago
Marek Marczykowski-Górecki 533e8e75bd
anaconda: add plymouth.ignore-serial-consoles boot option by default
5 years ago
Marek Marczykowski-Górecki f3f7ae7a87
lorax-templates-qubes: add plymouth.ignore-serial-consoles kernel option
5 years ago
Marek Marczykowski-Górecki afd1fe2d41
qubes-anaconda-addon: update default template
5 years ago
Marek Marczykowski-Górecki 60af84f159
comps: update template versions for R4.0.2
5 years ago
Marek Marczykowski-Górecki 3c12390129
qubes-release 4.0-8
5 years ago
unman 2ce7edc6fe
Add new onion addresses to repo lists
5 years ago
Frédéric Pierret (fepitre) beb177026c
Add 'kernel-latest' and 'kernel-latest-qubes-vm' as optional packages
5 years ago
Marek Marczykowski-Górecki c92b713f9f
conf: create separate iso-full-online.ks for release builds
5 years ago
Frédéric Pierret (fepitre) cfe1e28266
Create ISO with new name format instead of legacy one
5 years ago
Frédéric Pierret (fepitre) e574ea6c3c
Add stamp for latest built iso
5 years ago

3
.gitmodules vendored

@ -1,3 +0,0 @@
[submodule "qubes-release"]
path = qubes-release
url = https://github.com/QubesOS/qubes-qubes-release

@ -4,15 +4,14 @@ language: generic
install: git clone https://github.com/QubesOS/qubes-builder ~/qubes-builder
script:
- ~/qubes-builder/scripts/travis-build
- travis_wait 45 $EXPECT_FAILURE make -C ~/qubes-builder iso BUILDERCONF=scripts/travis-builder.conf VERBOSE=0 COMPONENTS=installer-qubes-os
- travis_wait 35 $EXPECT_FAILURE make -C ~/qubes-builder iso BUILDERCONF=scripts/travis-builder.conf VERBOSE=0 COMPONENTS=installer-qubes-os
after_script:
- tail -n 100 ~/qubes-builder/build-logs/installer-qubes-os-iso-*.log
- ls -l ~/qubes-builder/iso
env:
- DIST_DOM0=fc31 INSTALLER_KICKSTART=/tmp/qubes-installer/conf/travis-iso-full.ks USE_QUBES_REPO_VERSION=4.1 USE_QUBES_REPO_TESTING=1 RPM_BUILD_DEFINES=--nocheck
- DIST_DOM0=fc31 INSTALLER_KICKSTART=/tmp/qubes-installer/conf/travis-iso-unsigned.ks USE_QUBES_REPO_VERSION=4.1 USE_QUBES_REPO_TESTING=1 EXPECT_FAILURE=./scripts/expected-failure
- DIST_DOM0=fc31 INSTALLER_KICKSTART=/tmp/qubes-installer/conf/travis-iso-unsigned2.ks USE_QUBES_REPO_VERSION=4.1 USE_QUBES_REPO_TESTING=1 EXPECT_FAILURE=./scripts/expected-failure
- DIST_DOM0=fc31 INSTALLER_KICKSTART=/tmp/qubes-installer/conf/travis-iso-unknown-key.ks USE_QUBES_REPO_VERSION=4.1 USE_QUBES_REPO_TESTING=1 EXPECT_FAILURE=./scripts/expected-failure
- DIST_DOM0=fc25 INSTALLER_KICKSTART=/tmp/qubes-installer/conf/travis-iso-full.ks USE_QUBES_REPO_VERSION=4.0 RPM_BUILD_DEFINES=--nocheck
- DIST_DOM0=fc25 INSTALLER_KICKSTART=/tmp/qubes-installer/conf/travis-iso-unsigned.ks USE_QUBES_REPO_VERSION=4.0 EXPECT_FAILURE=./expected-failure
- DIST_DOM0=fc25 INSTALLER_KICKSTART=/tmp/qubes-installer/conf/travis-iso-unknown-key.ks USE_QUBES_REPO_VERSION=4.0 EXPECT_FAILURE=./expected-failure
# don't build tags which are meant for code signing only
branches:

@ -2,7 +2,6 @@
# The Qubes OS Project, http://www.qubes-os.org
#
# Copyright (C) 2011 Tomasz Sterna <tomek@xiaoka.com>
# Copyright (C) 2019 Frédéric Pierret <frederic.pierret@qubes-os.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@ -19,55 +18,21 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#
DIST ?= fc31
DIST_VER = $(subst fc,,$(DIST))
INSTALLER_DIR ?= $(PWD)
ISO_INSTALLER ?= 1
INSTALLER_KICKSTART ?= $(INSTALLER_DIR)/conf/qubes-kickstart.cfg
ISO_LIVEUSB ?= 0
LIVE_KICKSTART ?= $(INSTALLER_DIR)/conf/liveusb.ks
CREATEREPO := $(shell which createrepo_c createrepo 2>/dev/null |head -1)
PUNGI := /usr/bin/pungi-gather
PUNGI_OPTS := --arch=x86_64 --greedy=none --exclude-debug --exclude-source
LORAX := /usr/sbin/lorax
LORAX_OPTS := --product "Qubes OS" --variant "qubes" --macboot --force --rootfs-size=4
LORAX_OPTS += --dracut-arg="--xz"
LORAX_OPTS += --dracut-arg="--install /.buildstamp"
LORAX_OPTS += --dracut-arg="--no-early-microcode"
LORAX_OPTS += --dracut-arg="--no-hostonly"
LORAX_OPTS += --dracut-arg="--debug"
LORAX_OPTS += --dracut-arg="--omit plymouth"
LORAX_OPTS += --dracut-arg="--add fips livenet dmsquash-live convertfs pollcdrom qemu qemu-net"
LORAX_OPTS += --dracut-arg="--add-drivers intel_lpss intel_lpss_pci spi_pxa2xx_platform spi_pxa2xx_pci applespi apple_ib_tb"
PUNGI_OPTS := --nosource --nodebuginfo --nogreedy --all-stages
ifdef QUBES_RELEASE
ISO_VERSION := $(QUBES_RELEASE)
LORAX_OPTS += --isfinal
PUNGI_OPTS += --isfinal
else
ISO_VERSION ?= $(shell date +%Y%m%d)
ISO_VERSION := $(shell date +%Y%m%d)
endif
ISO_NAME := Qubes-$(ISO_VERSION)-x86_64
ISO_VOLID := $(shell echo $(ISO_NAME) | tr a-z A-Z | tr -s -c [:alnum:]'\n' -)
BASE_DIR := $(INSTALLER_DIR)/work/$(ISO_VERSION)/x86_64
LORAX_OPTS += --version "$(ISO_VERSION)" --release "Qubes OS $(ISO_VERSION)" --volid $(ISO_VOLID)
LORAX_OPTS += --workdir $(INSTALLER_DIR)/work/work/x86_64 --logfile $(INSTALLER_DIR)/work/logs/lorax-x86_64.log
LORAX_OPTS += --repo $(INSTALLER_DIR)/conf/dnf-lorax.repo
MKISOFS := /usr/bin/xorriso -as mkisofs
# common mkisofs flags
MKISOFS_OPTS := -v -U -J --joliet-long -R -T -m repoview -m boot.iso
# x86 boot args
MKISOFS_OPTS += -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table
# efi boot args
MKISOFS_OPTS += -eltorito-alt-boot -e images/efiboot.img -no-emul-boot
PUNGI_OPTS += --ver="$(ISO_VERSION)"
INSTALLER_KICKSTART ?= $(PWD)/conf/qubes-kickstart.cfg
LIVE_KICKSTART ?= $(PWD)/conf/liveusb.ks
help:
@echo "make iso <== \o/";\
@ -86,30 +51,15 @@ iso: iso-liveusb
endif
iso-prepare:
rm -rf && mkdir work
ln -nsf $(INSTALLER_DIR) /tmp/qubes-installer
$(CREATEREPO) -q -g ../../conf/comps-qubes.xml --update yum/qubes-dom0
ln -nsf `pwd` /tmp/qubes-installer
createrepo -q -g ../../conf/comps-qubes.xml --update yum/qubes-dom0
iso-installer-gather:
mkdir -p $(BASE_DIR)/os/Packages
umask 022; $(PUNGI) $(PUNGI_OPTS) --config $(INSTALLER_KICKSTART) --download-to=$(BASE_DIR)/os/Packages
pushd $(BASE_DIR)/os/ && $(CREATEREPO) -q -g $(INSTALLER_DIR)/conf/comps-qubes.xml .
iso-installer-lorax:
$(INSTALLER_DIR)/scripts/ksparser --ks $(INSTALLER_KICKSTART) --extract-repo-conf-to $(INSTALLER_DIR)/conf/dnf-lorax.repo
$(LORAX) $(LORAX_OPTS) $(BASE_DIR)/os
iso-installer-mkisofs:
mkdir -p $(BASE_DIR)/iso/
chmod og+rX -R $(BASE_DIR)/os/
$(MKISOFS) $(MKISOFS_OPTS) -V $(ISO_VOLID) -o $(BASE_DIR)/iso/$(ISO_NAME).iso $(BASE_DIR)/os/
/usr/bin/isohybrid -u $(BASE_DIR)/iso/$(ISO_NAME).iso
/usr/bin/implantisomd5 $(BASE_DIR)/iso/$(ISO_NAME).iso
iso-installer: iso-prepare iso-installer-gather iso-installer-lorax iso-installer-mkisofs
iso-installer: iso-prepare
mkdir -p work
pushd work && pungi --name=Qubes $(PUNGI_OPTS) -c $(INSTALLER_KICKSTART) && popd
# Move result files to known-named directories
mkdir -p build/ISO/qubes-x86_64/iso
mv $(BASE_DIR)/iso/$(ISO_NAME).iso build/ISO/qubes-x86_64/iso/
mv work/$(ISO_VERSION)/x86_64/iso/*-DVD*.iso build/ISO/qubes-x86_64/iso/Qubes-$(ISO_VERSION)-x86_64.iso
echo $(ISO_VERSION) > build/ISO/qubes-x86_64/iso/build_latest
rm -rf build/work
mv work build/work
@ -117,7 +67,8 @@ iso-installer: iso-prepare iso-installer-gather iso-installer-lorax iso-installe
rm -rf work
iso-liveusb: $(LIVE_KICKSTART) iso-prepare
pushd work && $(INSTALLER_DIR)/scripts/livecd-creator-qubes --debug --product='Qubes OS' --title="Qubes OS $(ISO_VERSION)" --fslabel="Qubes-$(ISO_VERSION)-x86_64-LIVE" --config $(LIVE_KICKSTART) && popd
mkdir -p work
pushd work && ../livecd-creator-qubes --debug --product='Qubes OS' --title="Qubes OS $(ISO_VERSION)" --fslabel="Qubes-$(ISO_VERSION)-x86_64-LIVE" --config $(LIVE_KICKSTART) && popd
# Move result files to known-named directories
mkdir -p build/ISO/qubes-x86_64/iso build/work
mv work/*.iso build/ISO/qubes-x86_64/iso/
@ -131,16 +82,10 @@ clean-repos:
clean:
sudo rm -fr build/*
get-sources:
git submodule update --init --recursive
ifeq ($(ISO_LIVEUSB),1)
get-sources:
$(MAKE) -C livecd-tools get-sources
verify-sources:
$(MAKE) -C livecd-tools verify-sources
else
verify-sources:
@true
endif

@ -1,3 +1,14 @@
RPM_SPEC_FILES.dom0 := \
pykickstart/pykickstart.spec \
blivet/python-blivet.spec \
lorax/lorax.spec \
lorax-templates-qubes/lorax-templates-qubes.spec \
pungi/pungi.spec \
anaconda/anaconda.spec \
qubes-anaconda-addon/qubes-anaconda-addon.spec \
qubes-release/qubes-release.spec \
qubes-release/qubes-dom0-dist-upgrade.spec
ifeq ($(ISO_LIVEUSB),1)
RPM_SPEC_FILES.dom0 += \
livecd-tools/livecd-tools.spec \

@ -0,0 +1,112 @@
From aef23d6edb86739638cdaf08e7892683681392b1 Mon Sep 17 00:00:00 2001
From: Tomasz Sterna <tomek@xiaoka.com>
Date: Fri, 19 Oct 2018 08:02:11 +0200
Subject: [PATCH] anaconda: add Qubes installclass
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/installclasses/qubes.py | 93 ++++++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
create mode 100644 pyanaconda/installclasses/qubes.py
diff --git a/pyanaconda/installclasses/qubes.py b/pyanaconda/installclasses/qubes.py
new file mode 100644
index 000000000..e98912b63
--- /dev/null
+++ b/pyanaconda/installclasses/qubes.py
@@ -0,0 +1,89 @@
+#
+# qubes.py
+#
+# Copyright (C) 2011 Invisible Things Lab All rights reserved.
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+
+from pyanaconda.installclass import BaseInstallClass
+from pyanaconda.constants import *
+from pyanaconda.product import *
+from pyanaconda import network
+from pyanaconda.i18n import N_
+import os, types
+import blivet.platform
+
+from blivet.size import Size
+from blivet.platform import platform
+from decimal import Decimal
+
+class InstallClass(BaseInstallClass):
+ # name has underscore used for mnemonics, strip if you dont need it
+ id = "qubes"
+ name = N_("Qubes")
+ _description = N_("The default installation of %s is a minimal install. "
+ "You can optionally select a different set of software "
+ "now.")
+ _descriptionFields = (productName,)
+ sortPriority = 20000
+ hidden = 0
+ efi_dir = 'qubes'
+ _l10n_domain = "anaconda"
+ installUpdates = False
+
+ bootloaderTimeoutDefault = 5
+
+ tasks = [(N_("Minimal"), ["base", "base-x", "kde-desktop-qubes", "qubes" ]) ]
+
+ help_placeholder = "QubesPlaceholder.html"
+ help_placeholder_with_links = "QubesPlaceholderWithLinks.html"
+
+ def getPackagePaths(self, uri):
+ if not type(uri) == types.ListType:
+ uri = [uri,]
+
+ return {'Installation Repo': uri}
+
+ def configure(self, anaconda):
+ BaseInstallClass.configure(self, anaconda)
+ self.setDefaultPartitioning(anaconda.storage)
+
+ def setDefaultPartitioning(self, storage):
+ BaseInstallClass.setDefaultPartitioning(self,
+ storage)
+ for autoreq in list(storage.autopart_requests):
+ if autoreq.mountpoint == "/":
+ autoreq.max_size=None
+ autoreq.required_space=Size("10GiB")
+ if autoreq.mountpoint == "/home":
+ storage.autopart_requests.remove(autoreq)
+ if autoreq.mountpoint == "/boot/efi":
+ autoreq.max_size=Size("500MiB")
+
+ def productMatches(self, oldprod):
+ if oldprod is None:
+ return False
+
+ if oldprod.startswith(productName):
+ return True
+
+ return False
+
+ def versionMatches(self, oldver):
+ return True
+
+ def __init__(self):
+ BaseInstallClass.__init__(self)
--
2.14.4

@ -0,0 +1,89 @@
From 0cb13168feb3dfd4b9510c89ed3bc005a23795ca Mon Sep 17 00:00:00 2001
From: Tomasz Sterna <tomek@xiaoka.com>
Date: Fri, 19 Oct 2018 08:02:11 +0200
Subject: [PATCH] anaconda: add Qubes post-scripts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
data/post-scripts/40-qubes-alt-kernels.ks | 20 ++++++++++++++++++++
data/post-scripts/50-qubes.ks | 5 +++++
data/post-scripts/60-systemd-preset.ks | 13 +++++++++++++
data/post-scripts/Makefile.am | 2 +-
4 files changed, 39 insertions(+), 1 deletion(-)
create mode 100644 data/post-scripts/40-qubes-alt-kernels.ks
create mode 100644 data/post-scripts/50-qubes.ks
create mode 100644 data/post-scripts/60-systemd-preset.ks
diff --git a/data/post-scripts/40-qubes-alt-kernels.ks b/data/post-scripts/40-qubes-alt-kernels.ks
new file mode 100644
index 000000000..4909a99ee
--- /dev/null
+++ b/data/post-scripts/40-qubes-alt-kernels.ks
@@ -0,0 +1,20 @@
+%post --nochroot
+
+for pkg in /run/install/repo/extrakernels/*.rpm; do
+ name=`basename $pkg .rpm`
+ rpm --root=$ANA_INSTALL_PATH -q $name > /dev/null || rpm --root=$ANA_INSTALL_PATH -i --oldpackage $pkg
+done
+
+# Set grub default to the current kernel if running not the latest one
+latest=`basename /run/install/repo/Packages/k/kernel-[0-9]*.rpm .rpm|cut -d- -f2-`
+if [ "$latest" != "`uname -r`" ]; then
+ rootdev=`grep " $ANA_INSTALL_PATH " /proc/mounts | cut -f 1 -d ' '`
+ sysid=`blkid -o value -s UUID $rootdev`
+ xenver=`dmesg | grep 'Xen version:' | sed -e 's/.*version: \([0-9.]\+\).*/\1/'`
+ grubid="gnulinux-advanced-$sysid"
+ grubid="$grubid>xen-hypervisor-$xenver-$sysid"
+ grubid="$grubid>xen-gnulinux-`uname -r`-advanced-$sysid"
+ grub2-set-default --boot-directory=$ANA_INSTALL_PATH/boot "$grubid"
+fi
+
+%end
diff --git a/data/post-scripts/50-qubes.ks b/data/post-scripts/50-qubes.ks
new file mode 100644
index 000000000..1b9238b40
--- /dev/null
+++ b/data/post-scripts/50-qubes.ks
@@ -0,0 +1,5 @@
+%post
+
+rpm --import /etc/pki/rpm-gpg/*
+
+%end
diff --git a/data/post-scripts/60-systemd-preset.ks b/data/post-scripts/60-systemd-preset.ks
new file mode 100644
index 000000000..9e6cb3f3a
--- /dev/null
+++ b/data/post-scripts/60-systemd-preset.ks
@@ -0,0 +1,13 @@
+%post
+
+# preset all services, to not worry about package installation order (preset
+# files vs services)
+systemctl preset-all
+
+systemctl enable initial-setup.service
+
+# systemctl preset-all disables default target
+# (https://bugzilla.redhat.com/1316387), re-enable it manually
+systemctl set-default graphical.target
+
+%end
diff --git a/data/post-scripts/Makefile.am b/data/post-scripts/Makefile.am
index 7d78d4bc3..ad2f6497d 100644
--- a/data/post-scripts/Makefile.am
+++ b/data/post-scripts/Makefile.am
@@ -16,5 +16,5 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
postscriptsdir = $(datadir)/$(PACKAGE_NAME)/post-scripts
-dist_postscripts_DATA = 80-setfilecons.ks 90-copy-screenshots.ks 99-copy-logs.ks
+dist_postscripts_DATA = 40-qubes-alt-kernels.ks 50-qubes.ks 60-systemd-preset.ks 80-setfilecons.ks 90-copy-screenshots.ks 99-copy-logs.ks
MAINTAINERCLEANFILES = Makefile.in
--
2.14.4

@ -0,0 +1,154 @@
From 5ccbe4b9f6265ac4e07f0539da39db809fc8020a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Pierret=20=28fepitre=29?=
<frederic.epitre@orange.fr>
Date: Fri, 19 Oct 2018 08:02:11 +0200
Subject: [PATCH] anaconda: remove other installclasses
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/installclasses/fedora.py | 58 ---------------------------------
pyanaconda/installclasses/rhel.py | 64 -------------------------------------
2 files changed, 122 deletions(-)
delete mode 100644 pyanaconda/installclasses/fedora.py
delete mode 100644 pyanaconda/installclasses/rhel.py
diff --git a/pyanaconda/installclasses/fedora.py b/pyanaconda/installclasses/fedora.py
deleted file mode 100644
index c9ced65fd..000000000
--- a/pyanaconda/installclasses/fedora.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# fedora.py
-#
-# Copyright (C) 2007 Red Hat, Inc. All rights reserved.
-#
-# 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; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-
-from pyanaconda.installclass import BaseInstallClass
-from pyanaconda.product import productName
-from pyanaconda import network
-from pyanaconda import nm
-
-class FedoraBaseInstallClass(BaseInstallClass):
- name = "Fedora"
- sortPriority = 10000
- if productName.startswith("Red Hat "): # pylint: disable=no-member
- hidden = True
-
- _l10n_domain = "anaconda"
-
- efi_dir = "fedora"
-
- help_placeholder = "FedoraPlaceholder.html"
- help_placeholder_with_links = "FedoraPlaceholderWithLinks.html"
-
- def configure(self, anaconda):
- BaseInstallClass.configure(self, anaconda)
- BaseInstallClass.setDefaultPartitioning(self, anaconda.storage)
-
- def setNetworkOnbootDefault(self, ksdata):
- if any(nd.onboot for nd in ksdata.network.network if nd.device):
- return
- # choose first wired device having link
- for dev in nm.nm_devices():
- if nm.nm_device_type_is_wifi(dev):
- continue
- try:
- link_up = nm.nm_device_carrier(dev)
- except (nm.UnknownDeviceError, nm.PropertyNotFoundError):
- continue
- if link_up:
- network.update_onboot_value(dev, True, ksdata=ksdata)
- break
-
- def __init__(self):
- BaseInstallClass.__init__(self)
diff --git a/pyanaconda/installclasses/rhel.py b/pyanaconda/installclasses/rhel.py
deleted file mode 100644
index 7e907e4bd..000000000
--- a/pyanaconda/installclasses/rhel.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# rhel.py
-#
-# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
-#
-# 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; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-
-from pyanaconda.installclass import BaseInstallClass
-from pyanaconda.product import productName
-from pyanaconda import network
-from pyanaconda import nm
-
-class RHELBaseInstallClass(BaseInstallClass):
- name = "Red Hat Enterprise Linux"
- sortPriority = 10000
- if not productName.startswith("Red Hat "): # pylint: disable=no-member
- hidden = True
- defaultFS = "xfs"
-
- bootloaderTimeoutDefault = 5
-
- ignoredPackages = ["ntfsprogs"]
-
- installUpdates = False
-
- _l10n_domain = "comps"
-
- efi_dir = "redhat"
-
- help_placeholder = "RHEL7Placeholder.html"
- help_placeholder_with_links = "RHEL7PlaceholderWithLinks.html"
-
- def configure(self, anaconda):
- BaseInstallClass.configure(self, anaconda)
- BaseInstallClass.setDefaultPartitioning(self, anaconda.storage)
-
- def setNetworkOnbootDefault(self, ksdata):
- if any(nd.onboot for nd in ksdata.network.network if nd.device):
- return
- # choose the device used during installation
- # (ie for majority of cases the one having the default route)
- dev = network.default_route_device() \
- or network.default_route_device(family="inet6")
- if not dev:
- return
- # ignore wireless (its ifcfgs would need to be handled differently)
- if nm.nm_device_type_is_wifi(dev):
- return
- network.update_onboot_value(dev, True, ksdata=ksdata)
-
- def __init__(self):
- BaseInstallClass.__init__(self)
--
2.14.4

@ -0,0 +1,387 @@
From 9eb4146449147e8aaccc386823c8d805c276bd17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Sat, 20 Oct 2018 11:23:40 +0200
Subject: [PATCH] anaconda: remove network setup from text interface
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We have network disabled.
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/tui/spokes/network.py | 361 ------------------------------------
1 file changed, 361 deletions(-)
delete mode 100644 pyanaconda/ui/tui/spokes/network.py
diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py
deleted file mode 100644
index 56ab1173b..000000000
--- a/pyanaconda/ui/tui/spokes/network.py
+++ /dev/null
@@ -1,361 +0,0 @@
-# Network configuration spoke classes
-#
-# Copyright (C) 2013 Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details. You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-
-
-from pyanaconda.flags import can_touch_runtime_system, flags
-from pyanaconda.ui.categories.system import SystemCategory
-from pyanaconda.ui.tui.spokes import EditTUISpoke, OneShotEditTUIDialog
-from pyanaconda.ui.tui.spokes import EditTUISpokeEntry as Entry
-from pyanaconda.ui.tui.simpleline import TextWidget, ColumnWidget
-from pyanaconda.ui.common import FirstbootSpokeMixIn
-from pyanaconda.i18n import N_, _
-from pyanaconda import network
-from pyanaconda import nm
-
-from pyanaconda.regexes import IPV4_PATTERN_WITHOUT_ANCHORS, IPV4_NETMASK_WITHOUT_ANCHORS
-from pyanaconda.constants_text import INPUT_PROCESSED
-from pyanaconda.constants import ANACONDA_ENVIRON
-
-import logging
-log = logging.getLogger("anaconda")
-
-import re
-
-__all__ = ["NetworkSpoke"]
-
-
-class NetworkSpoke(FirstbootSpokeMixIn, EditTUISpoke):
- """ Spoke used to configure network settings.
-
- .. inheritance-diagram:: NetworkSpoke
- :parts: 3
- """
- title = N_("Network configuration")
- category = SystemCategory
-
- def __init__(self, app, data, storage, payload, instclass):
- EditTUISpoke.__init__(self, app, data, storage, payload, instclass)
- self.hostname_dialog = OneShotEditTUIDialog(app, data, storage, payload, instclass)
- self.hostname_dialog.value = self.data.network.hostname
- self.supported_devices = []
- self.errors = []
- self._apply = False
-
- def initialize(self):
- self._load_new_devices()
-
- EditTUISpoke.initialize(self)
- if not self.data.network.seen:
- self._update_network_data()
-
- def _load_new_devices(self):
- devices = nm.nm_devices()
- intf_dumped = network.dumpMissingDefaultIfcfgs()
- if intf_dumped:
- log.debug("Dumped interfaces: %s", intf_dumped)
-
- for name in devices:
- if name in self.supported_devices:
- continue
- if network.is_ibft_configured_device(name):
- continue
- if nm.nm_device_type_is_ethernet(name):
- # ignore slaves
- if nm.nm_device_setting_value(name, "connection", "slave-type"):
- continue
- self.supported_devices.append(name)
-
- @property
- def completed(self):
- """ Check whether this spoke is complete or not. Do an additional
- check if we're installing from CD/DVD, since a network connection
- should not be required in this case.
- """
- return (not can_touch_runtime_system("require network connection")
- or nm.nm_activated_devices())
-
- @property
- def mandatory(self):
- # the network spoke should be mandatory only if it is running
- # during the installation and if the installation source requires network
- return ANACONDA_ENVIRON in flags.environs and self.payload.needsNetwork
-
- @property
- def status(self):
- """ Short msg telling what devices are active. """
- return network.status_message()
-
- def _summary_text(self):
- """Devices cofiguration shown to user."""
- msg = ""
- activated_devs = nm.nm_activated_devices()
- for name in self.supported_devices:
- if name in activated_devs:
- msg += self._activated_device_msg(name)
- else:
- msg += _("Wired (%(interface_name)s) disconnected\n") \
- % {"interface_name": name}
- return msg
-
- def _activated_device_msg(self, devname):
- msg = _("Wired (%(interface_name)s) connected\n") \
- % {"interface_name": devname}
-
- ipv4config = nm.nm_device_ip_config(devname, version=4)
- ipv6config = nm.nm_device_ip_config(devname, version=6)
-
- if ipv4config and ipv4config[0]:
- addr_str, prefix, gateway_str = ipv4config[0][0]
- netmask_str = network.prefix2netmask(prefix)
- dnss_str = ",".join(ipv4config[1])
- else:
- addr_str = dnss_str = gateway_str = netmask_str = ""
- msg += _(" IPv4 Address: %(addr)s Netmask: %(netmask)s Gateway: %(gateway)s\n") % \
- {"addr": addr_str, "netmask": netmask_str, "gateway": gateway_str}
- msg += _(" DNS: %s\n") % dnss_str
-
- if ipv6config and ipv6config[0]:
- for ipv6addr in ipv6config[0]:
- addr_str, prefix, gateway_str = ipv6addr
- # Do not display link-local addresses
- if not addr_str.startswith("fe80:"):
- msg += _(" IPv6 Address: %(addr)s/%(prefix)d\n") % \
- {"addr": addr_str, "prefix": prefix}
-
- dnss_str = ",".join(ipv6config[1])
-
- return msg
-
- def refresh(self, args=None):
- """ Refresh screen. """
- self._load_new_devices()
- EditTUISpoke.refresh(self, args)
-
- summary = self._summary_text()
- self._window += [TextWidget(summary), ""]
- hostname = _("Host Name: %s\n") % self.data.network.hostname
- self._window += [TextWidget(hostname), ""]
- current_hostname = _("Current host name: %s\n") % network.current_hostname()
- self._window += [TextWidget(current_hostname), ""]
-
- # if we have any errors, display them
- while len(self.errors) > 0:
- self._window += [TextWidget(self.errors.pop()), ""]
-
- def _prep(i, w):
- """ Mangle our text to make it look pretty on screen. """
- number = TextWidget("%2d)" % (i + 1))
- return ColumnWidget([(4, [number]), (None, [w])], 1)
-
- _opts = [_("Set host name")]
- for devname in self.supported_devices:
- _opts.append(_("Configure device %s") % devname)
- text = [TextWidget(o) for o in _opts]
-
- # make everything presentable on screen
- choices = [_prep(i, w) for i, w in enumerate(text)]
- displayed = ColumnWidget([(78, choices)], 1)
- self._window.append(displayed)
-
- return True
-
- def input(self, args, key):
- """ Handle the input. """
- try:
- num = int(key)
- except ValueError:
- return key
-
- if num == 1:
- # set hostname
- self.app.switch_screen_modal(self.hostname_dialog, Entry(_("Host Name"),
- "hostname", re.compile(".*$"), True))
- self.apply()
- return INPUT_PROCESSED
- elif 2 <= num <= len(self.supported_devices) + 1:
- # configure device
- devname = self.supported_devices[num-2]
- ndata = network.ksdata_from_ifcfg(devname)
- if not ndata:
- try:
- nm.nm_device_setting_value(devname, "connection", "uuid")
- except nm.SettingsNotFoundError:
- pass
- else:
- log.debug("network: dumping ifcfg file for in-memory connection %s", devname)
- nm.nm_update_settings_of_device(devname, [['connection', 'id', devname, None]])
- ndata = network.ksdata_from_ifcfg(devname)
-
- if not ndata:
- log.debug("network: can't find any connection for %s", devname)
- self.errors.append(_("Configuration of device not found"))
- return INPUT_PROCESSED
-
- newspoke = ConfigureNetworkSpoke(self.app, self.data, self.storage,
- self.payload, self.instclass, ndata)
- self.app.switch_screen_modal(newspoke)
-
- if ndata.ip == "dhcp":
- ndata.bootProto = "dhcp"
- ndata.ip = ""
- else:
- ndata.bootProto = "static"
- if not ndata.netmask:
- self.errors.append(_("Configuration not saved: netmask missing in static configuration"))
- return INPUT_PROCESSED
-
- if ndata.ipv6 == "ignore":
- ndata.noipv6 = True
- ndata.ipv6 = ""
- else:
- ndata.noipv6 = False
-
- network.update_settings_with_ksdata(devname, ndata)
- network.update_onboot_value(devname, ndata.onboot, ksdata=None, root_path="")
-
- if ndata._apply:
- self._apply = True
- uuid = nm.nm_device_setting_value(devname, "connection", "uuid")
- try:
- nm.nm_activate_device_connection(devname, uuid)
- except (nm.UnmanagedDeviceError, nm.UnknownConnectionError):
- self.errors.append(_("Can't apply configuration, device activation failed."))
-
- self.apply()
- return INPUT_PROCESSED
- else:
- return key
-
- def apply(self):
- """Apply all of our settings."""
- self._update_network_data()
- log.debug("network: apply ksdata %s", self.data.network)
-
- if self._apply:
- self._apply = False
- if ANACONDA_ENVIRON in flags.environs:
- from pyanaconda.packaging import payloadMgr
- payloadMgr.restartThread(self.storage, self.data, self.payload,
- self.instclass, checkmount=False)
-
- def _update_network_data(self):
- hostname = self.data.network.hostname
-
- self.data.network.network = []
- for i, name in enumerate(nm.nm_devices()):
- if network.is_ibft_configured_device(name):
- continue
- nd = network.ksdata_from_ifcfg(name)
- if not nd:
- continue
- if name in nm.nm_activated_devices():
- nd.activate = True
- else:
- # First network command defaults to --activate so we must
- # use --no-activate explicitly to prevent the default
- if i == 0:
- nd.activate = False
- self.data.network.network.append(nd)
-
- (valid, error) = network.sanityCheckHostname(self.hostname_dialog.value)
- if valid:
- hostname = self.hostname_dialog.value
- else:
- self.errors.append(_("Host name is not valid: %s") % error)
- self.hostname_dialog.value = hostname
- network.update_hostname_data(self.data, hostname)
-
-def check_ipv6_config(value):
- if value in ["auto", "dhcp", "ignore"]:
- return (True, None)
- addr, _slash, prefix = value.partition("/")
- if prefix:
- try:
- if not 1 <= int(prefix) <= 128:
- return (False, None)
- except ValueError:
- return (False, None)
- return check_ipv6_address(addr)
-
-def check_ipv6_address(value):
- return (network.check_ip_address(value, version=6), None)
-
-def check_nameservers(value):
- addresses = [str.strip(i) for i in value.split(",")]
- if not addresses:
- return (False, None)
-
- for ip in addresses:
- if not network.check_ip_address(ip):
- return (False, None)
- return (True, None)
-
-class ConfigureNetworkSpoke(EditTUISpoke):
- """ Spoke to set various configuration options for net devices. """
- title = N_("Device configuration")
- category = "network"
-
- edit_fields = [
- Entry(N_('IPv4 address or %s for DHCP') % '"dhcp"', "ip",
- re.compile("^(?:" + IPV4_PATTERN_WITHOUT_ANCHORS + "|dhcp)$"), True),
- Entry(N_("IPv4 netmask"), "netmask", re.compile("^" + IPV4_NETMASK_WITHOUT_ANCHORS + "$"), True),
- Entry(N_("IPv4 gateway"), "gateway", re.compile("^" + IPV4_PATTERN_WITHOUT_ANCHORS + "$"), True),
- Entry(N_('IPv6 address[/prefix] or %(auto)s for automatic, %(dhcp)s for DHCP, %(ignore)s to turn off')
- % {"auto": '"auto"', "dhcp": '"dhcp"', "ignore": '"ignore"'}, "ipv6",
- check_ipv6_config, True),
- Entry(N_("IPv6 default gateway"), "ipv6gateway", check_ipv6_address, True),
- Entry(N_("Nameservers (comma separated)"), "nameserver", check_nameservers, True),
- Entry(N_("Connect automatically after reboot"), "onboot", EditTUISpoke.CHECK, True),
- Entry(N_("Apply configuration in installer"), "_apply", EditTUISpoke.CHECK, True),
- ]
-
- def __init__(self, app, data, storage, payload, instclass, ndata):
- EditTUISpoke.__init__(self, app, data, storage, payload, instclass)
- self.args = ndata
- if self.args.bootProto == "dhcp":
- self.args.ip = "dhcp"
- if self.args.noipv6:
- self.args.ipv6 = "ignore"
- self.args._apply = False
-
- def refresh(self, args=None):
- """ Refresh window. """
- EditTUISpoke.refresh(self, args)
- message = _("Configuring device %s.") % self.args.device
- self._window += [TextWidget(message), ""]
- return True
-
- def input(self, args, key):
- self.dialog.wrong_input_message = _("Bad format of the IP address")
- try:
- field = self.visible_fields[int(key)-1]
- except (ValueError, IndexError):
- pass
- else:
- if field.attribute == "netmask":
- self.dialog.wrong_input_message = _("Bad format of the netmask")
- return EditTUISpoke.input(self, args, key)
-
- @property
- def indirect(self):
- return True
-
- def apply(self):
- """ Apply our changes. """
- # this is done at upper level by updating ifcfg file
--
2.14.4

@ -0,0 +1,30 @@
From 383217cc20f6da8030e98891e34cccd7b03d40c0 Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:11 +0200
Subject: [PATCH] anaconda: fix grub config setup by removing non-xen options
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index a37f91b9a..68fca98bf 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1558,6 +1558,9 @@ class GRUB2(GRUB):
except (BootLoaderError, OSError, RuntimeError) as e:
log.error("boot loader password setup failed: %s", e)
+ # disable non-xen entries
+ os.chmod("%s/etc/grub.d/10_linux" % iutil.getSysroot(), 0o644)
+
# make sure the default entry is the OS we are installing
if self.default is not None:
# find the index of the default image
--
2.14.4

@ -0,0 +1,32 @@
From 2cdfe3b92b5997d03f22521a2d4edb1d42ea443f Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:11 +0200
Subject: [PATCH] anaconda: make encrypted partitions by default
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/kickstart.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index dc58d9b65..7d67bf1a6 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -252,6 +252,11 @@ class Authconfig(commands.authconfig.FC3_Authconfig):
log.error("Error running %s %s: %s", cmd, args, msg)
class AutoPart(commands.autopart.F21_AutoPart):
+ def __init__(self, writePriority=100, *args, **kwargs):
+ if 'encrypted' not in kwargs:
+ kwargs['encrypted'] = True
+ super(AutoPart, self).__init__(writePriority=writePriority, *args, **kwargs)
+
def parse(self, args):
retval = commands.autopart.F21_AutoPart.parse(self, args)
--
2.14.4

@ -0,0 +1,39 @@
From 0bfebcf148078e9d43cfabd13ceb92ffad6274d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:11 +0200
Subject: [PATCH] anaconda: set default grub theme
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 68fca98bf..b6488c5fd 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1401,7 +1401,7 @@ class GRUB2(GRUB):
_config_file = "grub.cfg"
_config_dir = "grub2"
defaults_file = "/etc/default/grub"
- terminal_type = "console"
+ terminal_type = "gfxterm"
stage2_max_end = None
# requirements for boot devices
@@ -1503,7 +1503,7 @@ class GRUB2(GRUB):
log.info("bootloader.py: used boot args: %s ", self.boot_args)
defaults.write("GRUB_CMDLINE_LINUX=\"%s\"\n" % self.boot_args)
defaults.write("GRUB_DISABLE_RECOVERY=\"true\"\n")
- #defaults.write("GRUB_THEME=\"/boot/grub2/themes/system/theme.txt\"\n")
+ defaults.write("GRUB_THEME=\"/boot/grub2/themes/system/theme.txt\"\n")
defaults.close()
def _encrypt_password(self):
--
2.14.4

@ -0,0 +1,30 @@
From 4efdab482cd1b73f58abf4f6cf16be4965ab49ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Pierret=20=28fepitre=29?=
<frederic.epitre@orange.fr>
Date: Fri, 19 Oct 2018 08:02:11 +0200
Subject: [PATCH] anaconda: add options can_dual_boot and can_update to grub
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index b6488c5fd..083b99f1a 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1403,6 +1403,8 @@ class GRUB2(GRUB):
defaults_file = "/etc/default/grub"
terminal_type = "gfxterm"
stage2_max_end = None
+ can_dual_boot = True
+ can_update = True
# requirements for boot devices
stage2_device_types = ["partition", "mdarray", "lvmlv"]
--
2.14.4

@ -0,0 +1,31 @@
From b0d781737479e11c4b138ef6df4d372d8fbd2503 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Pierret=20=28fepitre=29?=
<frederic.epitre@orange.fr>
Date: Fri, 19 Oct 2018 08:02:11 +0200
Subject: [PATCH] anaconda: efimgr specify root=iutil.getSysroot()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 083b99f1a..acdfb8322 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1743,7 +1743,8 @@ class EFIBase(object):
log.warning("failed to parse efi boot slot (%s)", slot)
continue
- rc = self.efibootmgr("-b", slot_id, "-B")
+ rc = self.efibootmgr("-b", slot_id, "-B",
+ root=iutil.getSysroot())
if rc:
raise BootLoaderError("failed to remove old efi boot entry. This is most likely a kernel or firmware bug.")
--
2.14.4

@ -0,0 +1,121 @@
From f53f5fdcaf10bdd2f64bd144b78052561ae15aa6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: generate xen efi configuration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 78 insertions(+), 1 deletion(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index acdfb8322..908020ad0 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -21,6 +21,7 @@
import collections
import os
import re
+import shutil
import blivet
from parted import PARTITION_BIOS_GRUB
from glob import glob
@@ -1828,6 +1829,82 @@ class EFIGRUB(EFIBase, GRUB2):
class Aarch64EFIGRUB(EFIGRUB):
_serial_consoles = ["ttyAMA", "ttyS"]
+class XenEFI(EFIGRUB):
+ packages = ["efibootmgr"]
+ _config_file = 'xen.cfg'
+
+ # stage2 not used at all, so allow any type
+ stage2_device_types = ["partition", "mdarray", "lvmlv"]
+
+ def __init__(self):
+ super(XenEFI, self).__init__()
+ self.efi_dir = 'qubes'
+
+ def add_efi_boot_target(self):
+ if self.stage1_device.type == "partition":
+ boot_disk = self.stage1_device.disk
+ boot_part_num = self.stage1_device.parted_partition.number
+ elif self.stage1_device.type == "mdarray":
+ # FIXME: I'm just guessing here. This probably needs the full
+ # treatment, ie: multiple targets for each member.
+ boot_disk = self.stage1_device.parents[0].disk
+ boot_part_num = self.stage1_device.parents[0].parted_partition.number
+ boot_part_num = str(boot_part_num)
+
+ if not os.path.exists(
+ "{}/{}".format(iutil.getSysroot() + self.config_dir, "xen.efi")):
+ xen_efi = [x for x in os.listdir(iutil.getSysroot() + self.config_dir) if
+ x.startswith('xen-') and x.endswith('.efi')][0]
+ shutil.copy("{}/{}".format(iutil.getSysroot() + self.config_dir, xen_efi),
+ "{}/{}".format(iutil.getSysroot() + self.config_dir, "xen.efi"))
+ rc = self.efibootmgr("-c", "-w", "-L", productName,
+ "-d", boot_disk.path, "-p", boot_part_num,
+ "-l",
+ self.efi_dir_as_efifs_dir + "\\xen.efi",
+ root=iutil.getSysroot())
+ if rc:
+ raise BootLoaderError("failed to set new efi boot target")
+
+ def add_image(self, image):
+ super(XenEFI, self).add_image(image)
+ shutil.copy("{}/boot/{}".format(iutil.getSysroot(), image.kernel),
+ os.path.normpath(
+ "{}/{}".format(iutil.getSysroot() + self.config_dir,
+ image.kernel)))
+ if image.initrd is not None:
+ shutil.copy("{}/boot/{}".format(iutil.getSysroot(), image.initrd),
+ os.path.normpath(
+ "{}/{}".format(iutil.getSysroot() + self.config_dir,
+ image.initrd)))
+
+ def write_config_header(self, config):
+ config.write("[global]\n")
+ config.write("default={}\n".format(self.default.version))
+
+ def write_config_images(self, config):
+ for image in self.images:
+ config.write("\n")
+ config.write("[{}]\n".format(image.version))
+ config.write("options=loglvl=all dom0_mem=min:1024M dom0_mem=max:4096M\n")
+ config.write("kernel={} root={} {}\n".format(
+ image.kernel,
+ image.device.fstab_spec,
+ self.boot_args))
+ config.write("ramdisk={}\n".format(image.initrd))
+
+ def write_config_console(self, config):
+ pass
+
+ def write_config_post(self):
+ pass
+
+ def is_valid_stage2_device(self, device, linux=True, non_linux=False):
+ """ XenEFI doesn't use stage2 at all, so allow anything here """
+ return True
+
+ write_config = BootLoader.write_config
+
+
class MacEFIGRUB(EFIGRUB):
def mactel_config(self):
if os.path.exists(iutil.getSysroot() + "/usr/libexec/mactel-boot-setup"):
@@ -2342,7 +2419,7 @@ class EXTLINUX(BootLoader):
# every platform that wants a bootloader needs to be in this dict
bootloader_by_platform = {
platform.X86: GRUB2,
- platform.EFI: EFIGRUB,
+ platform.EFI: XenEFI,
platform.MacEFI: MacEFIGRUB,
platform.PPC: GRUB2,
platform.IPSeriesPPC: IPSeriesGRUB2,
--
2.14.4

@ -0,0 +1,65 @@
From 1c37fe7581a01b93d1f46b8eb03b37f5cb09bb0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: fix dracut module to work with reduced dependencies
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Do not fail because of not present url-lib. Also 'loop' module requires manual
loading now.
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
dracut/anaconda-diskroot | 2 ++
dracut/module-setup.sh | 2 +-
dracut/parse-anaconda-options.sh | 6 +++++-
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/dracut/anaconda-diskroot b/dracut/anaconda-diskroot
index 7e52e052b..230b20418 100755
--- a/dracut/anaconda-diskroot
+++ b/dracut/anaconda-diskroot
@@ -43,6 +43,8 @@ kickstart="$(getarg ks= inst.ks=)"
[ -e "/dev/root" ] && exit 1 # we already have a root device!
+modprobe -q loop
+
# If we're waiting for a cdrom kickstart, the user might need to swap discs.
# So if this is a CDROM drive, make a note of it, but don't mount it (yet).
# Once we get the kickstart either the udev trigger or disk-reinsertion will
diff --git a/dracut/module-setup.sh b/dracut/module-setup.sh
index 184036188..9f4e9d48c 100755
--- a/dracut/module-setup.sh
+++ b/dracut/module-setup.sh
@@ -7,7 +7,7 @@ check() {
}
depends() {
- echo livenet nfs img-lib convertfs ifcfg
+ echo img-lib dmsquash-live
case "$(uname -m)" in
s390*) echo cms ;;
esac
diff --git a/dracut/parse-anaconda-options.sh b/dracut/parse-anaconda-options.sh
index fa1455f8b..8fce64aed 100755
--- a/dracut/parse-anaconda-options.sh
+++ b/dracut/parse-anaconda-options.sh
@@ -2,7 +2,11 @@
# parse-anaconda-options.sh - parse installer-specific options
. /lib/anaconda-lib.sh
-. /lib/url-lib.sh
+if [ -r /lib/url-lib.sh ]; then
+ . /lib/url-lib.sh
+else
+ alias set_http_header=:
+fi
# create the repodir and isodir that anaconda will look for
mkdir -p $repodir $isodir
--
2.14.4

@ -0,0 +1,61 @@
From 66a87473c6360bac0f47e14fca6293cda8c15bc7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: use installer kernel parameters as default for
installed system
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This way if any kernel parameter was need to boot Qubes on particular hardware, it will also be set to installed system
Fixes QubesOS/qubes-issues#1650
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 908020ad0..963af46f9 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -229,14 +229,13 @@ class BootLoader(object):
def stage2_format_types(self):
return ["ext4", "ext3", "ext2"]
- # this is so stupid...
- global_preserve_args = ["speakup_synth", "apic", "noapic", "apm", "ide",
- "noht", "acpi", "video", "pci", "nodmraid",
- "nompath", "nomodeset", "noiswmd", "fips",
- "selinux", "biosdevname", "ipv6.disable",
- "net.ifnames"]
preserve_args = []
+ global_no_preserve_args = ["stage2", "root", "rescue",
+ "rd.live.check", "ip", "repo", "ks",
+ "rd.lvm", "rd.md", "rd.luks", "rd.dm",
+ "rd.lvm.lv"]
+
_trusted_boot = False
def __init__(self):
@@ -870,11 +869,10 @@ class BootLoader(object):
self.boot_args.add("iscsi_firmware")
#
- # preservation of some of our boot args
- # FIXME: this is stupid.
+ # preservation of most of our boot args
#
- for opt in self.global_preserve_args + self.preserve_args:
- if opt not in flags.cmdline:
+ for opt in flags.cmdline.keys():
+ if opt in self.global_no_preserve_args:
continue
arg = flags.cmdline.get(opt)
--
2.14.4

@ -0,0 +1,51 @@
From 73b928fd84acfde8a8f20ddf20241da9085b87b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: use kernel-install instead of grubby to regenerate
initrd/grub.conf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since we have own hook there, it properly handles Xen. This means we no longer need post scripts in kickstart for that.
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/packaging/__init__.py | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py
index a99fbe973..8332ce0e5 100644
--- a/pyanaconda/packaging/__init__.py
+++ b/pyanaconda/packaging/__init__.py
@@ -608,23 +608,18 @@ class Payload(object):
# prevent boot on some systems
def recreateInitrds(self):
- """ Recreate the initrds by calling new-kernel-pkg
+ """ Recreate the initrds by calling kernel-install
This needs to be done after all configuration files have been
written, since dracut depends on some of them.
:returns: None
"""
- if not os.path.exists(iutil.getSysroot() + "/usr/sbin/new-kernel-pkg"):
- log.error("new-kernel-pkg does not exist - grubby wasn't installed? skipping")
- return
-
for kernel in self.kernelVersionList:
log.info("recreating initrd for %s", kernel)
if not flags.imageInstall:
- iutil.execInSysroot("new-kernel-pkg",
- ["--mkinitrd", "--dracut",
- "--depmod", "--update", kernel])
+ iutil.execInSysroot("kernel-install",
+ ["add", kernel, "/boot/vmlinuz-%s" % kernel])
else:
# hostonly is not sensible for disk image installations
# using /dev/disk/by-uuid/ is necessary due to disk image naming
--
2.14.4

@ -0,0 +1,33 @@
From c10dd05e7957cc188b69c302e7a9b4c2c8249ce6 Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <m.v.b@runbox.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: Fix a regular expression determining Release
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Without the start-of-line matcher, other lines are matched as well, causing invalid PACKAGE_RELEASE variable substitutions within the Makefiles.
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
configure.ac | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index df1d206b3..b36cf53ec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,7 +97,9 @@ SHUT_UP_GCC="-Wno-unused-result"
# Add remaining compiler flags we want to use
CFLAGS="$CFLAGS -Wall -Werror $SHUT_UP_GCC"
-AC_SUBST(PACKAGE_RELEASE, [1])
+# Get the release number from the spec file
+rel="`awk '/^Release:/ { split($2, r, "%"); print r[[1]] }' $srcdir/anaconda.spec`"
+AC_SUBST(PACKAGE_RELEASE, [$rel])
# Perform arch related tests
AC_CANONICAL_BUILD
--
2.14.4

@ -0,0 +1,38 @@
From 40992b40f344685a755f39813f0f2afd9f56e7b6 Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <m.v.b@runbox.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: Do not fail during initramfs start-up due to
missing url-lib
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
dracut/anaconda-ks-sendheaders.sh | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/dracut/anaconda-ks-sendheaders.sh b/dracut/anaconda-ks-sendheaders.sh
index 7bc97393b..39fa0ce0d 100755
--- a/dracut/anaconda-ks-sendheaders.sh
+++ b/dracut/anaconda-ks-sendheaders.sh
@@ -2,7 +2,15 @@
# anaconda-ks-sendheaders.sh - set various HTTP headers for kickstarting
[ -f /tmp/.ks_sendheaders ] && return
-command -v set_http_header >/dev/null || . /lib/url-lib.sh
+
+if ! command -v set_http_header >/dev/null; then
+ if ! [ -r /lib/url-lib.sh ]; then
+ alias set_http_header=:
+ return
+ fi
+
+ . /lib/url-lib.sh
+fi
# inst.ks.sendmac: send MAC addresses in HTTP headers
if getargbool 0 kssendmac inst.ks.sendmac; then
--
2.14.4

@ -0,0 +1,733 @@
From dc6d56efd644de06468ddd225c436bd3610a6527 Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <m.v.b@runbox.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: Disable the NTP configuration spoke
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/datetime_spoke.glade | 300 +----------------------
pyanaconda/ui/gui/spokes/datetime_spoke.py | 332 --------------------------
2 files changed, 2 insertions(+), 630 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/datetime_spoke.glade b/pyanaconda/ui/gui/spokes/datetime_spoke.glade
index 9179640fe..fab5ad067 100644
--- a/pyanaconda/ui/gui/spokes/datetime_spoke.glade
+++ b/pyanaconda/ui/gui/spokes/datetime_spoke.glade
@@ -1,14 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.18.3 -->
+<!-- Generated with glade 3.19.0 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<requires lib="AnacondaWidgets" version="1.0"/>
<requires lib="TimezoneMap" version="0.4"/>
- <object class="GtkImage" id="addImage">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">list-add-symbolic</property>
- </object>
<object class="GtkListStore" id="cities">
<columns>
<!-- column-name name -->
@@ -26,11 +21,6 @@
<property name="inline_completion">True</property>
<signal name="match-selected" handler="on_completion_match_selected" object="cityCombobox" swapped="no"/>
</object>
- <object class="GtkImage" id="configImage">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">system-run-symbolic</property>
- </object>
<object class="GtkListStore" id="days">
<columns>
<!-- column-name idx -->
@@ -91,221 +81,6 @@
<column type="gboolean"/>
</columns>
</object>
- <object class="GtkDialog" id="ntpConfigDialog">
- <property name="can_focus">False</property>
- <property name="border_width">6</property>
- <property name="type_hint">dialog</property>
- <property name="decorated">False</property>
- <child internal-child="vbox">
- <object class="GtkBox" id="dialog-vbox1">
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child internal-child="action_area">
- <object class="GtkButtonBox" id="dialog-action_area1">
- <property name="can_focus">False</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="cancelButton">
- <property name="label" translatable="yes" context="GUI|Date and Time|NTP">_Cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="okButton">
- <property name="label" translatable="yes" context="GUI|Date and Time|NTP">_OK</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="configHeadingLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Add and mark for usage NTP servers</property>
- <attributes>
- <attribute name="font-desc" value="Sans Bold 12"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="box3">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkEntry" id="serverEntry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <signal name="activate" handler="on_entry_activated" swapped="no"/>
- <child internal-child="accessible">
- <object class="AtkObject" id="serverEntry-atkobject">
- <property name="AtkObject::accessible-name" translatable="yes">New NTP Server</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="addButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">addImage</property>
- <signal name="clicked" handler="on_add_clicked" swapped="no"/>
- <child internal-child="accessible">
- <object class="AtkObject" id="addButton-atkobject">
- <property name="AtkObject::accessible-name" translatable="yes">Add NTP Server</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="padding">4</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="poolCheckButton">
- <property name="label" translatable="yes">This URL refers to a pool of NTP servers</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolledWindow">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="shadow_type">in</property>
- <child>
- <object class="GtkTreeView" id="serversView">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="model">serversStore</property>
- <property name="headers_clickable">False</property>
- <property name="search_column">0</property>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection"/>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="hostnameColumn">
- <property name="title" translatable="yes">Host Name</property>
- <property name="expand">True</property>
- <child>
- <object class="GtkCellRendererText" id="hostnameRenderer">
- <property name="editable">True</property>
- <signal name="edited" handler="on_server_edited" swapped="no"/>
- </object>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="pool">
- <property name="title" translatable="yes">Pool</property>
- <child>
- <object class="GtkCellRendererToggle" id="poolRenderer">
- <signal name="toggled" handler="on_pool_toggled" swapped="no"/>
- </object>
- <attributes>
- <attribute name="active">1</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="workingColumn">
- <property name="title" translatable="yes">Working</property>
- <child>
- <object class="GtkCellRendererPixbuf" id="workingRenderer"/>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="removeColumn">
- <property name="title" translatable="yes">Use</property>
- <child>
- <object class="GtkCellRendererToggle" id="removeRenderer">
- <signal name="toggled" handler="on_use_server_toggled" swapped="no"/>
- </object>
- <attributes>
- <attribute name="active">3</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">4</property>
- </packing>
- </child>
- </object>
- </child>
- <action-widgets>
- <action-widget response="0">cancelButton</action-widget>
- <action-widget response="1">okButton</action-widget>
- </action-widgets>
- <child internal-child="accessible">
- <object class="AtkObject" id="ntpConfigDialog-atkobject">
- <property name="AtkObject::accessible-name" translatable="yes">Configure NTP</property>
- </object>
- </child>
- </object>
<object class="GtkImage" id="upImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -463,78 +238,7 @@
</packing>
</child>
<child>
- <object class="GtkAlignment" id="alignment4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="xscale">0.20000000298023224</property>
- <property name="right_padding">24</property>
- <child>
- <object class="GtkBox" id="box6">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <child>
- <object class="GtkLabel" id="networkTimeLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes" context="GUI|Date and Time">_Network Time</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">networkTimeSwitch</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="padding">3</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSwitch" id="networkTimeSwitch">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <signal name="notify::active" handler="on_ntp_switched" swapped="no"/>
- <child internal-child="accessible">
- <object class="AtkObject" id="networkTimeSwitch-atkobject">
- <property name="AtkObject::accessible-name" translatable="yes">Use Network Time</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="padding">1</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="ntpConfigButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">configImage</property>
- <signal name="clicked" handler="on_ntp_config_clicked" swapped="no"/>
- <child internal-child="accessible">
- <object class="AtkObject" id="ntpConfigButton-atkobject">
- <property name="AtkObject::accessible-name" translatable="yes">Configure NTP</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="padding">1</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">4</property>
- </packing>
+ <placeholder/>
</child>
</object>
</child>
diff --git a/pyanaconda/ui/gui/spokes/datetime_spoke.py b/pyanaconda/ui/gui/spokes/datetime_spoke.py
index 0a1b0b5a8..5fffb670a 100644
--- a/pyanaconda/ui/gui/spokes/datetime_spoke.py
+++ b/pyanaconda/ui/gui/spokes/datetime_spoke.py
@@ -45,7 +45,6 @@ from pyanaconda import iutil
from pyanaconda import isys
from pyanaconda import network
from pyanaconda import nm
-from pyanaconda import ntp
from pyanaconda import flags
from pyanaconda import constants
from pyanaconda.threads import threadMgr, AnacondaThread
@@ -149,247 +148,6 @@ def _new_date_field_box(store):
return (box, combo, suffix_label)
-class NTPconfigDialog(GUIObject, GUIDialogInputCheckHandler):
- builderObjects = ["ntpConfigDialog", "addImage", "serversStore"]
- mainWidgetName = "ntpConfigDialog"
- uiFile = "spokes/datetime_spoke.glade"
-
- def __init__(self, *args):
- GUIObject.__init__(self, *args)
-
- # Use GUIDIalogInputCheckHandler to manipulate the sensitivity of the
- # add button, and check for valid input in on_entry_activated
- add_button = self.builder.get_object("addButton")
- GUIDialogInputCheckHandler.__init__(self, add_button)
-
- #epoch is increased when serversStore is repopulated
- self._epoch = 0
- self._epoch_lock = threading.Lock()
-
- @property
- def working_server(self):
- for row in self._serversStore:
- if row[SERVER_WORKING] == constants.NTP_SERVER_OK and row[SERVER_USE]:
- #server is checked and working
- return row[SERVER_HOSTNAME]
-
- return None
-
- @property
- def pools_servers(self):
- pools = list()
- servers = list()
-
- for used_row in (row for row in self._serversStore if row[SERVER_USE]):
- if used_row[SERVER_POOL]:
- pools.append(used_row[SERVER_HOSTNAME])
- else:
- servers.append(used_row[SERVER_HOSTNAME])
-
- return (pools, servers)
-
- def _render_working(self, column, renderer, model, itr, user_data=None):
- value = model[itr][SERVER_WORKING]
-
- if value == constants.NTP_SERVER_QUERY:
- return "dialog-question"
- elif value == constants.NTP_SERVER_OK:
- return "emblem-default"
- else:
- return "dialog-error"
-
- def initialize(self):
- self.window.set_size_request(500, 400)
-
- workingColumn = self.builder.get_object("workingColumn")
- workingRenderer = self.builder.get_object("workingRenderer")
- override_cell_property(workingColumn, workingRenderer, "icon-name",
- self._render_working)
-
- self._serverEntry = self.builder.get_object("serverEntry")
- self._serversStore = self.builder.get_object("serversStore")
-
- self._addButton = self.builder.get_object("addButton")
-
- self._poolCheckButton = self.builder.get_object("poolCheckButton")
-
- # Validate the server entry box
- self._serverCheck = self.add_check(self._serverEntry, self._validateServer)
- self._serverCheck.update_check_status()
-
- self._initialize_store_from_config()
-
- def _initialize_store_from_config(self):
- self._serversStore.clear()
-
- if self.data.timezone.ntpservers:
- pools, servers = ntp.internal_to_pools_and_servers(self.data.timezone.ntpservers)
- else:
- try:
- pools, servers = ntp.get_servers_from_config()
- except ntp.NTPconfigError:
- log.warning("Failed to load NTP servers configuration")
- return
-
- for pool in pools:
- self._add_server(pool, True)
- for server in servers:
- self._add_server(server, False)
-
-
- def _validateServer(self, inputcheck):
- server = self.get_input(inputcheck.input_obj)
-
- # If not set, fail the check to keep the button insensitive, but don't
- # display an error
- if not server:
- return InputCheck.CHECK_SILENT
-
- (valid, error) = network.sanityCheckHostname(server)
- if not valid:
- return "'%s' is not a valid hostname: %s" % (server, error)
- else:
- return InputCheck.CHECK_OK
-
- def refresh(self):
- self._serverEntry.grab_focus()
-
- def refresh_servers_state(self):
- itr = self._serversStore.get_iter_first()
- while itr:
- self._refresh_server_working(itr)
- itr = self._serversStore.iter_next(itr)
-
- def run(self):
- self.window.show()
- rc = self.window.run()
- self.window.hide()
-
- #OK clicked
- if rc == 1:
- new_pools, new_servers = self.pools_servers
-
- if flags.can_touch_runtime_system("save NTP servers configuration"):
- ntp.save_servers_to_config(new_pools, new_servers)
- iutil.restart_service(NTP_SERVICE)
-
- #Cancel clicked, window destroyed...
- else:
- self._epoch_lock.acquire()
- self._epoch += 1
- self._epoch_lock.release()
-
- self._initialize_store_from_config()
-
- return rc
-
- def _set_server_ok_nok(self, itr, epoch_started):
- """
- If the server is working, set its data to NTP_SERVER_OK, otherwise set its
- data to NTP_SERVER_NOK.
-
- :param itr: iterator of the $server's row in the self._serversStore
-
- """
-
- @gtk_action_nowait
- def set_store_value(arg_tuple):
- """
- We need a function for this, because this way it can be added to
- the MainLoop with thread-safe GLib.idle_add (but only with one
- argument).
-
- :param arg_tuple: (store, itr, column, value)
-
- """
-
- (store, itr, column, value) = arg_tuple
- store.set_value(itr, column, value)
-
- orig_hostname = self._serversStore[itr][SERVER_HOSTNAME]
- server_working = ntp.ntp_server_working(self._serversStore[itr][SERVER_HOSTNAME])
-
- #do not let dialog change epoch while we are modifying data
- self._epoch_lock.acquire()
-
- #check if we are in the same epoch as the dialog (and the serversStore)
- #and if the server wasn't changed meanwhile
- if epoch_started == self._epoch:
- actual_hostname = self._serversStore[itr][SERVER_HOSTNAME]
-
- if orig_hostname == actual_hostname:
- if server_working:
- set_store_value((self._serversStore,
- itr, SERVER_WORKING, constants.NTP_SERVER_OK))
- else:
- set_store_value((self._serversStore,
- itr, SERVER_WORKING, constants.NTP_SERVER_NOK))
- self._epoch_lock.release()
-
- @gtk_action_nowait
- def _refresh_server_working(self, itr):
- """ Runs a new thread with _set_server_ok_nok(itr) as a taget. """
-
- self._serversStore.set_value(itr, SERVER_WORKING, constants.NTP_SERVER_QUERY)
- threadMgr.add(AnacondaThread(prefix=constants.THREAD_NTP_SERVER_CHECK,
- target=self._set_server_ok_nok,
- args=(itr, self._epoch)))
-
- def _add_server(self, server, pool=False):
- """
- Checks if a given server is a valid hostname and if yes, adds it
- to the list of servers.
-
- :param server: string containing hostname
-
- """
-
- itr = self._serversStore.append([server, pool, constants.NTP_SERVER_QUERY, True])
-
- #do not block UI while starting thread (may take some time)
- self._refresh_server_working(itr)
-
- def on_entry_activated(self, entry, *args):
- # Check that the input check has passed
- if self._serverCheck.check_status == InputCheck.CHECK_OK:
- self._add_server(entry.get_text(), self._poolCheckButton.get_active())
- entry.set_text("")
- self._poolCheckButton.set_active(False)
-
- def on_add_clicked(self, *args):
- self._serverEntry.emit("activate")
-
- def on_use_server_toggled(self, renderer, path, *args):
- itr = self._serversStore.get_iter(path)
- old_value = self._serversStore[itr][SERVER_USE]
-
- self._serversStore.set_value(itr, SERVER_USE, not old_value)
-
- def on_pool_toggled(self, renderer, path, *args):
- itr = self._serversStore.get_iter(path)
- old_value = self._serversStore[itr][SERVER_POOL]
-
- self._serversStore.set_value(itr, SERVER_POOL, not old_value)
-
- def on_server_edited(self, renderer, path, new_text, *args):
- if not path:
- return
-
- (valid, error) = network.sanityCheckHostname(new_text)
- if not valid:
- log.error("'%s' is not a valid hostname: %s", new_text, error)
- return
-
- itr = self._serversStore.get_iter(path)
-
- if self._serversStore[itr][SERVER_HOSTNAME] == new_text:
- return
-
- self._serversStore.set_value(itr, SERVER_HOSTNAME, new_text)
- self._serversStore.set_value(itr, SERVER_WORKING, constants.NTP_SERVER_QUERY)
-
- self._refresh_server_working(itr)
-
class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
"""
.. inheritance-diagram:: DatetimeSpoke
@@ -480,8 +238,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
self._year_format, suffix = formats[widgets.index(year_box)]
year_label.set_text(suffix)
- self._ntpSwitch = self.builder.get_object("networkTimeSwitch")
-
self._regions_zones = get_all_regions_and_timezones()
# Set the initial sensitivity of the AM/PM toggle based on the time-type selected
@@ -490,9 +246,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
if not flags.can_touch_runtime_system("modify system time and date"):
self._set_date_time_setting_sensitive(False)
- self._config_dialog = NTPconfigDialog(self.data)
- self._config_dialog.initialize()
-
threadMgr.add(AnacondaThread(name=constants.THREAD_DATE_TIME,
target=self._initialize))
@@ -574,8 +327,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
self.data.timezone.seen = False
self._kickstarted = False
- self.data.timezone.nontp = not self._ntpSwitch.get_active()
-
def execute(self):
if self._update_datetime_timer_id is not None:
GLib.source_remove(self._update_datetime_timer_id)
@@ -610,20 +361,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
self._update_datetime()
- has_active_network = nm.nm_is_connected()
- if not has_active_network:
- self._show_no_network_warning()
- else:
- self.clear_info()
- gtk_call_once(self._config_dialog.refresh_servers_state)
-
- if flags.can_touch_runtime_system("get NTP service state"):
- ntp_working = has_active_network and iutil.service_running(NTP_SERVICE)
- else:
- ntp_working = not self.data.timezone.nontp
-
- self._ntpSwitch.set_active(ntp_working)
-
@gtk_action_wait
def _set_timezone(self, timezone):
"""
@@ -1078,72 +815,3 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
#contains all date/time setting widgets
footer_alignment = self.builder.get_object("footerAlignment")
footer_alignment.set_sensitive(sensitive)
-
- def _show_no_network_warning(self):
- self.set_warning(_("You need to set up networking first if you "\
- "want to use NTP"))
-
- def _show_no_ntp_server_warning(self):
- self.set_warning(_("You have no working NTP server configured"))
-
- def on_ntp_switched(self, switch, *args):
- if switch.get_active():
- #turned ON
- if not flags.can_touch_runtime_system("start NTP service"):
- #cannot touch runtime system, not much to do here
- return
-
- if not nm.nm_is_connected():
- self._show_no_network_warning()
- switch.set_active(False)
- return
- else:
- self.clear_info()
-
- working_server = self._config_dialog.working_server
- if working_server is None:
- self._show_no_ntp_server_warning()
- else:
- #we need a one-time sync here, because chronyd would not change
- #the time as drastically as we need
- ntp.one_time_sync_async(working_server)
-
- ret = iutil.start_service(NTP_SERVICE)
- self._set_date_time_setting_sensitive(False)
-
- #if starting chronyd failed and chronyd is not running,
- #set switch back to OFF
- if (ret != 0) and not iutil.service_running(NTP_SERVICE):
- switch.set_active(False)
-
- else:
- #turned OFF
- if not flags.can_touch_runtime_system("stop NTP service"):
- #cannot touch runtime system, nothing to do here
- return
-
- self._set_date_time_setting_sensitive(True)
- ret = iutil.stop_service(NTP_SERVICE)
-
- #if stopping chronyd failed and chronyd is running,
- #set switch back to ON
- if (ret != 0) and iutil.service_running(NTP_SERVICE):
- switch.set_active(True)
-
- self.clear_info()
-
- def on_ntp_config_clicked(self, *args):
- self._config_dialog.refresh()
-
- with self.main_window.enlightbox(self._config_dialog.window):
- response = self._config_dialog.run()
-
- if response == 1:
- pools, servers = self._config_dialog.pools_servers
- self.data.timezone.ntpservers = ntp.pools_servers_to_internal(pools, servers)
-
- if self._config_dialog.working_server is None:
- self._show_no_ntp_server_warning()
- else:
- self.clear_info()
-
--
2.14.4

@ -0,0 +1,37 @@
From dfa00956589ebcb0b8c7f4faca9f5a833945b74c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: drop useless on Qubes dependencies on network
filesystems
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Installing Qubes on network drive is not supported, so drop those dependencies.
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/kickstart.py | 6 ------
1 file changed, 6 deletions(-)
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index 7d67bf1a6..1121e0928 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -2155,12 +2155,6 @@ def parseKickstart(f):
# We need this so all the /dev/disk/* stuff is set up before parsing.
udev.trigger(subsystem="block", action="change")
- # So that drives onlined by these can be used in the ks file
- blivet.iscsi.iscsi.startup()
- blivet.fcoe.fcoe.startup()
- blivet.zfcp.zfcp.startup()
- # Note we do NOT call dasd.startup() here, that does not online drives, but
- # only checks if they need formatting, which requires zerombr to be known
try:
ksparser.readKickstart(f)
--
2.14.4

@ -0,0 +1,35 @@
From 29313be0db3cd1498629e9f5ff9a1b64b5fceec3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: skip NTP installation and setup in dom0
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Dom0 has no direct network access, to this doesn't make sense anyway.
Fixes QubesOS/qubes-issues#2110
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/kickstart.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index 1121e0928..5ac54b4fd 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -1715,6 +1715,9 @@ class Timezone(commands.timezone.F25_Timezone):
self._disabled_chrony = False
def setup(self, ksdata):
+ ### Skip the whole NTP setup in Qubes dom0
+ return
+
# do not install and use NTP package
if self.nontp or NTP_PACKAGE in ksdata.packages.excludedList:
if iutil.service_running(NTP_SERVICE) and \
--
2.14.4

@ -0,0 +1,58 @@
From fd7575cbd24f9f72447755995cd9e6694e23f149 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: don't force non-encrypted /boot on coreboot systems
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With grub payload it is possible to have all the partitions encrypted.
Based on patch by @tlaurion
Fixes QubesOS/qubes-issues#2118
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 963af46f9..fa56b532a 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -43,6 +43,8 @@ from blivet.size import Size
from pyanaconda.i18n import _, N_
import logging
+import subprocess
+
log = logging.getLogger("anaconda")
class serial_opts(object):
@@ -1411,16 +1413,15 @@ class GRUB2(GRUB):
raid.RAID5, raid.RAID6, raid.RAID10]
stage2_raid_metadata = ["0", "0.90", "1.0", "1.2"]
- @property
- def stage2_format_types(self):
- if productName.startswith("Red Hat "): # pylint: disable=no-member
- return ["xfs", "ext4", "ext3", "ext2", "btrfs"]
- else:
- return ["ext4", "ext3", "ext2", "btrfs", "xfs"]
+ stage2_format_types = ["ext4", "ext3", "ext2", "btrfs", "xfs"]
def __init__(self):
super(GRUB2, self).__init__()
+ self.encryption_support = True
+ self.stage2_format_types += ["lvmlv"]
+ self.skip_bootloader = flags.cmdline.getbool("skip_grub", False)
+
# XXX we probably need special handling for raid stage1 w/ gpt disklabel
# since it's unlikely there'll be a bios boot partition on each disk
--
2.14.4

@ -0,0 +1,65 @@
From efeff13f25e049159c556d40511f953e25aa3dc5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: switch default partitioning scheme to LVM Thin
Provisioning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
QubesOS/qubes-issues#2412
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/storage.py | 4 ++--
pyanaconda/ui/tui/spokes/storage.py | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 87a923657..7feda7db3 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -75,7 +75,7 @@ from pyanaconda import constants, iutil, isys
from pyanaconda.bootloader import BootLoaderError
from pyanaconda.storage_utils import on_disk_storage
-from pykickstart.constants import CLEARPART_TYPE_NONE, AUTOPART_TYPE_LVM
+from pykickstart.constants import CLEARPART_TYPE_NONE, AUTOPART_TYPE_LVM, AUTOPART_TYPE_LVM_THINP
from pykickstart.errors import KickstartParseError
import sys
@@ -553,7 +553,7 @@ class StorageSpoke(NormalSpoke, StorageChecker):
self.autopart = self.data.autopart.autopart
self.autoPartType = self.data.autopart.type
if self.autoPartType is None:
- self.autoPartType = AUTOPART_TYPE_LVM
+ self.autoPartType = AUTOPART_TYPE_LVM_THINP
self.encrypted = self.data.autopart.encrypted
self.passphrase = self.data.autopart.passphrase
diff --git a/pyanaconda/ui/tui/spokes/storage.py b/pyanaconda/ui/tui/spokes/storage.py
index fd6d7a505..d8ec992b9 100644
--- a/pyanaconda/ui/tui/spokes/storage.py
+++ b/pyanaconda/ui/tui/spokes/storage.py
@@ -42,7 +42,7 @@ from pyanaconda.constants_text import INPUT_PROCESSED
from pyanaconda.i18n import _, P_, N_, C_
from pyanaconda.bootloader import BootLoaderError
-from pykickstart.constants import CLEARPART_TYPE_ALL, CLEARPART_TYPE_LINUX, CLEARPART_TYPE_NONE, AUTOPART_TYPE_LVM
+from pykickstart.constants import CLEARPART_TYPE_ALL, CLEARPART_TYPE_LINUX, CLEARPART_TYPE_NONE, AUTOPART_TYPE_LVM, AUTOPART_TYPE_LVM_THINP
from pykickstart.errors import KickstartParseError
from collections import OrderedDict
@@ -351,7 +351,7 @@ class StorageSpoke(NormalTUISpoke):
self.data.clearpart.drives = self.selected_disks[:]
if self.data.autopart.type is None:
- self.data.autopart.type = AUTOPART_TYPE_LVM
+ self.data.autopart.type = AUTOPART_TYPE_LVM_THINP
if self.autopart:
self.clearPartType = CLEARPART_TYPE_ALL
--
2.14.4

@ -0,0 +1,29 @@
From 9891905a9d0b3ae52fafdfeae35b062a9b94bccb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: add "console=none" Xen parameter
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index fa56b532a..0e5a9a062 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1504,6 +1504,7 @@ class GRUB2(GRUB):
# boot arguments
log.info("bootloader.py: used boot args: %s ", self.boot_args)
defaults.write("GRUB_CMDLINE_LINUX=\"%s\"\n" % self.boot_args)
+ defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none\"\n")
defaults.write("GRUB_DISABLE_RECOVERY=\"true\"\n")
defaults.write("GRUB_THEME=\"/boot/grub2/themes/system/theme.txt\"\n")
defaults.close()
--
2.14.4

@ -0,0 +1,34 @@
From dfa27101877f13bf3d0c6b7cc2715bf355c9f6e5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: add dom0_mem=min:1024M to default xen cmdline
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This will solve #959 for new installations.
Related to qubesos/qubes-issues#959
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 0e5a9a062..e726517fe 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1504,7 +1504,7 @@ class GRUB2(GRUB):
# boot arguments
log.info("bootloader.py: used boot args: %s ", self.boot_args)
defaults.write("GRUB_CMDLINE_LINUX=\"%s\"\n" % self.boot_args)
- defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none\"\n")
+ defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none dom0_mem=min:1024M\"\n")
defaults.write("GRUB_DISABLE_RECOVERY=\"true\"\n")
defaults.write("GRUB_THEME=\"/boot/grub2/themes/system/theme.txt\"\n")
defaults.close()
--
2.14.4

@ -0,0 +1,36 @@
From 8aa4e95d549833bb481fad948ff241838cc02dcf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: limit dom0 maxmem to 4GB to limit its overhead on
big systems
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Linux kernel have some memory overhead depending on maxmem. Dom0 isn't meant to use that much memory (most should be assigned to AppVMs), so on big systems this will be pure waste.
QubesOS/qubes-issues#1136
Fixes QubesOS/qubes-issues#1313
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index e726517fe..26a48fc7a 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1504,7 +1504,7 @@ class GRUB2(GRUB):
# boot arguments
log.info("bootloader.py: used boot args: %s ", self.boot_args)
defaults.write("GRUB_CMDLINE_LINUX=\"%s\"\n" % self.boot_args)
- defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none dom0_mem=min:1024M\"\n")
+ defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none dom0_mem=min:1024M dom0_mem=max:4096M\"\n")
defaults.write("GRUB_DISABLE_RECOVERY=\"true\"\n")
defaults.write("GRUB_THEME=\"/boot/grub2/themes/system/theme.txt\"\n")
defaults.close()
--
2.14.4

@ -0,0 +1,49 @@
From bc8defc9d1f4e07685d4535ae47659aae8f29aed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: disable iommu for IGFX
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Many Intel processors (and BIOSes) have invalid IOMMU configuration for
IGFX, which cause multiple problems - from screen glitches, to system
hang.
Since IGFX currently is still in dom0 (isn't isolated from other system
components), disabling IOMMU for it doesn't lower overall security.
When GUI domain will be implemented, we need to re-enable IOMMU here and
hope hardware manufacturers will fix it in the meantime.
Fixes QubesOS/qubes-issues#2836
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 26a48fc7a..b0db4a087 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1504,7 +1504,7 @@ class GRUB2(GRUB):
# boot arguments
log.info("bootloader.py: used boot args: %s ", self.boot_args)
defaults.write("GRUB_CMDLINE_LINUX=\"%s\"\n" % self.boot_args)
- defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none dom0_mem=min:1024M dom0_mem=max:4096M\"\n")
+ defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx\"\n")
defaults.write("GRUB_DISABLE_RECOVERY=\"true\"\n")
defaults.write("GRUB_THEME=\"/boot/grub2/themes/system/theme.txt\"\n")
defaults.close()
@@ -1885,7 +1885,7 @@ class XenEFI(EFIGRUB):
for image in self.images:
config.write("\n")
config.write("[{}]\n".format(image.version))
- config.write("options=loglvl=all dom0_mem=min:1024M dom0_mem=max:4096M\n")
+ config.write("options=loglvl=all dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx\n")
config.write("kernel={} root={} {}\n".format(
image.kernel,
image.device.fstab_spec,
--
2.14.4

@ -0,0 +1,121 @@
From 1e8e3f8cef09f30e31f878ef4ccade45cb00a6d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: check for virtualization features
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Warn if the hardware lack features required for proper Qubes OS operation.
Fixes QubesOS/qubes-issues#2977
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/iutil.py | 17 +++++++++++++++++
pyanaconda/ui/gui/spokes/welcome.glade | 2 +-
pyanaconda/ui/gui/spokes/welcome.py | 8 ++++++--
pyanaconda/ui/tui/spokes/warnings_spoke.py | 16 ++++++++--------
4 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
index d966ca65c..20ed54302 100644
--- a/pyanaconda/iutil.py
+++ b/pyanaconda/iutil.py
@@ -1098,6 +1098,23 @@ def is_unsupported_hw():
tainted = 0
status = bool(tainted & UNSUPPORTED_HW)
+ try:
+ xl_info = subprocess.check_output(['xl', 'info'])
+ xl_dmesg = subprocess.check_output(['xl', 'dmesg'])
+ except subprocess.CalledProcessError:
+ status = 'xl call failed'
+ else:
+ missing_features = []
+ for line in xl_info.splitlines():
+ if line.startswith(b'virt_caps'):
+ if b'hvm' not in line:
+ missing_features.append('HVM/VT-x/AMD-V')
+ if b'hvm_directio' not in line:
+ missing_features.append('IOMMU/VT-d/AMD-Vi')
+ if b'HVM: Hardware Assisted Paging (HAP) detected' not in xl_dmesg:
+ missing_features.append('HAP/SLAT/EPT/RVI')
+ status = ', '.join(missing_features)
+
if status:
log.debug("Installing on Unsupported Hardware")
return status
diff --git a/pyanaconda/ui/gui/spokes/welcome.glade b/pyanaconda/ui/gui/spokes/welcome.glade
index 2373a75f1..87e5bf0e9 100644
--- a/pyanaconda/ui/gui/spokes/welcome.glade
+++ b/pyanaconda/ui/gui/spokes/welcome.glade
@@ -507,7 +507,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
- <property name="label" translatable="yes">This hardware (or a combination thereof) is not supported by Red Hat. For more information on supported hardware, please refer to http://www.redhat.com/hardware.</property>
+ <property name="label" translatable="yes">This hardware lack features required by Qubes OS. Missing features: %(features)s. For more information on supported hardware, please refer to https://www.qubes-os.org/system-requirements/</property>
<property name="wrap">True</property>
<attributes>
<attribute name="font-desc" value="Cantarell 12"/>
diff --git a/pyanaconda/ui/gui/spokes/welcome.py b/pyanaconda/ui/gui/spokes/welcome.py
index c77e36214..802a2179b 100644
--- a/pyanaconda/ui/gui/spokes/welcome.py
+++ b/pyanaconda/ui/gui/spokes/welcome.py
@@ -295,9 +295,13 @@ class WelcomeLanguageSpoke(LangLocaleHandler, StandaloneSpoke):
sys.exit(0)
# pylint: disable=no-member
- if productName.startswith("Red Hat ") and \
- is_unsupported_hw() and not self.data.unsupportedhardware.unsupported_hardware:
+ unsupported_status = is_unsupported_hw()
+ if unsupported_status:
+ # Fedora kickstart do not have unsupported_hardware option:
+ # and not self.data.unsupportedhardware.unsupported_hardware:
dlg = self.builder.get_object("unsupportedHardwareDialog")
+ msg = self.builder.get_object("unsupportedHardwareDesc")
+ msg.set_text(_(msg.get_text()) % {'features': unsupported_status})
with self.main_window.enlightbox(dlg):
rc = dlg.run()
dlg.destroy()
diff --git a/pyanaconda/ui/tui/spokes/warnings_spoke.py b/pyanaconda/ui/tui/spokes/warnings_spoke.py
index 6334c656c..8aed09625 100644
--- a/pyanaconda/ui/tui/spokes/warnings_spoke.py
+++ b/pyanaconda/ui/tui/spokes/warnings_spoke.py
@@ -43,15 +43,15 @@ class WarningsSpoke(StandaloneTUISpoke):
def __init__(self, *args, **kwargs):
StandaloneTUISpoke.__init__(self, *args, **kwargs)
- self._message = _("This hardware (or a combination thereof) is not "
- "supported by Red Hat. For more information on "
- "supported hardware, please refer to "
- "http://www.redhat.com/hardware.")
+ self._message = _("This hardware lack features required by Qubes OS. "
+ "Missing features: %(features)s. "
+ "For more information on supported hardware, "
+ "please refer to https://www.qubes-os.org/system-requirements/")
# Does anything need to be displayed?
# pylint: disable=no-member
- self._unsupported = productName.startswith("Red Hat ") and \
- is_unsupported_hw() and \
- not self.data.unsupportedhardware.unsupported_hardware
+ # self._unsupported = not self.data.unsupportedhardware.unsupported_hardware \
+ # and is_unsupported_hw()
+ self._unsupported = is_unsupported_hw()
@property
def completed(self):
@@ -60,7 +60,7 @@ class WarningsSpoke(StandaloneTUISpoke):
def refresh(self, args=None):
StandaloneTUISpoke.refresh(self, args)
- self._window += [TextWidget(self._message), ""]
+ self._window += [TextWidget(self._message % {'features': self._unsupported}), ""]
return True
--
2.14.4

@ -0,0 +1,48 @@
From 2f453961a603a30bd132d7883701dfe8320ee95b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: generate proper extlinux.conf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes QubesOS/qubes-issues#2902
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index b0db4a087..b1e9ff421 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -2352,6 +2352,8 @@ class EXTLINUX(BootLoader):
def write_config_images(self, config):
self.write_config_console(config)
+ xen_gz = [x for x in os.listdir(iutil.getSysroot() + self.config_dir) if
+ x.startswith('xen-') and x.endswith('.gz')][0]
for image in self.images:
args = Arguments()
args.update(["root=%s" % image.device.fstab_spec, "ro"])
@@ -2364,10 +2366,12 @@ class EXTLINUX(BootLoader):
label = "%s(%s)" % (self.image_label(image), image.version)
label = label.replace(" ", "")
stanza = ("label %(label)s\n"
- "\tkernel %(boot_prefix)s/%(kernel)s\n"
- "\tinitrd %(boot_prefix)s/%(initrd)s\n"
- "\tappend %(args)s\n\n"
+ "\tkernel mboot.c32\n"
+ "\tappend %(boot_prefix)s/%(xen)s --- "
+ "%(boot_prefix)s/%(kernel)s %(args)s --- "
+ "%(boot_prefix)s/%(initrd)s\n"
% {"label": label,
+ "xen": xen_gz,
"kernel": image.kernel,
"initrd": image.initrd,
"args": args,
--
2.14.4

@ -0,0 +1,51 @@
From c247cc5c37932dbe1c1db85d7d948a4b83da112e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: don't crash when no target disk is available
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
self.storage.root_device may be None in such case. Instead, allow proper reporting that no space is available.
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/lib/space.py | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/ui/lib/space.py b/pyanaconda/ui/lib/space.py
index 3679a33eb..9b15c474f 100644
--- a/pyanaconda/ui/lib/space.py
+++ b/pyanaconda/ui/lib/space.py
@@ -75,8 +75,11 @@ class FileSystemSpaceChecker(object):
log.info("fs space: %s needed: %s", free, needed)
self.success = (free > needed)
if not self.success:
- dev_required_size = self.payload.requiredDeviceSize(self.storage.root_device.format)
- self.deficit = dev_required_size - self.storage.root_device.size
+ if self.storage.root_device:
+ dev_required_size = self.payload.requiredDeviceSize(self.storage.root_device.format)
+ self.deficit = dev_required_size - self.storage.root_device.size
+ else:
+ self.deficit = needed - free
self.error_message = _(self.error_template) % self.deficit
return self.success
@@ -107,8 +110,11 @@ class DirInstallSpaceChecker(FileSystemSpaceChecker):
log.info("fs space: %s needed: %s", free, needed)
self.success = (free > needed)
if not self.success:
- dev_required_size = self.payload.requiredDeviceSize(self.storage.root_device.format)
- self.deficit = dev_required_size - self.storage.root_device.size
+ if self.storage.root_device:
+ dev_required_size = self.payload.requiredDeviceSize(self.storage.root_device.format)
+ self.deficit = dev_required_size - self.storage.root_device.size
+ else:
+ self.deficit = needed - free
self.error_message = _(self.error_template) % self.deficit
return self.success
--
2.14.4

@ -0,0 +1,32 @@
From faf9c486b086a3af05047fa63a07ad2fd9de4477 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: consider Interrupt Remapping as required feature
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
QubesOS/qubes-issues#2977
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/iutil.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
index 20ed54302..e3fb28862 100644
--- a/pyanaconda/iutil.py
+++ b/pyanaconda/iutil.py
@@ -1113,6 +1113,8 @@ def is_unsupported_hw():
missing_features.append('IOMMU/VT-d/AMD-Vi')
if b'HVM: Hardware Assisted Paging (HAP) detected' not in xl_dmesg:
missing_features.append('HAP/SLAT/EPT/RVI')
+ if b'Intel VT-d Interrupt Remapping enabled' not in xl_dmesg:
+ missing_features.append('Interrupt Remapping')
status = ', '.join(missing_features)
if status:
--
2.14.4

@ -0,0 +1,32 @@
From 0ac6e123eb37cec6e5f5849e861e2e6d76f3be05 Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: lock root account by default
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/kickstart.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index 5ac54b4fd..c0db1b614 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -1665,6 +1665,11 @@ class ReqPart(commands.reqpart.F23_ReqPart):
do_reqpart(storage, reqs)
class RootPw(commands.rootpw.F18_RootPw):
+ def __init__(self, writePriority=100, *args, **kwargs):
+ if 'lock' not in kwargs:
+ kwargs['lock'] = True
+ super(RootPw, self).__init__(writePriority=writePriority, *args, **kwargs)
+
def execute(self, storage, ksdata, instClass, users):
if not self.password and not flags.automatedInstall:
self.lock = True
--
2.14.4

@ -0,0 +1,161 @@
From bb3d9ee61f69488c18035d16c804af5ff079b7b7 Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: add option to lock root account
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Not only default setting, so one could leave account locked if entered
password setting spoke.
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/password.glade | 18 +++++++++++-
pyanaconda/ui/gui/spokes/password.py | 51 +++++++++++++++++++++++----------
2 files changed, 53 insertions(+), 16 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/password.glade b/pyanaconda/ui/gui/spokes/password.glade
index 1a4e77720..1f1fe5837 100644
--- a/pyanaconda/ui/gui/spokes/password.glade
+++ b/pyanaconda/ui/gui/spokes/password.glade
@@ -40,6 +40,22 @@
<object class="GtkBox" id="AnacondaSpokeWindow-action_area1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
+ <child>
+ <object class="GtkCheckButton" id="lock">
+ <property name="label" translatable="yes">Lock root account</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="clicked" handler="on_lock_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
<child>
<object class="GtkGrid" id="pwgrid">
<property name="visible">True</property>
@@ -174,7 +190,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
diff --git a/pyanaconda/ui/gui/spokes/password.py b/pyanaconda/ui/gui/spokes/password.py
index 92acfa8f3..3e8ada1cc 100644
--- a/pyanaconda/ui/gui/spokes/password.py
+++ b/pyanaconda/ui/gui/spokes/password.py
@@ -56,6 +56,7 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
def __init__(self, *args):
NormalSpoke.__init__(self, *args)
GUISpokeInputCheckHandler.__init__(self)
+ self._lock = self.data.rootpw.lock
self._kickstarted = False
def initialize(self):
@@ -63,6 +64,7 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
# place holders for the text boxes
self.pw = self.builder.get_object("pw")
self.confirm = self.builder.get_object("confirmPW")
+ self.lock = self.builder.get_object("lock")
# Install the password checks:
# - Has a password been specified?
@@ -119,17 +121,31 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
# Enable the input checks in case they were disabled on the last exit
for check in self.checks:
check.enabled = True
-
- self.pw.grab_focus()
+ self.lock.set_active(self._lock)
+ self.on_lock_clicked(self.lock)
self.pw.emit("changed")
self.confirm.emit("changed")
+ def on_lock_clicked(self, lock):
+ self.pw.set_sensitive(not lock.get_active())
+ self.confirm.set_sensitive(not lock.get_active())
+ if not lock.get_active():
+ self.pw.grab_focus()
+
+# Caps lock detection isn't hooked up right now
+# def setCapsLockLabel(self):
+# if isCapsLockEnabled():
+# self.capslock.set_text("<b>" + _("Caps Lock is on.") + "</b>")
+# self.capslock.set_use_markup(True)
+# else:
+# self.capslock..set_text("")
+
@property
def status(self):
- if self.data.rootpw.password:
- return _("Root password is set")
- elif self.data.rootpw.lock:
+ if self.data.rootpw.lock:
return _("Root account is disabled")
+ elif self.data.rootpw.password:
+ return _("Root password is set")
else:
return _("Root password is not set")
@@ -145,15 +161,10 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
self.data.rootpw.seen = False
self._kickstarted = False
- self.data.rootpw.lock = False
-
- if not pw:
- self.data.rootpw.password = ''
- self.data.rootpw.isCrypted = False
- return
-
- self.data.rootpw.password = cryptPassword(pw)
- self.data.rootpw.isCrypted = True
+ if pw:
+ self.data.rootpw.password = cryptPassword(pw)
+ self.data.rootpw.isCrypted = True
+ self.data.rootpw.lock = self._lock
self.pw.set_placeholder_text("")
self.confirm.set_placeholder_text("")
@@ -173,6 +184,8 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
# If the password was set by kickstart, skip this check
if self._kickstarted and not self.policy.changesok:
return InputCheck.CHECK_OK
+ if self.lock.get_active():
+ return InputCheck.CHECK_OK
if not self.get_input(inputcheck.input_obj):
if inputcheck.input_obj == self.pw:
@@ -187,9 +200,17 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
pw = self.pw.get_text()
confirm = self.confirm.get_text()
+ lock = self.lock.get_active()
+
+ if lock:
+ self._lock = True
+ self._password = None
+ self.clear_info()
+ self._error = False
+ result = InputCheck.CHECK_OK
# Skip the check if no password is required
- if (not pw and not confirm) and self._kickstarted:
+ elif (not pw and not confirm) and self._kickstarted:
result = InputCheck.CHECK_OK
elif confirm and (pw != confirm):
result = _(PASSWORD_CONFIRM_ERROR_GUI)
--
2.14.4

@ -0,0 +1,35 @@
From 9a037670677088cf8c7b67b8b1d03e09b39932c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Pierret=20=28fepitre=29?=
<frederic.epitre@orange.fr>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: check/add user to 'wheel' and 'qubes' groups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Originally from 378cfc44dd218c61b838f4f9011dcfd790df59eb by Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/user.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/pyanaconda/ui/gui/spokes/user.py b/pyanaconda/ui/gui/spokes/user.py
index bb2ec15e1..e954292c7 100644
--- a/pyanaconda/ui/gui/spokes/user.py
+++ b/pyanaconda/ui/gui/spokes/user.py
@@ -380,6 +380,11 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
self._user.name = self.username.get_text()
self._user.gecos = self.fullname.get_text()
+ if "wheel" not in self._user.groups:
+ self._user.groups.append("wheel")
+ if "qubes" not in self._user.groups:
+ self._user.groups.append("qubes")
+
# Copy the spoke data back to kickstart
# If the user name is not set, no user will be created.
if self._user.name:
--
2.14.4

@ -0,0 +1,389 @@
From cd70689b0642d41dcbdb826df4fc9f79b1ef899e Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <m.v.b@runbox.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: Modify user configuration spoke for QubesOS
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/user.glade | 96 +++++++------------------------------
pyanaconda/ui/gui/spokes/user.py | 57 +++-------------------
pyanaconda/ui/tui/spokes/user.py | 21 ++------
3 files changed, 28 insertions(+), 146 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/user.glade b/pyanaconda/ui/gui/spokes/user.glade
index 2873ff2d9..e6700657d 100644
--- a/pyanaconda/ui/gui/spokes/user.glade
+++ b/pyanaconda/ui/gui/spokes/user.glade
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.18.3 -->
+<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.6"/>
<requires lib="AnacondaWidgets" version="1.0"/>
@@ -53,33 +53,15 @@
<property name="can_focus">False</property>
<property name="row_spacing">8</property>
<property name="column_spacing">9</property>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="xpad">10</property>
- <property name="label" translatable="yes" context="GUI|User">_Full name</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">t_fullname</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">1</property>
<property name="xpad">10</property>
<property name="label" translatable="yes" context="GUI|User">_User name</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">t_username</property>
+ <property name="xalign">1</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
@@ -89,29 +71,12 @@
<property name="top_attach">1</property>
</packing>
</child>
- <child>
- <object class="GtkEntry" id="t_fullname">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="caps_lock_warning">False</property>
- <signal name="changed" handler="full_name_changed" swapped="no"/>
- <child internal-child="accessible">
- <object class="AtkObject" id="t_fullname-atkobject">
- <property name="AtkObject::accessible-name" translatable="yes">Full Name</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
<child>
<object class="GtkEntry" id="t_username">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <signal name="changed" handler="username_changed" swapped="no"/>
<signal name="changed" handler="on_username_set_by_user" swapped="no"/>
+ <signal name="changed" handler="username_changed" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="t_username-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">User Name</property>
@@ -127,11 +92,11 @@
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">1</property>
<property name="xpad">10</property>
<property name="label" translatable="yes" context="GUI|User">_Password</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">t_password</property>
+ <property name="xalign">1</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
@@ -145,11 +110,11 @@
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">1</property>
<property name="xpad">10</property>
<property name="label" translatable="yes" context="GUI|User">_Confirm password</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">t_verifypassword</property>
+ <property name="xalign">1</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
@@ -166,7 +131,7 @@
<property name="visibility">False</property>
<property name="invisible_char">●</property>
<signal name="changed" handler="password_changed" swapped="no"/>
- <signal name="icon_release" handler="on_password_icon_clicked" swapped="no"/>
+ <signal name="icon-release" handler="on_password_icon_clicked" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="t_password-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Password</property>
@@ -184,7 +149,7 @@
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="invisible_char">●</property>
- <signal name="icon_release" handler="on_password_icon_clicked" swapped="no"/>
+ <signal name="icon-release" handler="on_password_icon_clicked" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="t_verifypassword-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Confirm Password</property>
@@ -200,9 +165,9 @@
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Tip:&lt;/b&gt; Keep your user name shorter than 32 characters and do not use spaces.</property>
<property name="use_markup">True</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">1</property>
@@ -268,45 +233,16 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="c_admin">
- <property name="label" translatable="yes" context="GUI|User">_Make this user administrator</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_admin_toggled" swapped="no"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- </packing>
+ <placeholder/>
</child>
<child>
- <object class="GtkGrid" id="grid2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkButton" id="b_advanced">
- <property name="label" translatable="yes" context="GUI|User">_Advanced...</property>
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <signal name="clicked" handler="on_advanced_clicked" swapped="no"/>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">8</property>
- </packing>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
</child>
<child>
<placeholder/>
diff --git a/pyanaconda/ui/gui/spokes/user.py b/pyanaconda/ui/gui/spokes/user.py
index e954292c7..dac6ba3e5 100644
--- a/pyanaconda/ui/gui/spokes/user.py
+++ b/pyanaconda/ui/gui/spokes/user.py
@@ -38,7 +38,7 @@ from pyanaconda.constants import ANACONDA_ENVIRON, FIRSTBOOT_ENVIRON,\
PW_ASCII_CHARS, PASSWORD_ASCII
from pyanaconda.regexes import GECOS_VALID, GROUPNAME_VALID, GROUPLIST_FANCY_PARSE
-__all__ = ["UserSpoke", "AdvancedUserDialog"]
+__all__ = ["UserSpoke"]
class AdvancedUserDialog(GUIObject, GUIDialogInputCheckHandler):
"""
@@ -214,7 +214,7 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
builderObjects = ["userCreationWindow"]
mainWidgetName = "userCreationWindow"
- focusWidgetName = "t_fullname"
+ focusWidgetName = "t_username"
uiFile = "spokes/user.glade"
helpFile = "UserSpoke.xml"
@@ -252,14 +252,16 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
else:
self._user = self.data.UserData()
+ self._wheel = self.data.GroupData(name="wheel")
+ self._qubes = self.data.GroupData(name="qubes")
+
+ self._groupDict = {"wheel": self._wheel, "qubes": self._qubes}
+
# placeholders for the text boxes
- self.fullname = self.builder.get_object("t_fullname")
self.username = self.builder.get_object("t_username")
self.pw = self.builder.get_object("t_password")
self.confirm = self.builder.get_object("t_verifypassword")
- self.admin = self.builder.get_object("c_admin")
self.usepassword = self.builder.get_object("c_usepassword")
- self.b_advanced = self.builder.get_object("b_advanced")
# Counters for checks that ask the user to click Done to confirm
self._waiveStrengthClicks = 0
@@ -306,8 +308,6 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
self.add_check(self.username, self._checkUsername)
- self.add_re_check(self.fullname, GECOS_VALID, _("Full name cannot contain colon characters"))
-
# Modify the GUI based on the kickstart and policy information
# This needs to happen after the input checks have been created, since
# the Gtk signal handlers use the input check variables.
@@ -323,9 +323,6 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
# User isn't allowed to change whether password is required or not
self.usepassword.set_sensitive(False)
- self._advanced = AdvancedUserDialog(self._user, self.data)
- self._advanced.initialize()
-
# set the visibility of the password entries
set_password_visibility(self.pw, False)
set_password_visibility(self.confirm, False)
@@ -336,8 +333,6 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
check.enabled = True
self.username.set_text(self._user.name)
- self.fullname.set_text(self._user.gecos)
- self.admin.set_active("wheel" in self._user.groups)
self.pw.emit("changed")
self.confirm.emit("changed")
@@ -378,7 +373,6 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
self._password_kickstarted = False
self._user.name = self.username.get_text()
- self._user.gecos = self.fullname.get_text()
if "wheel" not in self._user.groups:
self._user.groups.append("wheel")
@@ -469,34 +463,10 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
def username_changed(self, editable, data=None):
"""Called by Gtk on all username changes."""
- # Disable the advanced user dialog button when no username is set
- if editable.get_text():
- self.b_advanced.set_sensitive(True)
- else:
- self.b_advanced.set_sensitive(False)
-
# Re-run the password checks against the new username
self.pw.emit("changed")
self.confirm.emit("changed")
- def full_name_changed(self, editable, data=None):
- """Called by Gtk callback when the full name field changes."""
-
- if self.guesser:
- fullname = editable.get_text()
- username = guess_username(fullname)
-
- with blockedHandler(self.username, self.on_username_set_by_user):
- self.username.set_text(username)
-
- def on_admin_toggled(self, togglebutton, data=None):
- # Add or remove "wheel" from the grouplist on changes to the admin checkbox
- if togglebutton.get_active():
- if "wheel" not in self._user.groups:
- self._user.groups.append("wheel")
- elif "wheel" in self._user.groups:
- self._user.groups.remove("wheel")
-
def _checkPasswordEmpty(self, inputcheck):
"""Check whether a password has been specified at all.
@@ -612,19 +582,6 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
else:
return msg or _("Invalid user name")
- def on_advanced_clicked(self, _button, data=None):
- """Handler for the Advanced.. button. It starts the Advanced dialog
- for setting homedit, uid, gid and groups.
- """
-
- self._user.name = self.username.get_text()
-
- self._advanced.refresh()
- with self.main_window.enlightbox(self._advanced.window):
- self._advanced.run()
-
- self.admin.set_active("wheel" in self._user.groups)
-
def on_back_clicked(self, button):
# If the failed check is for non-ASCII characters,
# add a click to the counter and check again
diff --git a/pyanaconda/ui/tui/spokes/user.py b/pyanaconda/ui/tui/spokes/user.py
index 1005852db..834b82cbf 100644
--- a/pyanaconda/ui/tui/spokes/user.py
+++ b/pyanaconda/ui/tui/spokes/user.py
@@ -40,11 +40,9 @@ class UserSpoke(FirstbootSpokeMixIn, EditTUISpoke):
edit_fields = [
Entry("Create user", "_create", EditTUISpoke.CHECK, True),
- Entry("Fullname", "gecos", GECOS_VALID, lambda self, args: args._create),
Entry("Username", "name", check_username, lambda self, args: args._create),
Entry("Use password", "_use_password", EditTUISpoke.CHECK, lambda self, args: args._create),
Entry("Password", "_password", EditTUISpoke.PASSWORD, lambda self, args: args._use_password and args._create),
- Entry("Administrator", "_admin", EditTUISpoke.CHECK, lambda self, args: args._create),
Entry("Groups", "_groups", GROUPLIST_SIMPLE_VALID, lambda self, args: args._create)
]
@@ -84,7 +82,6 @@ class UserSpoke(FirstbootSpokeMixIn, EditTUISpoke):
self.errors = []
def refresh(self, args=None):
- self.args._admin = "wheel" in self.args.groups
self.args._groups = ", ".join(self.args.groups)
# if we have any errors, display them
@@ -146,22 +143,14 @@ class UserSpoke(FirstbootSpokeMixIn, EditTUISpoke):
return EditTUISpoke.input(self, args, key)
def apply(self):
- if self.args.gecos and not self.args.name:
- username = guess_username(self.args.gecos)
- valid, msg = check_username(username)
- if not valid:
- self.errors.append(_("Invalid user name: %(name)s.\n%(error_message)s")
- % {"name": username, "error_message": msg})
- else:
- self.args.name = guess_username(self.args.gecos)
-
self.args.groups = [g.strip() for g in self.args._groups.split(",") if g]
- # Add or remove the user from wheel group
- if self.args._admin and "wheel" not in self.args.groups:
+ # Add the user to the wheel and qubes groups
+ if "wheel" not in self.args.groups:
self.args.groups.append("wheel")
- elif not self.args._admin and "wheel" in self.args.groups:
- self.args.groups.remove("wheel")
+
+ if "qubes" not in self.args.groups:
+ self.args.groups.append("qubes")
# Add or remove the user from userlist as needed
if self.args._create and (self.args not in self.data.user.userList and self.args.name):
--
2.14.4

@ -0,0 +1,94 @@
From b93178bff8ecb1e362c79e845c2e7ceec08c682e Mon Sep 17 00:00:00 2001
From: "M. Vefa Bicakci" <m.v.b@runbox.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: Make sure that a user is created at installation
time
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/user.py | 8 ++------
pyanaconda/ui/tui/spokes/user.py | 10 +++-------
2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/user.py b/pyanaconda/ui/gui/spokes/user.py
index dac6ba3e5..dd281f8e4 100644
--- a/pyanaconda/ui/gui/spokes/user.py
+++ b/pyanaconda/ui/gui/spokes/user.py
@@ -26,7 +26,6 @@ from pyanaconda.users import cryptPassword, validatePassword, guess_username, ch
from pyanaconda.ui.gui.spokes import NormalSpoke
from pyanaconda.ui.gui import GUIObject
from pyanaconda.ui.categories.user_settings import UserSettingsCategory
-from pyanaconda.ui.common import FirstbootSpokeMixIn
from pyanaconda.ui.helpers import InputCheck
from pyanaconda.ui.gui.helpers import GUISpokeInputCheckHandler, GUIDialogInputCheckHandler
from pyanaconda.ui.gui.utils import blockedHandler, set_password_visibility
@@ -206,7 +205,7 @@ class AdvancedUserDialog(GUIObject, GUIDialogInputCheckHandler):
return False
-class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
+class UserSpoke(NormalSpoke, GUISpokeInputCheckHandler):
"""
.. inheritance-diagram:: UserSpoke
:parts: 3
@@ -348,10 +347,7 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler):
@property
def mandatory(self):
- """ Only mandatory if the root pw hasn't been set in the UI
- eg. not mandatory if the root account was locked in a kickstart
- """
- return not self.data.rootpw.password and not self.data.rootpw.lock
+ return True
def apply(self):
# set the password only if the user enters anything to the text entry
diff --git a/pyanaconda/ui/tui/spokes/user.py b/pyanaconda/ui/tui/spokes/user.py
index 834b82cbf..baa3ac203 100644
--- a/pyanaconda/ui/tui/spokes/user.py
+++ b/pyanaconda/ui/tui/spokes/user.py
@@ -20,7 +20,6 @@
from pyanaconda.ui.categories.user_settings import UserSettingsCategory
from pyanaconda.ui.tui.spokes import EditTUISpoke
from pyanaconda.ui.tui.spokes import EditTUISpokeEntry as Entry
-from pyanaconda.ui.common import FirstbootSpokeMixIn
from pyanaconda.users import guess_username, check_username
from pyanaconda.flags import flags
from pyanaconda.i18n import N_, _
@@ -30,7 +29,7 @@ from pyanaconda.regexes import GECOS_VALID, GROUPLIST_SIMPLE_VALID
__all__ = ["UserSpoke"]
-class UserSpoke(FirstbootSpokeMixIn, EditTUISpoke):
+class UserSpoke(EditTUISpoke):
"""
.. inheritance-diagram:: UserSpoke
:parts: 3
@@ -64,8 +63,8 @@ class UserSpoke(FirstbootSpokeMixIn, EditTUISpoke):
return False
def __init__(self, app, data, storage, payload, instclass):
- FirstbootSpokeMixIn.__init__(self)
EditTUISpoke.__init__(self, app, data, storage, payload, instclass, "user")
+
if self.data.user.userList:
self.args = self.data.user.userList[0]
self.args._create = True
@@ -108,10 +107,7 @@ class UserSpoke(FirstbootSpokeMixIn, EditTUISpoke):
@property
def mandatory(self):
- """ Only mandatory if the root pw hasn't been set in the UI
- eg. not mandatory if the root account was locked in a kickstart
- """
- return not self.data.rootpw.password and not self.data.rootpw.lock
+ return True
@property
def status(self):
--
2.14.4

@ -0,0 +1,42 @@
From 5c3b0d8d2319f323d5437bf51356b2988262e84f Mon Sep 17 00:00:00 2001
From: Freddie Rice <freddie.rice@gmail.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: xen.efi upgraded during each install
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index b1e9ff421..27c7ed34a 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1851,12 +1851,15 @@ class XenEFI(EFIGRUB):
boot_part_num = self.stage1_device.parents[0].parted_partition.number
boot_part_num = str(boot_part_num)
- if not os.path.exists(
- "{}/{}".format(iutil.getSysroot() + self.config_dir, "xen.efi")):
- xen_efi = [x for x in os.listdir(iutil.getSysroot() + self.config_dir) if
- x.startswith('xen-') and x.endswith('.efi')][0]
- shutil.copy("{}/{}".format(iutil.getSysroot() + self.config_dir, xen_efi),
- "{}/{}".format(iutil.getSysroot() + self.config_dir, "xen.efi"))
+ # could be an old version, replace in case
+ xen_efi_target = "{}/{}".format(iutil.getSysroot() + self.config_dir, "xen.efi")
+ if os.path.exists(xen_efi_target):
+ os.remove(xen_efi_target)
+
+ xen_efi = [x for x in os.listdir(iutil.getSysroot() + self.config_dir) if
+ x.startswith('xen-') and x.endswith('.efi')][0]
+ shutil.copy("{}/{}".format(iutil.getSysroot() + self.config_dir, xen_efi),
+ "{}/{}".format(iutil.getSysroot() + self.config_dir, "xen.efi"))
rc = self.efibootmgr("-c", "-w", "-L", productName,
"-d", boot_disk.path, "-p", boot_part_num,
"-l",
--
2.14.4

@ -0,0 +1,39 @@
From 53204d90309574fddbb0576d7a153657996eef33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: make sure the latest version is placed as xen.efi
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
os.listdir returns files in filesystem order, not sorted.
QubesOS/qubes-issues#2990
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 27c7ed34a..ad8e8c2e7 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1856,10 +1856,10 @@ class XenEFI(EFIGRUB):
if os.path.exists(xen_efi_target):
os.remove(xen_efi_target)
- xen_efi = [x for x in os.listdir(iutil.getSysroot() + self.config_dir) if
- x.startswith('xen-') and x.endswith('.efi')][0]
+ xen_efi = [x for x in sorted(os.listdir(iutil.getSysroot() + self.config_dir)) if
+ x.startswith('xen-') and x.endswith('.efi')][-1]
shutil.copy("{}/{}".format(iutil.getSysroot() + self.config_dir, xen_efi),
- "{}/{}".format(iutil.getSysroot() + self.config_dir, "xen.efi"))
+ xen_efi_target)
rc = self.efibootmgr("-c", "-w", "-L", productName,
"-d", boot_disk.path, "-p", boot_part_num,
"-l",
--
2.14.4

@ -0,0 +1,34 @@
From 0a627aa765eb6fa7e9adbc0ec76ebb1e745c3941 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: update message about unusupported hardware
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Advise to not continue.
Fixes QubesOS/qubes-issues#3208
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/welcome.glade | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/ui/gui/spokes/welcome.glade b/pyanaconda/ui/gui/spokes/welcome.glade
index 87e5bf0e9..8daed92af 100644
--- a/pyanaconda/ui/gui/spokes/welcome.glade
+++ b/pyanaconda/ui/gui/spokes/welcome.glade
@@ -507,7 +507,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
- <property name="label" translatable="yes">This hardware lack features required by Qubes OS. Missing features: %(features)s. For more information on supported hardware, please refer to https://www.qubes-os.org/system-requirements/</property>
+ <property name="label" translatable="yes">This hardware lacks features required by Qubes OS. Missing features: %(features)s. Without these features, Qubes OS will not function normally. It is recommended that only developers and power users proceed with the installation. For more information on supported hardware, please refer to https://www.qubes-os.org/system-requirements/</property>
<property name="wrap">True</property>
<attributes>
<attribute name="font-desc" value="Cantarell 12"/>
--
2.14.4

@ -0,0 +1,35 @@
From 9d9ba78cef13cbfb00af08fddfa122488763a8e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: check also for message about AMD interrupt
remapping
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes QubesOS/qubes-issues#3208
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/iutil.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
index e3fb28862..166626a67 100644
--- a/pyanaconda/iutil.py
+++ b/pyanaconda/iutil.py
@@ -1113,7 +1113,9 @@ def is_unsupported_hw():
missing_features.append('IOMMU/VT-d/AMD-Vi')
if b'HVM: Hardware Assisted Paging (HAP) detected' not in xl_dmesg:
missing_features.append('HAP/SLAT/EPT/RVI')
- if b'Intel VT-d Interrupt Remapping enabled' not in xl_dmesg:
+ # slightly different wording for Intel and AMD
+ if b'Intel VT-d Interrupt Remapping enabled' not in xl_dmesg \
+ and 'Interrupt remapping enabled' not in xl_dmesg:
missing_features.append('Interrupt Remapping')
status = ', '.join(missing_features)
--
2.14.4

@ -0,0 +1,45 @@
From 477f57c5661c58537e675e1d8cfa20c7430f826f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: Remove in-memory kickstart representation from
traceback file (#1519895)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We have been doing this filtering already, but some paths have likely
changed and the filter was no longer effective.
So add two new filter strings:
"_intf.storage.ksdata"
"_intf.data"
After adding these two I was no longer able to find the plaintext password
anywhere in the traceback after manually triggering a crash with:
kill -USR1 `cat /var/run/anaconda.pid`
Resolves: rhbz#1519895
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/exception.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/pyanaconda/exception.py b/pyanaconda/exception.py
index c283a605a..483cd51c4 100644
--- a/pyanaconda/exception.py
+++ b/pyanaconda/exception.py
@@ -274,7 +274,9 @@ def initExceptionHandling(anaconda):
"_intf._currentAction._spokes[\"UserSpoke\"]._oldweak",
"_intf.storage.bootloader.password",
"_intf.storage.data",
+ "_intf.storage.ksdata",
"_intf.storage.encryption_passphrase",
+ "_intf.data",
"_bootloader.encrypted_password",
"_bootloader.password",
"payload._groups"],
--
2.14.4

@ -0,0 +1,43 @@
From 4c4c8e2f14c53e1a79edd9545e73945aba66c876 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:12 +0200
Subject: [PATCH] anaconda: fix default scheme in custom partitioning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Update to LVM Thin Provisioning there too.
Fixes QubesOS/qubes-issues#3225
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/constants.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/constants.py b/pyanaconda/constants.py
index 3531fdca6..0e6270451 100644
--- a/pyanaconda/constants.py
+++ b/pyanaconda/constants.py
@@ -27,7 +27,7 @@ SELINUX_DEFAULT = -1
# where to look for 3rd party addons
ADDON_PATHS = ["/usr/share/anaconda/addons"]
-from pykickstart.constants import AUTOPART_TYPE_LVM
+from pykickstart.constants import AUTOPART_TYPE_LVM_THINP
# common string needs to be easy to change
from pyanaconda import product
@@ -169,7 +169,7 @@ SCREENSHOTS_TARGET_DIRECTORY = "/root/anaconda-screenshots"
# cmdline arguments that append instead of overwrite
CMDLINE_APPEND = ["modprobe.blacklist", "ifname"]
-DEFAULT_AUTOPART_TYPE = AUTOPART_TYPE_LVM
+DEFAULT_AUTOPART_TYPE = AUTOPART_TYPE_LVM_THINP
# Default to these units when reading user input when no units given
SIZE_UNITS_DEFAULT = "MiB"
--
2.14.4

@ -0,0 +1,30 @@
From 2d405103c8e9f04049dffed0af1bd03e47a8d79e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: fix interrupt remapping detection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/iutil.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
index 166626a67..c83bcddee 100644
--- a/pyanaconda/iutil.py
+++ b/pyanaconda/iutil.py
@@ -1115,7 +1115,7 @@ def is_unsupported_hw():
missing_features.append('HAP/SLAT/EPT/RVI')
# slightly different wording for Intel and AMD
if b'Intel VT-d Interrupt Remapping enabled' not in xl_dmesg \
- and 'Interrupt remapping enabled' not in xl_dmesg:
+ and b'Interrupt remapping enabled' not in xl_dmesg:
missing_features.append('Interrupt Remapping')
status = ', '.join(missing_features)
--
2.14.4

@ -0,0 +1,276 @@
From a1980ee725fc73e367bde3706c327684ac5e35ee Mon Sep 17 00:00:00 2001
From: Eric Duncan <me@eduncan911.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: Fix macOS EFI Installation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Typical GRUB2 installations would execute the script
located at /usr/libexec/mactel-boot-setup which would
modify the HFS+ ESP files and bless the specified efi.
However, we are not using GRUB at this time which would
cause that script to exit earlier.
These changes will execute the relevant commands
to symlink the efi file in the /System directory as well
the cfg file. Lastly, macOS requires the bootable efi
file to be blessed.
We also attempt to place some user-friendly icons
for Qubes to show to the user.
Lastly, we add a README with some instructions on how
to get into rescue mode from macOS.
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 220 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 215 insertions(+), 5 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index ad8e8c2e7..821eb2100 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1908,16 +1908,208 @@ class XenEFI(EFIGRUB):
write_config = BootLoader.write_config
-class MacEFIGRUB(EFIGRUB):
+class MacEFIGRUB(XenEFI):
+ """Special EFI handling for macOS HFS+ ESP partition.
+
+ Typical GRUB2 installations would execute the script
+ located at /usr/libexec/mactel-boot-setup which would
+ modify the HFS+ ESP files and bless the specified efi.
+
+ However, we are not using GRUB at this time which would
+ cause that script to exit earlier.
+
+ In this class, we will execute the relevant commands
+ to symlink the efi file in the /System directory as well
+ the cfg file. Lastly, macOS requires the bootable efi
+ file to be blessed.
+ """
+
+ def __init__(self):
+ super(MacEFIGRUB, self).__init__()
+ self._mountpoint = "/boot/efi" # fixme: extract from writeBootLoader()
+ self._system_label = "Qubes OS"
+ self._mactel_sys_dir = "{}/{}".format(self._mountpoint, "/System/Library/Coreservices")
+ self._mactel_artwork_dir = "{}/{}".format("/usr/share/pixmaps/bootloader/apple", self.efi_dir)
+
def mactel_config(self):
- if os.path.exists(iutil.getSysroot() + "/usr/libexec/mactel-boot-setup"):
- rc = iutil.execInSysroot("/usr/libexec/mactel-boot-setup", [])
- if rc:
- log.error("failed to configure Mac boot loader")
+ """Modifies the HFS+ ESP partition to be bootable.
+
+ Based on the /usr/libexec/mactel-boot-setup script,
+ we will create two symlinks pointing to the Qubes
+ Xen version that is installed and configured for
+ the system. We also need to run hfs-bless on
+ the specific EFI file we allow to be bootable.
+ """
+
+ log.info("mactel configure MacEFI boot partition")
+
+ not_ready = False
+ xen_efi_file = "{}/{}".format(iutil.getSysroot() + self.config_dir, "xen.efi")
+ if not os.path.exists(xen_efi_file):
+ log.waring("mactel efi file not found: %s", xen_efi_file)
+ not_ready = True
+ xen_cfg_file = "{}/{}".format(iutil.getSysroot() + self.config_dir, "xen.cfg")
+ if not os.path.exists(xen_cfg_file):
+ log.warning("mactel efi cfg not found: %s", xen_cfg_file)
+ not_ready = True
+ if not_ready:
+ log.error("mactel cannot continue with mactel_config. see log for details.")
+ return
+
+ sys_dir = iutil.getSysroot() + self._mactel_sys_dir
+ if not os.path.exists(sys_dir):
+ try:
+ os.makedirs(sys_dir)
+ except Exception as error:
+ log.warning("mactel tried to create sys_dir %s but received error: %s", sys_dir, error)
+
+ src_efi = "{}/{}".format("../../../EFI/" + self.efi_dir, "xen.efi")
+ sys_efi = "{}/{}".format(sys_dir, "boot.efi")
+ self._symlink(src_efi, sys_efi)
+
+ src_cfg = "{}/{}".format("../../../EFI/" + self.efi_dir, "xen.cfg")
+ sys_cfg = "{}/{}".format(sys_dir, "xen.cfg") # convention for Xen's cfg lookup
+ self._symlink(src_cfg, sys_cfg)
+
+ result_code = iutil.execInSysroot("touch", ["{}/{}".format(self._mountpoint, "mach_kernel")])
+ if result_code:
+ log.error("mactel failed to touch: %s", "{}/{}".format(self._mountpoint, "mach_kernel"))
+
+ text = """<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ProductBuildVersion</key>
+ <string></string>
+ <key>ProductName</key>
+ <string>Linux</string>
+ <key>ProductVersion</key>
+ <string>{}</string>
+</dict>
+</plist>""".format(self._system_label)
+ sys_ver_file_name = "{}/{}".format(sys_dir, "SystemVersion.plist")
+ try:
+ with open(sys_ver_file_name, "w") as sys_version_file:
+ sys_version_file.write(text)
+ except IOError as error:
+ log.error("mactel failed to open %s for write: %s", sys_ver_file_name, error)
+ cfg_ver_file_name = "{}/{}".format(iutil.getSysroot() + self.config_dir, "SystemVersion.plist")
+ self._copy_file(sys_ver_file_name, cfg_ver_file_name)
+
+ bless_file = "{}/{}".format(self.config_dir, "xen.efi")
+ result_code = iutil.execInSysroot("hfs-bless", [bless_file])
+ if result_code:
+ log.error("mactel failed to run 'hfs-bless %s'", bless_file)
+
+ # make the partition macOS friendly (e.g. to set rescue mode from macOS)
+ fseventsd = "{}/{}".format(iutil.getSysroot() + self._mountpoint, ".fseventsd")
+ try:
+ os.makedirs(fseventsd)
+ except Exception as error:
+ log.error("mactel could not make directory %s: %s", fseventsd, error)
+ touch_files = [
+ "{}/{}/{}".format(self._mountpoint, ".fseventsd", "no_log"),
+ "{}/{}".format(self._mountpoint, ".metadata_never_index"),
+ "{}/{}".format(self._mountpoint, ".Trashes")]
+ result_code = iutil.execInSysroot("touch", touch_files)
+ if result_code:
+ log.error("mactel failed to touch: %s", touch_files)
+
+ text = """Qubes OS
+
+CAUTION
+--
+This partition is used to boot Qubes OS on a macOS machine.
+Modifying the contents could render your installation unbootable.
+
+RESCUE / RECOVERY MODE
+--
+In the event that you need to boot into Rescue mode, you will need
+to change the default Xen configuration.
+
+0. Backup your xen.cfg.
+
+ cp /EFI/qubes/xen.cfg /EFI/qubes/xen.cfg~
+
+1. Open /EFI/qubes/xen.cfg
+2. Look at the sections with the named headers. One may already be
+ named "qubes-rescue", which we will use in Step 4 below.
+
+ If not, we will need to make one. Copy your current configuration
+ to another entry. But change the kernel line to only have "rescue"
+ at the end. As an example only:
+
+ [qubes-rescue]
+ options=loglvl=all dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx
+ kernel=vmlinuz-4.14.13-2.pvops.qubes.x86_64 rescue
+ ramdisk=initramfs-4.14.13-2.pvops.qubes.x86_64.img
+
+ Do not simply copy this section above. You will need to make sure
+ all of your existing parameters, vmlinuz and initramfs versions match
+ your current kernel(s) you are booting.
+
+3. At the top of the file, edit the default link to use your new entry.
+
+ [global]
+ default=qubes-rescue
+
+Now when you reboot using Boot Camp and select "Qubes OS", it will boot
+into Rescue mode.
+
+To revert, change the default entry back to the original first entry name."""
+ readme = "{}/{}".format(iutil.getSysroot() + self._mountpoint, "00-README.txt")
+ try:
+ with open(readme, "w") as readme_file:
+ readme_file.write(text)
+ except IOError as error:
+ log.error("mactel failed to open %s for write: %s", readme, error)
+
+ def mactel_install_qubes_artwork(self):
+ """Configures the Qubes logo and label for macOS boot selector.
+
+ Shows during boot selection options.
+
+ .disk_label is defined as a text representation of the volume
+ label converted to a special image. See this link for
+ more details: http://refit.sourceforge.net/info/vollabel.html
+
+ .VolumeIcon.icns is defined as an ICNS image format of 512x512.
+ """
+
+ log.info("mactel creating Qubes Artwork")
+
+ artwork_dir = self._mactel_artwork_dir
+ if not os.path.exists(artwork_dir):
+ log.debug("mactel using sysroot for artwork prefix")
+ artwork_dir = iutil.getSysroot() + artwork_dir
+ if not os.path.exists(artwork_dir):
+ log.warning("mactel artwork missing from: %s", artwork_dir)
+ return
+
+ icon_src = artwork_dir + ".icns"
+ if os.path.exists(icon_src):
+ icon_dst_fil = "{}/{}".format(iutil.getSysroot() + self._mountpoint, ".VolumeIcon.icns")
+ self._copy_file(icon_src, icon_dst_fil)
+ else:
+ log.warning("mactel volume icon not found: %s", icon_src)
+
+ src_files = os.listdir(artwork_dir)
+ for file_name in src_files:
+ full_file_name = "{}/{}".format(artwork_dir, file_name)
+ if os.path.isfile(full_file_name):
+ sys_dir_file_name = "{}/{}".format(iutil.getSysroot() + self._mactel_sys_dir, "." + file_name)
+ self._copy_file(full_file_name, sys_dir_file_name)
+ config_dir = iutil.getSysroot() + self.config_dir
+ if os.path.exists(config_dir):
+ dest = "{}/{}".format(config_dir, "." + file_name)
+ self._copy_file(full_file_name, dest)
+
def install(self, args=None):
super(MacEFIGRUB, self).install()
+ log.info("Installing mactel MacEFI")
self.mactel_config()
+ self.mactel_install_qubes_artwork()
def is_valid_stage1_device(self, device, early=False):
valid = super(MacEFIGRUB, self).is_valid_stage1_device(device, early)
@@ -1932,6 +2124,24 @@ class MacEFIGRUB(EFIGRUB):
log.debug("MacEFIGRUB.is_valid_stage1_device(%s) returning %s", device.name, valid)
return valid
+ @staticmethod
+ def _symlink(source="", target=""):
+ """Creates a symlink between source and target."""
+ try:
+ os.symlink(source, target)
+ except OSError as error:
+ log.error("mactel failed to symlink %s -> %s : %s", source, target, error)
+
+ @staticmethod
+ def _copy_file(source="", target=""):
+ """Copies source to target using shutil.
+
+ Also chmod to 0644."""
+ try:
+ shutil.copy(source, target)
+ os.chmod(target, 0o644)
+ except OSError as error:
+ log.error("mactel failed to copy %s to %s: %s", source, target, error)
# Inherit abstract methods from BootLoader
# pylint: disable=abstract-method
--
2.14.4

@ -0,0 +1,46 @@
From bcb258acbfb3b21c44422bdd9490e5f57c1e03fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: use proper subvolume argument when booting from
btrfs (EFI)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Kernel command line in legacy mode is constructed by grub scripts and
properly handle btrfs subvolumes. For EFI, it is built directly by
anaconda and 'rootflags=subvol=...' argument need to be added manually.
Fixes QubesOS/qubes-issues#1871
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 821eb2100..c68b8b1e8 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1886,12 +1886,15 @@ class XenEFI(EFIGRUB):
def write_config_images(self, config):
for image in self.images:
+ root_args = 'root=' + image.device.fstab_spec
+ if image.device.type == "btrfs subvolume":
+ root_args += " rootflags=subvol=%s" % image.device.name
config.write("\n")
config.write("[{}]\n".format(image.version))
config.write("options=loglvl=all dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx\n")
- config.write("kernel={} root={} {}\n".format(
+ config.write("kernel={} {} {}\n".format(
image.kernel,
- image.device.fstab_spec,
+ root_args,
self.boot_args))
config.write("ramdisk={}\n".format(image.initrd))
--
2.14.4

@ -0,0 +1,86 @@
From 99ea01b31f1733910123eff96a226f1183458839 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: enable discard option for dom0 filesystems by
default
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This may have performance impact on some older SSD, but on the other
hand, without this option it's pretty easy to fill the whole LVM thin
pool even if there is plenty free space in dom0.
Note that this doesn't enable it on LUKS layer, this is still disabled
by default.
Fixes QubesOS/qubes-issues#3226
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/install.py | 11 +++++++++++
pyanaconda/kickstart.py | 12 ++++++++++++
2 files changed, 23 insertions(+)
diff --git a/pyanaconda/install.py b/pyanaconda/install.py
index a11b6b43b..324e136c7 100644
--- a/pyanaconda/install.py
+++ b/pyanaconda/install.py
@@ -211,6 +211,17 @@ def doInstall(storage, payload, ksdata, instClass):
wait_for_entropy=entropy_wait_clbk)
turn_on_filesystems(storage, mount_only=flags.flags.dirInstall, callbacks=callbacks_reg)
+
+ # For autopart, actual partition related objects (especially
+ # blivet.format.FS objects) are created by the above call. And autopart
+ # does not provide any way to specify default mount options (unlike manual
+ # partitioning). Because of this, patch it now to add 'discard' option.
+ if storage.root_device.format.options and \
+ 'discard' not in storage.root_device.format.options:
+ storage.root_device.format.options += ',discard'
+ else:
+ storage.root_device.format.options = 'defaults,discard'
+
payload.writeStorageEarly()
# Run %pre-install scripts with the filesystem mounted and no packages
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index c0db1b614..5cd86d5fb 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -885,6 +885,10 @@ class LogVolData(commands.logvol.F23_LogVolData):
self.mountpoint = ""
ty = None
+ if self.mountpoint.startswith('/') and not self.fsopts:
+ # enable discard for normal filesystems in dom0
+ self.fsopts = "defaults,discard"
+
# Sanity check mountpoint
if self.mountpoint != "" and self.mountpoint[0] != '/':
raise KickstartParseError(formatErrorMsg(self.lineno,
@@ -1245,6 +1249,10 @@ class PartitionData(commands.partition.F23_PartData):
else:
ty = storage.default_fstype
+ if self.mountpoint.startswith('/') and not self.fsopts:
+ # enable discard for normal filesystems in dom0
+ self.fsopts = "defaults,discard"
+
if not size and self.size:
try:
size = Size("%d MiB" % self.size)
@@ -1490,6 +1498,10 @@ class RaidData(commands.raid.F25_RaidData):
else:
ty = storage.default_fstype
+ if self.mountpoint.startswith('/') and not self.fsopts:
+ # enable discard for normal filesystems in dom0
+ self.fsopts = "defaults,discard"
+
# Sanity check mountpoint
if self.mountpoint != "" and self.mountpoint[0] != '/':
raise KickstartParseError(formatErrorMsg(self.lineno,
--
2.14.4

@ -0,0 +1,45 @@
From 93611849f490f249b7ecf5c5cdce8852c526c73d Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: Add ucode=scan to default Xen command line
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Try to update microcode as early as possible if provided.
This option will scan all multiboot modules besides dom0 kernel. In our
case this is perfect - there is only one other module and it is
initramfs which have microcode early cpio prepended.
QubesOS/qubes-issues#3703
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index c68b8b1e8..27cc480b5 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1504,7 +1504,7 @@ class GRUB2(GRUB):
# boot arguments
log.info("bootloader.py: used boot args: %s ", self.boot_args)
defaults.write("GRUB_CMDLINE_LINUX=\"%s\"\n" % self.boot_args)
- defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx\"\n")
+ defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx ucode=scan\"\n")
defaults.write("GRUB_DISABLE_RECOVERY=\"true\"\n")
defaults.write("GRUB_THEME=\"/boot/grub2/themes/system/theme.txt\"\n")
defaults.close()
@@ -1891,7 +1891,7 @@ class XenEFI(EFIGRUB):
root_args += " rootflags=subvol=%s" % image.device.name
config.write("\n")
config.write("[{}]\n".format(image.version))
- config.write("options=loglvl=all dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx\n")
+ config.write("options=loglvl=all dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx ucode=scan\n")
config.write("kernel={} {} {}\n".format(
image.kernel,
root_args,
--
2.14.4

@ -0,0 +1,36 @@
From 5136f7c2142166360108c104fdf9244cdca91820 Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: avoid adding duplicated kernel entries
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
List kernel versions without duplicates, even when there are multiple
files related to the same kernel version.
Duplicated kernel versions here caused regenerating initramfs multiple
times and duplicated entries in xen.cfg.
QubesOS/qubes-issues#3624
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/packaging/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py
index 8332ce0e5..26eb953d4 100644
--- a/pyanaconda/packaging/__init__.py
+++ b/pyanaconda/packaging/__init__.py
@@ -829,7 +829,7 @@ class PackagePayload(Payload):
if fnmatch(f, "/boot/vmlinuz-*") or
fnmatch(f, "/boot/efi/EFI/%s/vmlinuz-*" % self.instclass.efi_dir)))
- return sorted(files, key=functools.cmp_to_key(versionCmp))
+ return sorted(set(files), key=functools.cmp_to_key(versionCmp))
@property
def rpmMacros(self):
--
2.14.4

@ -0,0 +1,51 @@
From fb3d98cebb67a468e37c036b1dd2c1707cc731bd Mon Sep 17 00:00:00 2001
From: Andrew David Wong <adw@andrewdavidwong.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: Fix System Requirements URL and typo in hardware
warnings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes QubesOS/qubes-issues#3932
Related to QubesOS/qubes-issues#3208
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/welcome.glade | 2 +-
pyanaconda/ui/tui/spokes/warnings_spoke.py | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/welcome.glade b/pyanaconda/ui/gui/spokes/welcome.glade
index 8daed92af..3bd04fe08 100644
--- a/pyanaconda/ui/gui/spokes/welcome.glade
+++ b/pyanaconda/ui/gui/spokes/welcome.glade
@@ -507,7 +507,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
- <property name="label" translatable="yes">This hardware lacks features required by Qubes OS. Missing features: %(features)s. Without these features, Qubes OS will not function normally. It is recommended that only developers and power users proceed with the installation. For more information on supported hardware, please refer to https://www.qubes-os.org/system-requirements/</property>
+ <property name="label" translatable="yes">This hardware lacks features required by Qubes OS. Missing features: %(features)s. Without these features, Qubes OS will not function normally. It is recommended that only developers and power users proceed with the installation. For more information on supported hardware, please refer to https://www.qubes-os.org/doc/system-requirements/</property>
<property name="wrap">True</property>
<attributes>
<attribute name="font-desc" value="Cantarell 12"/>
diff --git a/pyanaconda/ui/tui/spokes/warnings_spoke.py b/pyanaconda/ui/tui/spokes/warnings_spoke.py
index 8aed09625..a0e750914 100644
--- a/pyanaconda/ui/tui/spokes/warnings_spoke.py
+++ b/pyanaconda/ui/tui/spokes/warnings_spoke.py
@@ -43,10 +43,10 @@ class WarningsSpoke(StandaloneTUISpoke):
def __init__(self, *args, **kwargs):
StandaloneTUISpoke.__init__(self, *args, **kwargs)
- self._message = _("This hardware lack features required by Qubes OS. "
+ self._message = _("This hardware lacks features required by Qubes OS. "
"Missing features: %(features)s. "
"For more information on supported hardware, "
- "please refer to https://www.qubes-os.org/system-requirements/")
+ "please refer to https://www.qubes-os.org/doc/system-requirements/")
# Does anything need to be displayed?
# pylint: disable=no-member
# self._unsupported = not self.data.unsupportedhardware.unsupported_hardware \
--
2.14.4

@ -0,0 +1,84 @@
From 9c52b9b77378282cf25c87744ff86935f529e345 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: save keyboard layout to udev
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Xorg loads keyboard layout for new devices (or existing one re-detected)
only from its config, ignoring runtime changes done in the meantime
(setxkbmap etc). Since installation process calls udevadm trigger
somewhere, all input devices are re-discovered and reverted to default
keyboard layout (us). Avoid this by configuring current keyboard layout
also as udev rules, which are loaded by Xorg while discovering device.
Fixes QubesOS/qubes-issues#3352
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/xkl_wrapper.py | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/pyanaconda/ui/gui/xkl_wrapper.py b/pyanaconda/ui/gui/xkl_wrapper.py
index a2f14ce75..73178310b 100644
--- a/pyanaconda/ui/gui/xkl_wrapper.py
+++ b/pyanaconda/ui/gui/xkl_wrapper.py
@@ -307,6 +307,8 @@ class XklWrapper(object):
raise XklWrapperError("Failed to add layout '%s (%s)'" % (layout,
variant))
+ self.save_layouts_to_udev(self._rec.layouts, self._rec.variants)
+
@gtk_action_wait
def remove_layout(self, layout):
"""
@@ -341,6 +343,8 @@ class XklWrapper(object):
raise XklWrapperError("Failed to remove layout '%s (%s)'" % (layout,
variant))
+ self.save_layouts_to_udev(new_layouts, new_variants)
+
@gtk_action_wait
def replace_layouts(self, layouts_list):
"""
@@ -368,6 +372,8 @@ class XklWrapper(object):
msg = "Failed to replace layouts with: %s" % ",".join(layouts_list)
raise XklWrapperError(msg)
+ self.save_layouts_to_udev(new_layouts, new_variants)
+
@gtk_action_wait
def set_switching_options(self, options):
"""
@@ -391,3 +397,26 @@ class XklWrapper(object):
msg = "Failed to set switching options to: %s" % ",".join(options)
raise XklWrapperError(msg)
+ def save_layouts_to_udev(self, layouts, variants):
+ """
+ Sets layouts to udev, so it will also apply to newly connected
+ keyboards (or existing after udevadm trigger). Otherwise Xorg setup
+ them based on xorg.conf with a fallback to hardcoded values.
+
+ :param layouts: list of layouts
+ :param variants: list of layout variants, matching *layouts*
+ """
+
+ udev_rules_dir = '/run/udev/rules.d'
+ udev_rules_path = udev_rules_dir + '/90-keyboard-layout.rules'
+ try:
+ iutil.mkdirChain(udev_rules_dir)
+ except FileExistsError:
+ pass
+ with open(udev_rules_path, 'w') as rules:
+ rules.write('ENV{{ID_INPUT_KEYBOARD}}=="1", '
+ 'ENV{{xkblayout}}="{layouts}", '
+ 'ENV{{xkbvariant}}="{variants}"\n'.format(
+ layouts=','.join(layouts), variants=','.join(variants)))
+
+ iutil.startProgram(['udevadm', 'control', '-R']).communicate()
--
2.14.4

@ -0,0 +1,67 @@
From ee52e579dee7e8b33c932a61d27151826e47a97e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: fix root password dialog
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Properly save 'lock' state. Previously if it was unchecked, new password
was saved, but remained locked.
Fixes QubesOS/qubes-issues#3327
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/password.py | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/password.py b/pyanaconda/ui/gui/spokes/password.py
index 3e8ada1cc..646e7f7c1 100644
--- a/pyanaconda/ui/gui/spokes/password.py
+++ b/pyanaconda/ui/gui/spokes/password.py
@@ -99,6 +99,8 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
self.pw.set_placeholder_text(_("The password is set."))
self.confirm.set_placeholder_text(_("The password is set."))
+ self._lock = self.data.rootpw.lock
+
self.pw_bar = self.builder.get_object("password_bar")
self.pw_label = self.builder.get_object("password_label")
@@ -131,6 +133,7 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
self.confirm.set_sensitive(not lock.get_active())
if not lock.get_active():
self.pw.grab_focus()
+ self._lock = lock.get_active()
# Caps lock detection isn't hooked up right now
# def setCapsLockLabel(self):
@@ -161,10 +164,12 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
self.data.rootpw.seen = False
self._kickstarted = False
- if pw:
+ if self._lock:
+ self.data.rootpw.lock = True
+ elif pw:
+ self.data.rootpw.lock = False
self.data.rootpw.password = cryptPassword(pw)
self.data.rootpw.isCrypted = True
- self.data.rootpw.lock = self._lock
self.pw.set_placeholder_text("")
self.confirm.set_placeholder_text("")
@@ -265,7 +270,7 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
return InputCheck.CHECK_OK
# If the password is empty, clear the strength bar and skip this check
- if not pw and not confirm:
+ if self.lock.get_active() or (not pw and not confirm):
self._updatePwQuality(True, 0)
return InputCheck.CHECK_OK
--
2.14.4

@ -0,0 +1,35 @@
From 2522cc68bb55ca668ca5a71abc9497fdd0114d21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: mark 'qubes' user name as reserved
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
'qubes' group is used internally, but useradd want to create a new group
named as new user, so 'qubes' user name should also be avoided.
Fixes QubesOS/qubes-issues#3777
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/users.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/users.py b/pyanaconda/users.py
index 366d6226f..1b4424be8 100644
--- a/pyanaconda/users.py
+++ b/pyanaconda/users.py
@@ -123,7 +123,7 @@ def validatePassword(pw, user="root", settings=None, minlen=None):
return (valid, strength, message)
def check_username(name):
- if name in os.listdir("/") + ["root", "home", "daemon", "system"]:
+ if name in os.listdir("/") + ["root", "home", "daemon", "system", "qubes"]:
return (False, _("User name is reserved for system: %s") % name)
if name.startswith("-"):
--
2.14.4

@ -0,0 +1,44 @@
From 3bf0a8b70e34c5019adf39b1a7439efa93e28ac6 Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: add smt=off xen option during installation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Defaults set during package installation do not apply, as booloader
configuration doesn't exist at that stage yet.
Reported by @rustybird
QubesOS/qubes-issues#4252
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 27cc480b5..deab41cf1 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1504,7 +1504,7 @@ class GRUB2(GRUB):
# boot arguments
log.info("bootloader.py: used boot args: %s ", self.boot_args)
defaults.write("GRUB_CMDLINE_LINUX=\"%s\"\n" % self.boot_args)
- defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx ucode=scan\"\n")
+ defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx ucode=scan smt=off\"\n")
defaults.write("GRUB_DISABLE_RECOVERY=\"true\"\n")
defaults.write("GRUB_THEME=\"/boot/grub2/themes/system/theme.txt\"\n")
defaults.close()
@@ -1891,7 +1891,7 @@ class XenEFI(EFIGRUB):
root_args += " rootflags=subvol=%s" % image.device.name
config.write("\n")
config.write("[{}]\n".format(image.version))
- config.write("options=loglvl=all dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx ucode=scan\n")
+ config.write("options=loglvl=all dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx ucode=scan smt=off\n")
config.write("kernel={} {} {}\n".format(
image.kernel,
root_args,
--
2.14.4

@ -0,0 +1,50 @@
From 8914364af4e9724852ad91ef583d425e5b0b53fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: update Qubes-specific code for Fedora 21 version
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
data/help/en-US/QubesPlaceholder.html | 5 +++++
data/help/en-US/QubesPlaceholderWithLinks.html | 13 +++++++++++++
2 files changed, 18 insertions(+)
create mode 100644 data/help/en-US/QubesPlaceholder.html
create mode 100644 data/help/en-US/QubesPlaceholderWithLinks.html
diff --git a/data/help/en-US/QubesPlaceholder.html b/data/help/en-US/QubesPlaceholder.html
new file mode 100644
index 000000000..6811a3871
--- /dev/null
+++ b/data/help/en-US/QubesPlaceholder.html
@@ -0,0 +1,5 @@
+<body>
+<h1>The Anaconda built-in help</h1>
+<p>...is not yet available for this screen.</p>
+<p>You can check the Anaconda wiki page, the Qubes Installation Guide or other online help resources instead.</p>
+</body>
diff --git a/data/help/en-US/QubesPlaceholderWithLinks.html b/data/help/en-US/QubesPlaceholderWithLinks.html
new file mode 100644
index 000000000..0f7d7dcd5
--- /dev/null
+++ b/data/help/en-US/QubesPlaceholderWithLinks.html
@@ -0,0 +1,13 @@
+<body>
+<h1>The Anaconda built-in help</h1>
+<p>...is not yet available for this screen.</p>
+<p>You can check the Anaconda wiki page, the Qubes Installation Guide or other online help resources instead:</p>
+<p>
+<ul>
+ <li><a href="https://wiki.qubes-os.org/wiki/InstallationGuideR3">Qubes R3 Installation Guide</a></li>
+ <li><a href="https://fedoraproject.org/wiki/Anaconda">Anaconda Wiki</a></li>
+ <li><a href="http://fedoraproject.org/wiki/Anaconda_Boot_Options">Anaconda Boot Options</a></li>
+ <li><a href="http://fedoraproject.org/wiki/Anaconda/Kickstart">Anaconda Kickstart</a></li>
+</ul>
+</p>
+</body>
--
2.14.4

@ -0,0 +1,151 @@
From 757f6c7095362f2b71321bc94ed67f290a6ff8db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: require user password being set
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Drop selectable option 'Require a password to use this account'. Make it
required.
QubesOS/qubes-issues#2574
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/user.glade | 17 ---------------
pyanaconda/ui/gui/spokes/user.py | 43 ++++++-------------------------------
2 files changed, 7 insertions(+), 53 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/user.glade b/pyanaconda/ui/gui/spokes/user.glade
index e6700657d..79283a948 100644
--- a/pyanaconda/ui/gui/spokes/user.glade
+++ b/pyanaconda/ui/gui/spokes/user.glade
@@ -174,23 +174,6 @@
<property name="top_attach">2</property>
</packing>
</child>
- <child>
- <object class="GtkCheckButton" id="c_usepassword">
- <property name="label" translatable="yes" context="GUI|User">_Require a password to use this account</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="xalign">0</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="usepassword_toggled" swapped="no"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">4</property>
- </packing>
- </child>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
diff --git a/pyanaconda/ui/gui/spokes/user.py b/pyanaconda/ui/gui/spokes/user.py
index dd281f8e4..7db7e44d4 100644
--- a/pyanaconda/ui/gui/spokes/user.py
+++ b/pyanaconda/ui/gui/spokes/user.py
@@ -260,7 +260,6 @@ class UserSpoke(NormalSpoke, GUISpokeInputCheckHandler):
self.username = self.builder.get_object("t_username")
self.pw = self.builder.get_object("t_password")
self.confirm = self.builder.get_object("t_verifypassword")
- self.usepassword = self.builder.get_object("c_usepassword")
# Counters for checks that ask the user to click Done to confirm
self._waiveStrengthClicks = 0
@@ -311,16 +310,8 @@ class UserSpoke(NormalSpoke, GUISpokeInputCheckHandler):
# This needs to happen after the input checks have been created, since
# the Gtk signal handlers use the input check variables.
if self._password_kickstarted:
- self.usepassword.set_active(True)
self.pw.set_placeholder_text(_("The password was set by kickstart."))
self.confirm.set_placeholder_text(_("The password was set by kickstart."))
- elif not self.policy.emptyok:
- # Policy is that a non-empty password is required
- self.usepassword.set_active(True)
-
- if not self.policy.emptyok:
- # User isn't allowed to change whether password is required or not
- self.usepassword.set_sensitive(False)
# set the visibility of the password entries
set_password_visibility(self.pw, False)
@@ -352,21 +343,12 @@ class UserSpoke(NormalSpoke, GUISpokeInputCheckHandler):
def apply(self):
# set the password only if the user enters anything to the text entry
# this should preserve the kickstart based password
- if self.usepassword.get_active():
- if self.pw.get_text():
- self._password_kickstarted = False
- self._user.password = cryptPassword(self.pw.get_text())
- self._user.isCrypted = True
- self.pw.set_placeholder_text("")
- self.confirm.set_placeholder_text("")
-
- # reset the password when the user unselects it
- else:
+ if self.pw.get_text():
+ self._password_kickstarted = False
+ self._user.password = cryptPassword(self.pw.get_text())
+ self._user.isCrypted = True
self.pw.set_placeholder_text("")
self.confirm.set_placeholder_text("")
- self._user.password = ""
- self._user.isCrypted = False
- self._password_kickstarted = False
self._user.name = self.username.get_text()
@@ -419,17 +401,6 @@ class UserSpoke(NormalSpoke, GUISpokeInputCheckHandler):
self.pw_bar.set_value(val)
self.pw_label.set_text(text)
- def usepassword_toggled(self, togglebutton=None, data=None):
- """Called by Gtk callback when the "Use password" check
- button is toggled. It will make password entries in/sensitive."""
-
- self.pw.set_sensitive(togglebutton.get_active())
- self.confirm.set_sensitive(togglebutton.get_active())
-
- # Re-check the password
- self.pw.emit("changed")
- self.confirm.emit("changed")
-
def password_changed(self, editable=None, data=None):
"""Update the password strength level bar"""
# Reset the counters used for the "press Done twice" logic
@@ -474,7 +445,7 @@ class UserSpoke(NormalSpoke, GUISpokeInputCheckHandler):
return InputCheck.CHECK_OK
# Skip the check if no password is required
- if (not self.usepassword.get_active()) or self._password_kickstarted:
+ if self._password_kickstarted:
return InputCheck.CHECK_OK
elif not self.get_input(inputcheck.input_obj):
if inputcheck.input_obj == self.pw:
@@ -488,7 +459,7 @@ class UserSpoke(NormalSpoke, GUISpokeInputCheckHandler):
"""If the user has entered confirmation data, check whether it matches the password."""
# Skip the check if no password is required
- if (not self.usepassword.get_active()) or self._password_kickstarted:
+ if self._password_kickstarted:
result = InputCheck.CHECK_OK
elif self.confirm.get_text() and (self.pw.get_text() != self.confirm.get_text()):
result = _(PASSWORD_CONFIRM_ERROR_GUI)
@@ -506,7 +477,7 @@ class UserSpoke(NormalSpoke, GUISpokeInputCheckHandler):
"""
# Skip the check if no password is required
- if not self.usepassword.get_active or self._password_kickstarted:
+ if self._password_kickstarted:
return InputCheck.CHECK_OK
# If the password is empty, clear the strength bar and skip this check
--
2.14.4

@ -0,0 +1,44 @@
From 6b1e2472eb4b495ac6e65ff5b39c3f42cfde50b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: abort installation on X startup fail
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Do not fallback to text mode, which cannot property install the system
without kickstart file (missing LUKS passphrase prompt).
Fixes QubesOS/qubes-issues#2996
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
anaconda.py | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/anaconda.py b/anaconda.py
index 25eba4b0a..f5c7fdb7f 100755
--- a/anaconda.py
+++ b/anaconda.py
@@ -543,10 +543,13 @@ def setupDisplay(anaconda, options, addons=None):
doStartupX11Actions()
except (OSError, RuntimeError) as e:
log.warning("X startup failed: %s", e)
- stdoutLog.warning("X startup failed, falling back to text mode")
- anaconda.displayMode = 't'
- graphical_failed = 1
- time.sleep(2)
+ stdoutLog.warning("X startup failed, aborting installation")
+ stdoutLog.error("X startup failed, aborting installation")
+ print(_("The installation cannot continue and the system will be rebooted"))
+ print(_("Press ENTER to continue"))
+ input()
+ iutil.ipmi_report(constants.IPMI_ABORTED)
+ sys.exit(1)
if not graphical_failed:
doExtraX11Actions(options.runres)
--
2.14.4

@ -0,0 +1,34 @@
From 94957794abf433c8a1ab48cace77fa6b4998eaa8 Mon Sep 17 00:00:00 2001
From: Wojtek Porczyk <woju@invisiblethingslab.com>
Date: Fri, 19 Oct 2018 08:02:13 +0200
Subject: [PATCH] anaconda: fix encryption passphrase check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The installer checks if there is password for autopart. It should check
that only if autopart is actually in use.
QubesOS/qubes-issues#2180
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/ui/gui/spokes/storage.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 7feda7db3..b812dc543 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -372,7 +372,7 @@ class StorageSpoke(NormalSpoke, StorageChecker):
# on the off-chance dasdfmt is running, we can't proceed further
threadMgr.wait(constants.THREAD_DASDFMT)
hubQ.send_message(self.__class__.__name__, _("Saving storage configuration..."))
- if flags.automatedInstall and self.data.autopart.encrypted and not self.data.autopart.passphrase:
+ if flags.automatedInstall and self.data.autopart.autopart and self.data.autopart.encrypted and not self.data.autopart.passphrase:
self.autopart_missing_passphrase = True
StorageChecker.errors = [_("Passphrase for autopart encryption not specified.")]
self._ready = True
--
2.14.4

@ -0,0 +1,30 @@
From e1e51562a8a25892f8c6027b428ce06b0465ac0b Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Sat, 20 Oct 2018 11:16:05 +0200
Subject: [PATCH] anaconda: disable os prober
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It tries to mount every existing block device, including VM images.
Signed-off-by: Frédéric Pierret <frederic.epitre@orange.fr>
---
pyanaconda/bootloader.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index deab41cf1..9a4defb9f 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1507,6 +1507,7 @@ class GRUB2(GRUB):
defaults.write("GRUB_CMDLINE_XEN_DEFAULT=\"console=none dom0_mem=min:1024M dom0_mem=max:4096M iommu=no-igfx ucode=scan smt=off\"\n")
defaults.write("GRUB_DISABLE_RECOVERY=\"true\"\n")
defaults.write("GRUB_THEME=\"/boot/grub2/themes/system/theme.txt\"\n")
+ defaults.write("GRUB_DISABLE_OS_PROBER=\"true\"\n")
defaults.close()
def _encrypt_password(self):
--
2.14.4

@ -0,0 +1,29 @@
From 83136384582280bde3379ee87898891d88463930 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Tue, 25 Jun 2019 19:59:17 +0200
Subject: [PATCH] Add "plymouth.ignore-serial-consoles" boot option by default
This preserve graphical boot even if plymouth detects /dev/hvc0 as a
serial console.
QubesOS/qubes-issues#3849
---
pyanaconda/installclasses/qubes.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/pyanaconda/installclasses/qubes.py b/pyanaconda/installclasses/qubes.py
index b5caff037..0ab8ce553 100644
--- a/pyanaconda/installclasses/qubes.py
+++ b/pyanaconda/installclasses/qubes.py
@@ -45,6 +45,7 @@ class InstallClass(BaseInstallClass):
installUpdates = False
bootloaderTimeoutDefault = 5
+ bootloaderExtraArgs = ["plymouth.ignore-serial-consoles"]
tasks = [(N_("Minimal"), ["base", "base-x", "kde-desktop-qubes", "qubes" ]) ]
--
2.20.1

@ -0,0 +1,79 @@
From 0f181e582ff47bb216f0f334a77518197d05f0fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Thu, 24 Oct 2019 18:11:46 +0200
Subject: [PATCH] Report 20% space needed for LVM thin provisioning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
blivet reserver 20% free space if thin pool is created. Anaconda/blivet
interface for reporting metadata/reserved space is lacking. As a
workaround add 20% at GUI layer.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
pyanaconda/ui/gui/spokes/lib/resize.py | 7 +++++++
pyanaconda/ui/gui/spokes/storage.py | 5 +++++
2 files changed, 12 insertions(+)
diff --git a/pyanaconda/ui/gui/spokes/lib/resize.py b/pyanaconda/ui/gui/spokes/lib/resize.py
index 73be5e23e..2626bec0d 100644
--- a/pyanaconda/ui/gui/spokes/lib/resize.py
+++ b/pyanaconda/ui/gui/spokes/lib/resize.py
@@ -31,6 +31,7 @@ from pyanaconda.ui.gui import GUIObject
from pyanaconda.ui.gui.utils import blockedHandler, escape_markup, timed_action
from blivet.size import Size
from blivet.formats.fs import FS
+from pykickstart.constants import AUTOPART_TYPE_LVM_THINP
__all__ = ["ResizeDialog"]
@@ -84,6 +85,9 @@ class ResizeDialog(GUIObject):
self._required_label = self.builder.get_object("requiredSpaceLabel")
markup = _("Installation requires a total of <b>%s</b> for system data.")
required_dev_size = self.payload.requiredDeviceSize(FS.biggest_overhead_FS())
+ if self.storage.autopart_type == AUTOPART_TYPE_LVM_THINP:
+ # blivet reserve 20% free space in volume group if thin pool is created
+ required_dev_size /= 0.8
self._required_label.set_markup(markup % escape_markup(str(required_dev_size)))
self._reclaimDescLabel = self.builder.get_object("reclaimDescLabel")
@@ -315,6 +319,9 @@ class ResizeDialog(GUIObject):
def _update_reclaim_button(self, got):
required_dev_size = self.payload.requiredDeviceSize(FS.biggest_overhead_FS())
+ if self.storage.autopart_type == AUTOPART_TYPE_LVM_THINP:
+ # blivet reserve 20% free space in volume group if thin pool is created
+ required_dev_size /= 0.8
self._resizeButton.set_sensitive(got+self._initialFreeSpace >= required_dev_size)
# pylint: disable=arguments-differ
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index a75f1dfc9..0c6000f2e 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -874,6 +874,9 @@ class StorageSpoke(NormalSpoke, StorageChecker):
disks_size = sum((d.size for d in disks), Size(0))
required_space = self.payload.spaceRequired
+ if self.storage.autopart_type == AUTOPART_TYPE_LVM_THINP:
+ # blivet reserve 20% free space in volume group if thin pool is created
+ required_space /= 0.8
auto_swap = sum((r.size for r in self.storage.autopart_requests
if r.fstype == "swap"), Size(0))
if self.autopart and auto_swap == Size(0):
@@ -1021,6 +1024,8 @@ class StorageSpoke(NormalSpoke, StorageChecker):
dialog = ResizeDialog(self.data, self.storage, self.payload)
dialog.refresh(disks)
else:
+ # respect disk selection and other choices in the ReclaimDialog
+ self.apply()
dialog = self._check_space_and_get_dialog(disks)
if dialog:
--
2.20.1

@ -0,0 +1,35 @@
From 2bccfe3f8c5e7ce18f4c4208914a1ea865072481 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Wed, 8 Jan 2020 20:28:25 +0100
Subject: [PATCH] Do not require user setup during automated (kickseeded)
install
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
OEM installation may prefer to setup it during initial-setup phase.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
pyanaconda/ui/gui/spokes/user.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/ui/gui/spokes/user.py b/pyanaconda/ui/gui/spokes/user.py
index 7db7e44..2bb110d 100644
--- a/pyanaconda/ui/gui/spokes/user.py
+++ b/pyanaconda/ui/gui/spokes/user.py
@@ -338,7 +338,7 @@ class UserSpoke(NormalSpoke, GUISpokeInputCheckHandler):
@property
def mandatory(self):
- return True
+ return not flags.automatedInstall
def apply(self):
# set the password only if the user enters anything to the text entry
--
2.21.0

Binary file not shown.

File diff suppressed because it is too large Load Diff

@ -0,0 +1,47 @@
From 1ce66b58907e229e21a0012a7a36ae93e9e32054 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Tue, 22 Oct 2019 16:15:31 +0200
Subject: [PATCH] Avoid mounting pre-existing disks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
This operation may be harmfull in many ways:
- may unintentionally modify a disk not selected as installation target
(mounting even read only replays journal for example)
- if previous system was compromised, it may try to exploit some of the
parsing code (filesystem driver etc) to survive across
re-installation
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
blivet/osinstall.py | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/blivet/osinstall.py b/blivet/osinstall.py
index 485e774c..f46388cd 100644
--- a/blivet/osinstall.py
+++ b/blivet/osinstall.py
@@ -211,14 +211,8 @@ def find_existing_installations(devicetree, teardown_all=True):
:rtype: list of :class:`Root`
"""
- try:
- roots = _find_existing_installations(devicetree)
- return roots
- except Exception: # pylint: disable=broad-except
- log_exception_info(log.info, "failure detecting existing installations")
- finally:
- if teardown_all:
- devicetree.teardown_all()
+ if teardown_all:
+ devicetree.teardown_all()
return []
--
2.20.1

@ -0,0 +1,36 @@
From 88b59572bccd4cfa60d5eb8d0379094a81908358 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Tue, 20 Aug 2019 04:17:42 +0200
Subject: [PATCH] Double recommended LVM thin pool metadata space
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Running out of metadata space is fatal, and it happens with the default
value on Qubes OS. Double the default to be safe.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
blivet/devices/lvm.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
index 72a2d395..e163dbe3 100644
--- a/blivet/devices/lvm.py
+++ b/blivet/devices/lvm.py
@@ -1532,6 +1532,9 @@ class LVMThinPoolMixin(object):
self._metadata_size = Size( get_thpool_meta_size(self._size,
self._chunk_size,
100)) # snapshots
+ # use twice as much as thin_metadata_size recommends, to accommodate
+ # large number of frequent snapshots
+ self._metadata_size *= 2
log.debug("Recommended metadata size: %s", self._metadata_size)
self._metadata_size = self.vg.align(self._metadata_size, roundup=True)
--
2.20.1

@ -0,0 +1,34 @@
From b4407b21415f6ede2542ef044fdc5d45b5dd5c48 Mon Sep 17 00:00:00 2001
From: Vojtech Trefny <vtrefny@redhat.com>
Date: Mon, 16 Oct 2017 12:57:44 +0200
Subject: [PATCH] Fix AttributeError in fsminsize (#1502587)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
blivet/tasks/fsminsize.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/blivet/tasks/fsminsize.py b/blivet/tasks/fsminsize.py
index ab6c647b..620b7dca 100644
--- a/blivet/tasks/fsminsize.py
+++ b/blivet/tasks/fsminsize.py
@@ -128,12 +128,12 @@ class Ext2FSMinSize(FSMinSize):
block_size = self._extract_block_size()
if block_size is None:
- raise FSError("failed to get block size for %s filesystem on %s" % (self.fs.mount_type, self.fs.device.name))
+ raise FSError("failed to get block size for %s filesystem on %s" % (self.fs.mount_type, self.fs.device))
resize_info = self._get_resize_info()
num_blocks = self._extract_num_blocks(resize_info)
if num_blocks is None:
- raise FSError("failed to get minimum block number for %s filesystem on %s" % (self.fs.mount_type, self.fs.device.name))
+ raise FSError("failed to get minimum block number for %s filesystem on %s" % (self.fs.mount_type, self.fs.device))
return block_size * num_blocks
--
2.13.6

@ -0,0 +1,76 @@
From e6369b8986953e3d0eba93cc024a2219320fa42c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Tue, 22 Oct 2019 14:52:17 +0200
Subject: [PATCH 1/2] Revert "FBA DASD should use the msdos disk label type"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
This reverts commit 41627e946cafc9341fd90c6713830aa67ebe28e7.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
blivet/platform.py | 21 ++++-----------------
python-blivet.spec | 2 +-
2 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/blivet/platform.py b/blivet/platform.py
index 4772b35d..9100487e 100644
--- a/blivet/platform.py
+++ b/blivet/platform.py
@@ -22,11 +22,6 @@
import logging
log = logging.getLogger("blivet")
-import gi
-gi.require_version("BlockDev", "2.0")
-
-from gi.repository import BlockDev as blockdev
-
import parted
from . import arch
@@ -356,20 +351,12 @@ class S390(Platform):
return [PartSpec(mountpoint="/boot", size=Size("1GiB"),
weight=self.weight(mountpoint="/boot"), lv=False)]
- def best_disklabel_type(self, device):
- """The best disklabel type for the specified device."""
- if flags.testing:
- return self.default_disklabel_type
-
- # the device is FBA DASD
- if blockdev.s390.dasd_is_fba(device.path):
- return "msdos"
- # the device is DASD
- elif parted.Device(path=device.path).type == parted.DEVICE_DASD:
+ def required_disklabel_type(self, device_type):
+ """The required disklabel type for the specified device type."""
+ if device_type == parted.DEVICE_DASD:
return "dasd"
- # other types of devices
- return super(S390, self).best_disklabel_type(device)
+ return super(S390, self).required_disklabel_type(device_type)
class ARM(Platform):
diff --git a/python-blivet.spec b/python-blivet.spec
index 1481bf84..0c3392c9 100644
--- a/python-blivet.spec
+++ b/python-blivet.spec
@@ -19,7 +19,7 @@ Source0: http://github.com/storaged-project/blivet/archive/%{realname}-%{realver
%global partedver 1.8.1
%global pypartedver 3.10.4
%global utillinuxver 2.15.1
-%global libblockdevver 2.6
+%global libblockdevver 2.1
%global libbytesizever 0.3
%global pyudevver 0.18
--
2.20.1

@ -0,0 +1,497 @@
From cbf2890b7be57e159e0890da4fded5062152f191 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Tue, 22 Oct 2019 14:52:36 +0200
Subject: [PATCH 2/2] Revert "Require BlockDev 2.0 in the gi.require_version()
call"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
This reverts commit 778ca84050289f4a4c27857d923d6e3aea4919fc.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
blivet/__init__.py | 2 +-
blivet/devicefactory.py | 2 +-
blivet/devicelibs/lvm.py | 2 +-
blivet/devices/btrfs.py | 2 +-
blivet/devices/disk.py | 2 +-
blivet/devices/dm.py | 2 +-
blivet/devices/loop.py | 2 +-
blivet/devices/lvm.py | 2 +-
blivet/devices/md.py | 2 +-
blivet/devices/partition.py | 2 +-
blivet/devicetree.py | 2 +-
blivet/formats/__init__.py | 2 +-
blivet/formats/luks.py | 2 +-
blivet/formats/lvmpv.py | 2 +-
blivet/formats/mdraid.py | 2 +-
blivet/formats/swap.py | 2 +-
blivet/osinstall.py | 2 +-
blivet/partitioning.py | 2 +-
blivet/populator/helpers/disk.py | 2 +-
blivet/populator/helpers/dmraid.py | 2 +-
blivet/populator/helpers/loop.py | 2 +-
blivet/populator/helpers/luks.py | 2 +-
blivet/populator/helpers/lvm.py | 2 +-
blivet/populator/helpers/mdraid.py | 2 +-
blivet/populator/helpers/partition.py | 2 +-
blivet/populator/populator.py | 2 +-
blivet/static_data/lvm_info.py | 2 +-
blivet/static_data/mpath_info.py | 2 +-
blivet/tasks/availability.py | 2 +-
blivet/tasks/lukstasks.py | 2 +-
blivet/tasks/pvtask.py | 2 +-
blivet/util.py | 2 +-
blivet/zfcp.py | 2 +-
python-blivet.spec | 2 +-
34 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/blivet/__init__.py b/blivet/__init__.py
index 1325e540..d5105842 100644
--- a/blivet/__init__.py
+++ b/blivet/__init__.py
@@ -75,7 +75,7 @@ log_bd_message = lambda level, msg: program_log.info(msg)
import gi
gi.require_version("GLib", "2.0")
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
# initialize the libblockdev library
from gi.repository import GLib
diff --git a/blivet/devicefactory.py b/blivet/devicefactory.py
index 5b680668..5f486aab 100644
--- a/blivet/devicefactory.py
+++ b/blivet/devicefactory.py
@@ -38,7 +38,7 @@ from .size import Size
from .static_data import luks_data
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/devicelibs/lvm.py b/blivet/devicelibs/lvm.py
index 24adf9a0..352f67a2 100644
--- a/blivet/devicelibs/lvm.py
+++ b/blivet/devicelibs/lvm.py
@@ -27,7 +27,7 @@ from collections import namedtuple
import itertools
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/devices/btrfs.py b/blivet/devices/btrfs.py
index c5cb21f7..35a2b099 100644
--- a/blivet/devices/btrfs.py
+++ b/blivet/devices/btrfs.py
@@ -24,7 +24,7 @@ import copy
import tempfile
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/devices/disk.py b/blivet/devices/disk.py
index 1136a535..acf31eed 100644
--- a/blivet/devices/disk.py
+++ b/blivet/devices/disk.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/devices/dm.py b/blivet/devices/dm.py
index a0350b24..e7efddfb 100644
--- a/blivet/devices/dm.py
+++ b/blivet/devices/dm.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/devices/loop.py b/blivet/devices/loop.py
index 78f88d7d..fcef161d 100644
--- a/blivet/devices/loop.py
+++ b/blivet/devices/loop.py
@@ -20,7 +20,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
index 72a2d395..39c6f342 100644
--- a/blivet/devices/lvm.py
+++ b/blivet/devices/lvm.py
@@ -30,7 +30,7 @@ from functools import wraps
from enum import Enum
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/devices/md.py b/blivet/devices/md.py
index 891805aa..3006236e 100644
--- a/blivet/devices/md.py
+++ b/blivet/devices/md.py
@@ -23,7 +23,7 @@ import os
import six
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/devices/partition.py b/blivet/devices/partition.py
index 4c175403..66f768d2 100644
--- a/blivet/devices/partition.py
+++ b/blivet/devices/partition.py
@@ -24,7 +24,7 @@ import parted
import _ped
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/devicetree.py b/blivet/devicetree.py
index 805f6a04..8057f7e7 100644
--- a/blivet/devicetree.py
+++ b/blivet/devicetree.py
@@ -25,7 +25,7 @@ import pprint
import re
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/formats/__init__.py b/blivet/formats/__init__.py
index f60402fe..6d4eaf39 100644
--- a/blivet/formats/__init__.py
+++ b/blivet/formats/__init__.py
@@ -22,7 +22,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/formats/luks.py b/blivet/formats/luks.py
index d8db8dd5..4ad8252a 100644
--- a/blivet/formats/luks.py
+++ b/blivet/formats/luks.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/formats/lvmpv.py b/blivet/formats/lvmpv.py
index 260cc0bd..b2f70cdc 100644
--- a/blivet/formats/lvmpv.py
+++ b/blivet/formats/lvmpv.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/formats/mdraid.py b/blivet/formats/mdraid.py
index 383160a3..ee7e887a 100644
--- a/blivet/formats/mdraid.py
+++ b/blivet/formats/mdraid.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/formats/swap.py b/blivet/formats/swap.py
index 46dc980f..185fda53 100644
--- a/blivet/formats/swap.py
+++ b/blivet/formats/swap.py
@@ -29,7 +29,7 @@ from . import DeviceFormat, register_device_format
from ..size import Size
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/osinstall.py b/blivet/osinstall.py
index a4f9535f..485e774c 100644
--- a/blivet/osinstall.py
+++ b/blivet/osinstall.py
@@ -26,7 +26,7 @@ import stat
import time
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/partitioning.py b/blivet/partitioning.py
index dcc7ce80..b7b2617c 100644
--- a/blivet/partitioning.py
+++ b/blivet/partitioning.py
@@ -25,7 +25,7 @@ from decimal import Decimal
import functools
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
import parted
diff --git a/blivet/populator/helpers/disk.py b/blivet/populator/helpers/disk.py
index e937128b..9313f766 100644
--- a/blivet/populator/helpers/disk.py
+++ b/blivet/populator/helpers/disk.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/populator/helpers/dmraid.py b/blivet/populator/helpers/dmraid.py
index 5db42196..987caec3 100644
--- a/blivet/populator/helpers/dmraid.py
+++ b/blivet/populator/helpers/dmraid.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/populator/helpers/loop.py b/blivet/populator/helpers/loop.py
index 99fc4bb5..33bb3423 100644
--- a/blivet/populator/helpers/loop.py
+++ b/blivet/populator/helpers/loop.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
from ... import udev
diff --git a/blivet/populator/helpers/luks.py b/blivet/populator/helpers/luks.py
index 433cc06e..d27089a6 100644
--- a/blivet/populator/helpers/luks.py
+++ b/blivet/populator/helpers/luks.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/populator/helpers/lvm.py b/blivet/populator/helpers/lvm.py
index 10ef1646..2a985adc 100644
--- a/blivet/populator/helpers/lvm.py
+++ b/blivet/populator/helpers/lvm.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/populator/helpers/mdraid.py b/blivet/populator/helpers/mdraid.py
index 998e8de9..5542cc4d 100644
--- a/blivet/populator/helpers/mdraid.py
+++ b/blivet/populator/helpers/mdraid.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/populator/helpers/partition.py b/blivet/populator/helpers/partition.py
index 73b15f11..d977ea49 100644
--- a/blivet/populator/helpers/partition.py
+++ b/blivet/populator/helpers/partition.py
@@ -23,7 +23,7 @@
import copy
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
from ... import udev
diff --git a/blivet/populator/populator.py b/blivet/populator/populator.py
index 7a6a4ae9..84c1d33d 100644
--- a/blivet/populator/populator.py
+++ b/blivet/populator/populator.py
@@ -26,7 +26,7 @@ import copy
import parted
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/static_data/lvm_info.py b/blivet/static_data/lvm_info.py
index 89e1b8e1..f8965f15 100644
--- a/blivet/static_data/lvm_info.py
+++ b/blivet/static_data/lvm_info.py
@@ -21,7 +21,7 @@
#
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/static_data/mpath_info.py b/blivet/static_data/mpath_info.py
index 71bf17e1..c9ca8a30 100644
--- a/blivet/static_data/mpath_info.py
+++ b/blivet/static_data/mpath_info.py
@@ -20,7 +20,7 @@
import os
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/tasks/availability.py b/blivet/tasks/availability.py
index 354a9ee1..c7f58b87 100644
--- a/blivet/tasks/availability.py
+++ b/blivet/tasks/availability.py
@@ -25,7 +25,7 @@ from distutils.spawn import find_executable
from six import add_metaclass
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/tasks/lukstasks.py b/blivet/tasks/lukstasks.py
index d32fe978..7814454f 100644
--- a/blivet/tasks/lukstasks.py
+++ b/blivet/tasks/lukstasks.py
@@ -20,7 +20,7 @@
# Red Hat Author(s): Anne Mulhern <amulhern@redhat.com>
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/tasks/pvtask.py b/blivet/tasks/pvtask.py
index a96d380d..2cb07a34 100644
--- a/blivet/tasks/pvtask.py
+++ b/blivet/tasks/pvtask.py
@@ -21,7 +21,7 @@
# Red Hat Author(s): Vojtěch Trefný <vtrefny@redhat.com>
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/util.py b/blivet/util.py
index 57f6372f..ba81bb6e 100644
--- a/blivet/util.py
+++ b/blivet/util.py
@@ -22,7 +22,7 @@ from enum import Enum
from .errors import DependencyError
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/blivet/zfcp.py b/blivet/zfcp.py
index 2381599c..0074c5dc 100644
--- a/blivet/zfcp.py
+++ b/blivet/zfcp.py
@@ -26,7 +26,7 @@ from .i18n import _
from .util import stringize, unicodeize
import gi
-gi.require_version("BlockDev", "2.0")
+gi.require_version("BlockDev", "1.0")
from gi.repository import BlockDev as blockdev
diff --git a/python-blivet.spec b/python-blivet.spec
index 0c3392c9..5e7bf8a1 100644
--- a/python-blivet.spec
+++ b/python-blivet.spec
@@ -19,7 +19,7 @@ Source0: http://github.com/storaged-project/blivet/archive/%{realname}-%{realver
%global partedver 1.8.1
%global pypartedver 3.10.4
%global utillinuxver 2.15.1
-%global libblockdevver 2.1
+%global libblockdevver 1.9
%global libbytesizever 0.3
%global pyudevver 0.18
--
2.20.1

@ -0,0 +1,34 @@
From 42d465514031eb083cac591327436ed6bca2b94c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Tue, 22 Oct 2019 15:07:01 +0200
Subject: [PATCH] Revert "Adapt to logging module name change"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
This reverts commit c367d62a516e541ad28636c8259321f1c53417ce.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
blivet/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/blivet/__init__.py b/blivet/__init__.py
index d5105842..ecaedad8 100644
--- a/blivet/__init__.py
+++ b/blivet/__init__.py
@@ -124,7 +124,7 @@ def enable_installer_mode():
from pyanaconda.constants import ROOT_PATH # pylint: disable=redefined-outer-name,no-name-in-module
_storage_root = _sysroot = ROOT_PATH
- from pyanaconda.anaconda_logging import program_log_lock
+ from pyanaconda.anaconda_log import program_log_lock
util.program_log_lock = program_log_lock
flags.installer_mode = True
--
2.20.1

@ -0,0 +1,52 @@
From 7a4cfbeb1f971d4968248a6002a365835f11c72e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Wed, 23 Oct 2019 00:21:02 +0200
Subject: [PATCH] Backport lvm thin pool metadata size functions from BlockDev
2.0
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Those are included only in BlockDev >= 2.0 API (libblockdev>=2.1), but
we don't have luxury of such new version. Since it's just one short
function and two constants, "copy" (translating from C) them directly
into blivet/devices/lvm.py.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
blivet/devices/lvm.py | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
index 39c6f342..94894272 100644
--- a/blivet/devices/lvm.py
+++ b/blivet/devices/lvm.py
@@ -56,6 +56,22 @@ from .dm import DMDevice
from .md import MDRaidArrayDevice
from .cache import Cache, CacheStats, CacheRequest
+# loose backport from BlockDev 2.0 interface
+LVM_DEFAULT_CHUNK_SIZE = 65536
+LVM_MIN_THPOOL_MD_SIZE = 2 * 2**20 # 2 MiB
+
+def get_thpool_meta_size(pool_size, block_size, max_thins):
+
+ command = ["thin_metadata_size",
+ "-ub", "-n",
+ "-b", str(int(block_size)),
+ "-s", str(int(pool_size)),
+ "-m", str(int(max_thins))]
+ (rc, out) = util.run_program_and_capture_output(command)
+ if rc:
+ raise Exception("thin_metadata_size failed with %d" % rc)
+ return max(int(out), LVM_MIN_THPOOL_MD_SIZE)
+
class LVPVSpec(object):
""" Class for specifying how much space on a PV should be allocated for some LV """
--
2.20.1

@ -0,0 +1,36 @@
From 2aeba92531b6146a760440f857d526ca7c19053e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Wed, 23 Oct 2019 00:23:10 +0200
Subject: [PATCH 2/2] Use local backport of BlockDev 2.0 interface
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
blivet/devices/lvm.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
index 15ddef74..da3dc853 100644
--- a/blivet/devices/lvm.py
+++ b/blivet/devices/lvm.py
@@ -1541,10 +1541,10 @@ class LVMThinPoolMixin(object):
# we need to know chunk size to calculate recommended metadata size
if self._chunk_size == 0:
- self._chunk_size = Size(blockdev.LVM_DEFAULT_CHUNK_SIZE)
+ self._chunk_size = Size(LVM_DEFAULT_CHUNK_SIZE)
log.debug("Using default chunk size: %s", self._chunk_size)
- self._metadata_size = Size(blockdev.lvm.get_thpool_meta_size(self._size,
+ self._metadata_size = Size( get_thpool_meta_size(self._size,
self._chunk_size,
100)) # snapshots
log.debug("Recommended metadata size: %s", self._metadata_size)
--
2.20.1

Binary file not shown.

File diff suppressed because it is too large Load Diff

@ -4,4 +4,3 @@ pykickstart
lorax-templates-qubes
livecd-tools
dracut-live
python3-jinja2

@ -1,7 +1,7 @@
# Full ISO build using packages from online repositories instead of local build
%include qubes-kickstart.cfg
repo --name=qubes-r4.1 --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.1-primary --baseurl=http://yum.qubes-os.org/r4.1/current-testing/dom0/fc31 --ignoregroups=true
repo --name=qubes-r4.1-templates-itl --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.1-primary --metalink=http://yum.qubes-os.org/r4.1/templates-itl/repodata/repomd.xml.metalink --ignoregroups=true
repo --name=qubes-r4.1-templates-community --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.1-templates-community --metalink=http://yum.qubes-os.org/r4.1/templates-community/repodata/repomd.xml.metalink --ignoregroups=true
repo --name=qubes-r4.0 --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.0-primary --baseurl=http://yum.qubes-os.org/r4.0/current-testing/dom0/fc25 --ignoregroups=true
repo --name=qubes-r4.0-templates-itl --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.0-primary --mirrorlist=http://yum.qubes-os.org/r4.0/templates-itl/repodata/repomd.xml.metalink --ignoregroups=true
repo --name=qubes-r4.0-templates-community --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.0-templates-community --mirrorlist=http://yum.qubes-os.org/r4.0/templates-community/repodata/repomd.xml.metalink --ignoregroups=true

@ -4,8 +4,8 @@
# (@base is added by default unless you add --nobase to %packages)
# (default groups for the configured repos are added by --default)
repo --name=fedora --gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-31-primary --ignoregroups=true --metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-31&arch=x86_64
repo --name=fedora-updates --gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-31-primary --ignoregroups=true --metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f31&arch=x86_64
repo --name=fedora --gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-25-primary --ignoregroups=true --mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=fedora-25&arch=$basearch
repo --name=fedora-updates --gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-25-primary --ignoregroups=true --mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f25&arch=$basearch
repo --name=installer --baseurl=file:///tmp/qubes-installer/yum/installer/
repo --name=qubes-dom0 --baseurl=file:///tmp/qubes-installer/yum/qubes-dom0/
repo --name=dom0-updates --baseurl=file:///tmp/qubes-installer/yum/dom0-updates/

@ -1,6 +1,6 @@
%include iso-full-online.ks
repo --name=qubes-r4.1-testing --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.1-primary --baseurl=http://yum.qubes-os.org/r4.1/current-testing/dom0/fc31 --ignoregroups=true
repo --name=qubes-r4.1-templates-itl-testing --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.1-primary --metalink=http://yum.qubes-os.org/r4.1/templates-itl-testing/repodata/repomd.xml.metalink --ignoregroups=true
repo --name=qubes-r4.1-templates-community-testing --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.1-templates-community --metalink=http://yum.qubes-os.org/r4.1/templates-community-testing/repodata/repomd.xml.metalink --ignoregroups=true
repo --name=qubes-r4.0-testing --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.0-primary --baseurl=http://yum.qubes-os.org/r4.0/current-testing/dom0/fc25 --ignoregroups=true
repo --name=qubes-r4.0-templates-itl-testing --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.0-primary --mirrorlist=http://yum.qubes-os.org/r4.0/templates-itl-testing/repodata/repomd.xml.metalink --ignoregroups=true
repo --name=qubes-r4.0-templates-community-testing --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.0-templates-community --mirrorlist=http://yum.qubes-os.org/r4.0/templates-community-testing/repodata/repomd.xml.metalink --ignoregroups=true

@ -1,4 +1,3 @@
%include travis-iso.ks
# unsigned package to be downladed by pungi
repo --name=unsigned --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-3.1-primary --baseurl=http://ftp.qubes-os.org/~marmarek/repo-verify-unsigned --ignoregroups=true

@ -1,4 +0,0 @@
%include travis-iso.ks
# unsigned package to be downladed by lorax
repo --name=unsigned2 --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-3.1-primary --baseurl=http://ftp.qubes-os.org/~marmarek/repo-verify-unsigned2 --ignoregroups=true

@ -1,3 +1,3 @@
%include qubes-kickstart.cfg
repo --name=qubes-r4.1-testing --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.1-primary --baseurl=http://yum.qubes-os.org/r4.1/current-testing/dom0/fc31 --ignoregroups=true
repo --name=qubes-r4.0-testing --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.0-primary --baseurl=http://yum.qubes-os.org/r4.0/current-testing/dom0/fc25 --ignoregroups=true

@ -0,0 +1,44 @@
Name: lorax-templates-qubes
Version: 4.0.6
Release: 1%{?dist}
Summary: Lorax templates for Qubes installation ISO
Group: Applications/System
License: GPLv2+
URL: http://www.qubes-os.org/
Source0: %{name}-%{version}.tar.bz2
#BuildRequires:
Requires: lorax
BuildArch: noarch
%description
Lorax templates for Qubes installation ISO.
%prep
%setup -q
%install
rm -rf $RPM_BUILD_ROOT
install -d $RPM_BUILD_ROOT/usr/share/lorax-qubes
cp -r templates/* $RPM_BUILD_ROOT/usr/share/lorax-qubes/
%post
# pungi does not allow to specify alternative config, so must override the default one
if [ -r /etc/lorax/lorax.conf -a ! -r /etc/lorax/lorax-pre-qubes.conf ]; then
mv /etc/lorax/lorax.conf /etc/lorax/lorax-pre-qubes.conf
fi
cat > /etc/lorax/lorax.conf << EOF
# Lorax configuration file
[lorax]
sharedir: /usr/share/lorax-qubes
EOF
%files
%defattr(-,root,root,-)
/usr/share/lorax-qubes
%changelog

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<image>
<name>${name}</name>
<domain>
<boot type='hvm'>
<guest>
<arch>${arch}</arch>
</guest>
<os>
<loader dev='hd'/>
</os>
%for disk, letter in zip(disks, xrange(97, 123)):
<drive disk='${disk.name}' target='hd${chr(letter)}'/>
%endfor
</boot>
<devices>
<vcpu>${vcpus}</vcpu>
<memory>${memory}</memory>
%for net in networks:
<interface/>
%endfor
<graphics/>
</devices>
</domain>
<storage>
%for disk in disks:
<disk file='${disk.name}' use='system' format='${disk.format}'>
%if disk.checksum:
<checksum type='${disk.checksum_type}'>${disk.checksum}</checksum>
%endif
</disk>
%endfor
</storage>
</image>

@ -0,0 +1,92 @@
<%page args="kernels, runtime_img, runtime_base, basearch, outroot, arch"/>
<%
configdir="tmp/config_files/uboot"
PXEBOOTDIR="images/pxeboot"
BOOTDIR="boot"
KERNELDIR=PXEBOOTDIR
LIVEDIR="LiveOS"
# different platforms use different kernel load addresses.
# include a 'baseline' kernel for no 'flavor'.
kernelAddress = { 'baseline' : '0x00008000',
'highbank' : '0x00008000',
'imx' : '0x90008000',
'kirkwood' : '0x00008000',
'mvebu' : '0x00008000',
'omap' : '0x80008000',
'tegra' : '0x00008000',
}
%>
mkdir ${LIVEDIR}
install ${runtime_img} ${LIVEDIR}/squashfs.img
treeinfo stage2 mainimage ${LIVEDIR}/squashfs.img
# Add platforms to treeinfo for Beaker support.
treeinfo ${basearch} platforms highbank,imx,mvebu,omap,tegra
## install kernels
mkdir ${KERNELDIR}
%for kernel in kernels:
%if kernel.flavor:
installkernel images-${kernel.flavor}-${basearch} ${kernel.path} ${KERNELDIR}/vmlinuz-${kernel.flavor}
installinitrd images-${kernel.flavor}-${basearch} ${kernel.initrd.path} ${KERNELDIR}/initrd-${kernel.flavor}.img
%if doupgrade:
## install upgrade image
installupgradeinitrd images-${kernel.flavor}-${basearch} ${kernel.upgrade.path} ${KERNELDIR}/upgrade-${kernel.flavor}.img
%endif
## create U-Boot wrapped images
runcmd mkimage \
-A arm -O linux -T ramdisk -C none \
-a 0 -e 0 \
-n "${product.name} ${product.version} ${kernel.flavor} ${kernel.arch}" \
-d ${outroot}/${KERNELDIR}/initrd-${kernel.flavor}.img \
${outroot}/${KERNELDIR}/uInitrd-${kernel.flavor}
runcmd mkimage \
-A arm -O linux -T kernel -C none \
-a ${kernelAddress[kernel.flavor]} -e ${kernelAddress[kernel.flavor]} \
-n "${product.name} ${product.version} ${kernel.flavor} ${kernel.arch}" \
-d ${outroot}/${KERNELDIR}/vmlinuz-${kernel.flavor} \
${outroot}/${KERNELDIR}/uImage-${kernel.flavor}
treeinfo images-${kernel.flavor}-${basearch} uimage ${KERNELDIR}/uImage-${kernel.flavor}
treeinfo images-${kernel.flavor}-${basearch} uinitrd ${KERNELDIR}/uInitrd-${kernel.flavor}
%else:
installkernel images-${basearch} ${kernel.path} ${KERNELDIR}/vmlinuz
installinitrd images-${basearch} ${kernel.initrd.path} ${KERNELDIR}/initrd.img
%if doupgrade:
## install upgrade image
installupgradeinitrd images-${basearch} ${kernel.upgrade.path} ${KERNELDIR}/upgrade.img
%endif
## create U-Boot wrapped images
runcmd mkimage \
-A arm -O linux -T ramdisk -C none \
-a 0 -e 0 \
-n "${product.name} ${product.version} ${kernel.arch}" \
-d ${outroot}/${KERNELDIR}/initrd.img \
${outroot}/${KERNELDIR}/uInitrd
runcmd mkimage \
-A arm -O linux -T kernel -C none \
-a ${kernelAddress['baseline']} -e ${kernelAddress['baseline']} \
-n "${product.name} ${product.version} ${kernel.arch}" \
-d ${outroot}/${KERNELDIR}/vmlinuz \
${outroot}/${KERNELDIR}/uImage
treeinfo images-${basearch} uimage ${KERNELDIR}/uImage
treeinfo images-${basearch} uinitrd ${KERNELDIR}/uInitrd
%endif
%endfor
## FIXME: ARM may need some extra boot config

@ -0,0 +1,5 @@
splash.lss
- Press the 01<ENTER>07 key to begin the installation process.

@ -0,0 +1,13 @@
#debug --graphics
default=0
splashimage=@SPLASHPATH@
timeout 5
hiddenmenu
title Install @PRODUCT@ @VERSION@
findiso
kernel @KERNELPATH@ @ROOT@ quiet
initrd @INITRDPATH@
title Test this media & install @PRODUCT@ @VERSION@
findiso
kernel @KERNELPATH@ @ROOT@ rd.live.check quiet
initrd @INITRDPATH@

@ -0,0 +1,46 @@
set default="1"
function load_video {
if [ x$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
}
load_video
set gfxpayload=keep
insmod gzio
insmod part_gpt
insmod ext2
set timeout=60
### END /etc/grub.d/00_header ###
search --no-floppy --set=root -l '@ISOLABEL@'
### BEGIN /etc/grub.d/10_linux ###
menuentry 'Install @PRODUCT@ @VERSION@' --class red --class gnu-linux --class gnu --class os {
linux @KERNELPATH@ @ROOT@ ro
initrd @INITRDPATH@
}
menuentry 'Test this media & install @PRODUCT@ @VERSION@' --class red --class gnu-linux --class gnu --class os {
linux @KERNELPATH@ @ROOT@ rd.live.check
initrd @INITRDPATH@
}
submenu 'Troubleshooting -->' {
menuentry 'Install @PRODUCT@ @VERSION@ in basic graphics mode' --class red --class gnu-linux --class gnu --class os {
linux @KERNELPATH@ @ROOT@ nomodeset
initrd @INITRDPATH@
}
menuentry 'Rescue a @PRODUCT@ system' --class red --class gnu-linux --class gnu --class os {
linux @KERNELPATH@ @ROOT@ rescue
initrd @INITRDPATH@
}
}

@ -0,0 +1,11 @@
kill -USR1 `cat /var/run/anaconda.pid`
kill -USR2 `cat /var/run/anaconda.pid`
kill -HUP `cat /var/run/anaconda.pid`
udevadm info --export-db | less
tail -f /tmp/storage.log
echo b > /proc/sysrq-trigger
dmsetup table
multipath -d
HOME=/root chroot /mnt/sysimage bash -l -i
less /tmp/anaconda.log
grep -v _yum_lock /tmp/packaging.log

@ -0,0 +1,10 @@
[defaults]
skeleton = /mnt/sysimage/etc/skel
mailspooldir = /mnt/sysimage/var/mail
crypt_style = md5
modules = files shadow
create_modules = files shadow
[files]
directory = /mnt/sysimage/etc
[shadow]
directory = /mnt/sysimage/etc

@ -0,0 +1,4 @@
[org.gnome.desktop.wm.preferences]
button-layout=':'
action-right-click-titlebar='none'
num-workspaces=1

@ -0,0 +1,2 @@
[org.gtk.Settings.Debug]
enable-inspector-keybinding=true

@ -0,0 +1,9 @@
#%PAM-1.0
auth required pam_env.so
auth sufficient pam_unix.so likeauth nullok
auth required pam_deny.so
account required pam_unix.so
password sufficient pam_unix.so nullok use_authtok md5 shadow
password required pam_deny.so
session required pam_limits.so
session required pam_unix.so

@ -0,0 +1,3 @@
PS1="[anaconda \u@\h \W]\\$ "
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/mnt/sysimage/sbin:/mnt/sysimage/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin
export PATH PS1

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save