Compare commits
25 Commits
master
...
v25.20.9-1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9593f58731 | ||
![]() |
9c8a8d2fb4 | ||
![]() |
967c9caa7c | ||
![]() |
87116a2094 | ||
![]() |
32b3a210e0 | ||
![]() |
556b584f74 | ||
![]() |
0ec125b967 | ||
![]() |
91728177c2 | ||
![]() |
12cc054a74 | ||
![]() |
1abde9cad3 | ||
![]() |
40a1574500 | ||
![]() |
7c2d9b37e3 | ||
![]() |
70d4252d91 | ||
![]() |
a089792060 | ||
![]() |
3541eda275 | ||
![]() |
533e8e75bd | ||
![]() |
f3f7ae7a87 | ||
![]() |
afd1fe2d41 | ||
![]() |
60af84f159 | ||
![]() |
3c12390129 | ||
![]() |
2ce7edc6fe | ||
![]() |
beb177026c | ||
![]() |
c92b713f9f | ||
![]() |
cfe1e28266 | ||
![]() |
e574ea6c3c |
@ -1,5 +1,5 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
dist: bionic
|
||||
language: generic
|
||||
install: git clone https://github.com/QubesOS/qubes-builder ~/qubes-builder
|
||||
script:
|
||||
|
3
Makefile
3
Makefile
@ -59,7 +59,8 @@ iso-installer: iso-prepare
|
||||
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 work/$(ISO_VERSION)/x86_64/iso/*-DVD*.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
|
||||
chown --reference=Makefile -R build yum
|
||||
|
@ -17,7 +17,7 @@ new file mode 100644
|
||||
index 000000000..e98912b63
|
||||
--- /dev/null
|
||||
+++ b/pyanaconda/installclasses/qubes.py
|
||||
@@ -0,0 +1,93 @@
|
||||
@@ -0,0 +1,89 @@
|
||||
+#
|
||||
+# qubes.py
|
||||
+#
|
||||
@ -92,10 +92,6 @@ index 000000000..e98912b63
|
||||
+ storage.autopart_requests.remove(autoreq)
|
||||
+ if autoreq.mountpoint == "/boot/efi":
|
||||
+ autoreq.max_size=Size("500MiB")
|
||||
+ if autoreq.mountpoint == "/boot" and \
|
||||
+ isinstance(platform, blivet.platform.EFI):
|
||||
+ # xen.efi don't need /boot
|
||||
+ storage.autopart_requests.remove(autoreq)
|
||||
+
|
||||
+ def productMatches(self, oldprod):
|
||||
+ if oldprod is None:
|
||||
|
@ -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
|
||||
|
@ -3,7 +3,7 @@
|
||||
Summary: Graphical system installer
|
||||
Name: anaconda
|
||||
Version: 25.20.9
|
||||
Release: 14%{?dist}
|
||||
Release: 17%{?dist}
|
||||
License: GPLv2+ and MIT
|
||||
Epoch: 1000
|
||||
Group: Applications/System
|
||||
@ -74,6 +74,9 @@ Patch53: 0053-anaconda-require-user-password-being-set.patch
|
||||
Patch54: 0054-anaconda-abort-installation-on-X-startup-fail.patch
|
||||
Patch55: 0055-anaconda-fix-encryption-passphrase-check.patch
|
||||
Patch56: 0056-anaconda-disable-os-prober.patch
|
||||
Patch57: 0057-Add-plymouth.ignore-serial-consoles-boot-option-by-d.patch
|
||||
Patch58: 0058-Report-20-space-needed-for-LVM-thin-provisioning.patch
|
||||
Patch59: 0059-Do-not-require-user-setup-during-automated-kickseede.patch
|
||||
|
||||
# Versions of required components (done so we make sure the buildrequires
|
||||
# match the requires versions of things).
|
||||
|
47
blivet/0001-Avoid-mounting-pre-existing-disks.patch
Normal file
47
blivet/0001-Avoid-mounting-pre-existing-disks.patch
Normal file
@ -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
|
||||
|
@ -1,44 +0,0 @@
|
||||
From a43dc757eff7fe9417f72e25fc373d09439963de Mon Sep 17 00:00:00 2001
|
||||
From: Vratislav Podzimek <vpodzime@redhat.com>
|
||||
Date: Fri, 18 Nov 2016 14:01:49 +0100
|
||||
Subject: [PATCH 1/2] Change how we run e2fsck to check ext filesystems
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The '-p' option means "Automatically repair ("preen") the file system. This
|
||||
option will cause e2fsck to automatically fix any filesystem problems that can
|
||||
be safely fixed without human intervention." which is something we really
|
||||
shouldn't do as part of reset()/populate(). We should use '-n' instead "Open the
|
||||
filesystem read-only, and assume an answer of `no' to all questions." which
|
||||
guaranties no changes to be made on the file system.
|
||||
|
||||
We might want to add the '-p' functionality back at some point, but it needs to
|
||||
be explicitly triggered by the user code (e.g. Anaconda). I think we need to add
|
||||
a 'clean' property and a 'repair' method to the formats.FS class so that users
|
||||
can see where the problem is (if any) and explicitly trigger a safe fixup
|
||||
attempt if they want to.
|
||||
|
||||
Related: rhbz#1170803
|
||||
---
|
||||
blivet/tasks/fsck.py | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/blivet/tasks/fsck.py b/blivet/tasks/fsck.py
|
||||
index a3ed775..c4214dc 100644
|
||||
--- a/blivet/tasks/fsck.py
|
||||
+++ b/blivet/tasks/fsck.py
|
||||
@@ -114,7 +114,9 @@ class Ext2FSCK(FSCK):
|
||||
128: "Shared library error."}
|
||||
|
||||
ext = availability.E2FSCK_APP
|
||||
- options = ["-f", "-p", "-C", "0"]
|
||||
+ # "Force checking even if the file system seems clean." (we might get false results otherwise)
|
||||
+ # + "Open the filesystem read-only, and assume an answer of `no' to all questions."
|
||||
+ options = ["-f", "-n"]
|
||||
|
||||
def _error_message(self, rc):
|
||||
msgs = (self._fsck_errors[c] for c in self._fsck_errors.keys() if rc & c)
|
||||
--
|
||||
2.7.5
|
||||
|
@ -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
|
||||
|
@ -1,47 +0,0 @@
|
||||
From d08d99dfb766e539b9e0074643ab3bc940d6fcee Mon Sep 17 00:00:00 2001
|
||||
From: Adam Williamson <awilliam@redhat.com>
|
||||
Date: Thu, 10 Nov 2016 11:34:24 -0800
|
||||
Subject: [PATCH] Fix detection of 'macefi' partitions (#1393846)
|
||||
|
||||
368a4db6 lost a crucial condition in the detection of 'macefi'
|
||||
partitions in the transition to the 'populator helper' design.
|
||||
Previously we checked that the parted partition 'name' (which
|
||||
is a GPT property, for GPT partitions) matched the expected
|
||||
value according to the macefi format, which basically means we
|
||||
will only detect partitions created by a previous anaconda run
|
||||
as 'macefi' (because that name is a very specific one which is
|
||||
only created by anaconda in the first place).
|
||||
|
||||
In the transition, that condition was lost, and now we treat
|
||||
any device with an HFS+ filesystem that's over 50MiB in size
|
||||
as a 'macefi' device, which means we mount it at /boot/efi and
|
||||
try to write all kinds of stuff to it. Not surprisingly, this
|
||||
borks the install. Fortunately, HFS+ filesystems are mounted
|
||||
read-only unless they have journalling disabled, so this won't
|
||||
result in us messing up people's OS X partitions with any luck.
|
||||
---
|
||||
blivet/populator/helpers/boot.py | 10 ++++++++++
|
||||
tests/populator_test.py | 33 +++++++++++++++++++++++++++++++++
|
||||
2 files changed, 43 insertions(+)
|
||||
|
||||
diff --git a/blivet/populator/helpers/boot.py b/blivet/populator/helpers/boot.py
|
||||
index b679b3b..3d80dd2 100644
|
||||
--- a/blivet/populator/helpers/boot.py
|
||||
+++ b/blivet/populator/helpers/boot.py
|
||||
@@ -54,6 +54,16 @@ class MacEFIFormatPopulator(BootFormatPopulator):
|
||||
_type_specifier = "macefi"
|
||||
_base_type_specifier = "hfsplus"
|
||||
|
||||
+ @classmethod
|
||||
+ def match(cls, data, device):
|
||||
+ fmt = formats.get_format(cls._type_specifier)
|
||||
+ try:
|
||||
+ return (super().match(data, device) and
|
||||
+ device.parted_partition.name == fmt.name)
|
||||
+ except AttributeError:
|
||||
+ # just in case device.parted_partition has no name attr
|
||||
+ return False
|
||||
+
|
||||
|
||||
class AppleBootFormatPopulator(BootFormatPopulator):
|
||||
_type_specifier = "appleboot"
|
@ -1,34 +0,0 @@
|
||||
From 7a9697eae467fc0ed44022d948f70f30d156d69e Mon Sep 17 00:00:00 2001
|
||||
From: Adam Williamson <adamw@fedoraproject.org>
|
||||
Date: Fri, 11 Nov 2016 12:36:12 -0500
|
||||
Subject: [PATCH] Fix "unknown" SAS device sysfs parsing.
|
||||
|
||||
Since the regexp matches the device type as well as the identifying
|
||||
numbers, we need to pull the numbers from match groups 2 and 3, not 1
|
||||
and 2.
|
||||
|
||||
Resolves: rhbz#1394026
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
blivet/devicelibs/edd.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/blivet/devicelibs/edd.py b/blivet/devicelibs/edd.py
|
||||
index 7a1a1e2..51b7ed8 100644
|
||||
--- a/blivet/devicelibs/edd.py
|
||||
+++ b/blivet/devicelibs/edd.py
|
||||
@@ -316,8 +316,8 @@ class EddEntry(object):
|
||||
self.sas_address = int(sas_match.group(1), base=16)
|
||||
self.sas_lun = int(sas_match.group(2), base=16)
|
||||
elif unknown_match:
|
||||
- self.sas_address = int(unknown_match.group(1), base=16)
|
||||
- self.sas_lun = int(unknown_match.group(2), base=16)
|
||||
+ self.sas_address = int(unknown_match.group(2), base=16)
|
||||
+ self.sas_lun = int(unknown_match.group(3), base=16)
|
||||
else:
|
||||
log.warning("edd: can not match interface for %s: %s",
|
||||
self.sysfspath, interface)
|
||||
--
|
||||
2.7.4
|
||||
|
@ -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
|
||||
|
@ -1,28 +0,0 @@
|
||||
From cf32290dd3a0561585837fddfcdb08b3389f356a Mon Sep 17 00:00:00 2001
|
||||
From: Adam Williamson <awilliam@redhat.com>
|
||||
Date: Wed, 26 Oct 2016 16:17:46 -0700
|
||||
Subject: [PATCH 1/4] Use correct type for port in GVariant tuple
|
||||
|
||||
The type is `(sqa{sv})`, where `q` (according to the docs) is
|
||||
"an unsigned 16 bit integer", so this should be an int, not a
|
||||
string.
|
||||
---
|
||||
blivet/iscsi.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/blivet/iscsi.py b/blivet/iscsi.py
|
||||
index 8773509..14c4b9a 100644
|
||||
--- a/blivet/iscsi.py
|
||||
+++ b/blivet/iscsi.py
|
||||
@@ -369,7 +369,7 @@ class iSCSI(object):
|
||||
if r_password:
|
||||
auth_info["r_password"] = GLib.Variant("s", r_password)
|
||||
|
||||
- args = GLib.Variant("(sqa{sv})", (ipaddr, port, auth_info))
|
||||
+ args = GLib.Variant("(sqa{sv})", (ipaddr, int(port), auth_info))
|
||||
nodes, _n_nodes = self._call_initiator_method("DiscoverSendTargets", args)
|
||||
|
||||
found_nodes = _to_node_infos(nodes)
|
||||
--
|
||||
2.7.4
|
||||
|
@ -1,84 +0,0 @@
|
||||
From 32ba44edfa5cd4424154396b877cd5ad75e8c999 Mon Sep 17 00:00:00 2001
|
||||
From: Vratislav Podzimek <vpodzime@redhat.com>
|
||||
Date: Tue, 22 Nov 2016 08:52:34 +0100
|
||||
Subject: [PATCH 2/2] Do not run FS check as part of updating (re)size info
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If the FS tools tell us the minimum size of the file system we are supposed to
|
||||
(see rhbz#1170803) consider that an evidence of the file system being in a good
|
||||
enough shape to be resized.
|
||||
|
||||
Resolves: rhbz#1170803
|
||||
---
|
||||
blivet/formats/fs.py | 44 ++++++++++++++++++--------------------------
|
||||
1 file changed, 18 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py
|
||||
index 203926e..100bfce 100644
|
||||
--- a/blivet/formats/fs.py
|
||||
+++ b/blivet/formats/fs.py
|
||||
@@ -296,8 +296,6 @@ class FS(DeviceFormat):
|
||||
""" Update this filesystem's current and minimum size (for resize). """
|
||||
|
||||
# This method ensures:
|
||||
- # * If there are fsck errors, self._resizable is False.
|
||||
- # Note that if there is no fsck program, no errors are possible.
|
||||
# * If it is not possible to obtain the current size of the
|
||||
# filesystem by interrogating the filesystem, self._resizable
|
||||
# is False (and self._size is 0).
|
||||
@@ -317,32 +315,26 @@ class FS(DeviceFormat):
|
||||
self._min_instance_size = Size(0)
|
||||
self._resizable = self.__class__._resizable
|
||||
|
||||
- # We can't allow resize if the filesystem has errors.
|
||||
+ # try to gather current size info
|
||||
+ self._size = Size(0)
|
||||
try:
|
||||
- self.do_check()
|
||||
- except FSError:
|
||||
+ if self._info.available:
|
||||
+ self._current_info = self._info.do_task()
|
||||
+ except FSError as e:
|
||||
+ log.info("Failed to obtain info for device %s: %s", self.device, e)
|
||||
+ try:
|
||||
+ self._size = self._size_info.do_task()
|
||||
+ except (FSError, NotImplementedError) as e:
|
||||
+ log.warning("Failed to obtain current size for device %s: %s", self.device, e)
|
||||
+ else:
|
||||
+ self._min_instance_size = self._size
|
||||
+
|
||||
+ # We absolutely need a current size to enable resize. To shrink the
|
||||
+ # filesystem we need a real minimum size provided by the resize
|
||||
+ # tool. Failing that, we can default to the current size,
|
||||
+ # effectively disabling shrink.
|
||||
+ if self._size == Size(0):
|
||||
self._resizable = False
|
||||
- raise
|
||||
- finally:
|
||||
- # try to gather current size info anyway
|
||||
- self._size = Size(0)
|
||||
- try:
|
||||
- if self._info.available:
|
||||
- self._current_info = self._info.do_task()
|
||||
- except FSError as e:
|
||||
- log.info("Failed to obtain info for device %s: %s", self.device, e)
|
||||
- try:
|
||||
- self._size = self._size_info.do_task()
|
||||
- self._min_instance_size = self._size
|
||||
- except (FSError, NotImplementedError) as e:
|
||||
- log.warning("Failed to obtain current size for device %s: %s", self.device, e)
|
||||
-
|
||||
- # We absolutely need a current size to enable resize. To shrink the
|
||||
- # filesystem we need a real minimum size provided by the resize
|
||||
- # tool. Failing that, we can default to the current size,
|
||||
- # effectively disabling shrink.
|
||||
- if self._size == Size(0):
|
||||
- self._resizable = False
|
||||
|
||||
try:
|
||||
result = self._minsize.do_task()
|
||||
--
|
||||
2.7.5
|
||||
|
@ -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
|
||||
|
@ -1,122 +0,0 @@
|
||||
From 5eaadad9218210ed2a616104a6e56665c38f9277 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Williamson <awilliam@redhat.com>
|
||||
Date: Wed, 26 Oct 2016 20:42:53 -0700
|
||||
Subject: [PATCH 2/4] iSCSI: Store auth info in NodeInfo tuples
|
||||
|
||||
This seems to have been overlooked in 9280eff7 . When we were
|
||||
using libiscsi, the `node` objects were `PyIscsiNode` instances
|
||||
(I think), with `getAuth` and `setAuth` methods that let you
|
||||
read and set the authentication information for the node. We
|
||||
used `getAuth` in `iScsiDiskDevice.dracut_setup_args()` to
|
||||
include the auth information in the `netroot` arg. anaconda
|
||||
also expects the `node` attribute of an `iScsiDiskDevice`
|
||||
instance to be a `PyIscsiNode` and calls its `getAuth` method
|
||||
to populate the kickstart data for the node.
|
||||
|
||||
When we ditched libiscsi and turned the `node` objects into
|
||||
`NodeInfo` namedtuples, this was missed and not handled at all.
|
||||
Both blivet and anaconda are still trying to call methods that
|
||||
these node objects just don't have any more. The blivet call
|
||||
was changed from `getAuth()` to `get_auth()` in 4e8f941b , but
|
||||
apparently whoever did that didn't notice that neither method
|
||||
exists at all for these objects any more...
|
||||
|
||||
Here's my attempt to fix this: basically, just stuff the auth
|
||||
information into the `NodeInfo` instances when we log in. I
|
||||
thought of several different ways to do this, but I think in
|
||||
the end it always has to boil down to storing the auth details
|
||||
on the node object when we log in, so let's just go with the
|
||||
obvious way. We could mimic the `getAuth` and `setAuth` methods
|
||||
pretty easily for 'compatibility', but it doesn't seem worth
|
||||
it, we'd probably still be missing other bits of the interface.
|
||||
---
|
||||
blivet/devices/disk.py | 11 +++++------
|
||||
blivet/iscsi.py | 33 +++++++++++++++++++++++++++++++--
|
||||
2 files changed, 36 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/blivet/devices/disk.py b/blivet/devices/disk.py
|
||||
index 6880e1e..acf31ee 100644
|
||||
--- a/blivet/devices/disk.py
|
||||
+++ b/blivet/devices/disk.py
|
||||
@@ -452,12 +452,11 @@ class iScsiDiskDevice(DiskDevice, NetworkStorageDevice):
|
||||
address = "[%s]" % address
|
||||
|
||||
netroot = "netroot=iscsi:"
|
||||
- auth = self.node.get_auth()
|
||||
- if auth:
|
||||
- netroot += "%s:%s" % (auth.username, auth.password)
|
||||
- if len(auth.reverse_username) or len(auth.reverse_password):
|
||||
- netroot += ":%s:%s" % (auth.reverse_username,
|
||||
- auth.reverse_password)
|
||||
+ if self.node.username and self.node.password:
|
||||
+ netroot += "%s:%s" % (self.node.username, self.node.password)
|
||||
+ if self.node.r_username and self.node.r_password:
|
||||
+ netroot += ":%s:%s" % (self.node.r_username,
|
||||
+ self.node.r_password)
|
||||
|
||||
iface_spec = ""
|
||||
if self.nic != "default":
|
||||
diff --git a/blivet/iscsi.py b/blivet/iscsi.py
|
||||
index 14c4b9a..1969fc8 100644
|
||||
--- a/blivet/iscsi.py
|
||||
+++ b/blivet/iscsi.py
|
||||
@@ -66,10 +66,31 @@ def has_iscsi():
|
||||
return True
|
||||
|
||||
|
||||
-NodeInfo = namedtuple("NodeInfo", ["name", "tpgt", "address", "port", "iface"])
|
||||
TargetInfo = namedtuple("TargetInfo", ["ipaddr", "port"])
|
||||
|
||||
|
||||
+class NodeInfo(object):
|
||||
+ """Simple representation of node information."""
|
||||
+ def __init__(self, name, tpgt, address, port, iface):
|
||||
+ self.name = name
|
||||
+ self.tpgt = tpgt
|
||||
+ self.address = address
|
||||
+ self.port = port
|
||||
+ self.iface = iface
|
||||
+ # These get set by log_into_node, but *NOT* _login
|
||||
+ self.username = None
|
||||
+ self.password = None
|
||||
+ self.r_username = None
|
||||
+ self.r_password = None
|
||||
+
|
||||
+ @property
|
||||
+ def conn_info(self):
|
||||
+ """The 5-tuple of connection info (no auth info). This form
|
||||
+ is useful for interacting with storaged.
|
||||
+ """
|
||||
+ return (self.name, self.tpgt, self.address, self.port, self.iface)
|
||||
+
|
||||
+
|
||||
class LoginInfo(object):
|
||||
def __init__(self, node, logged_in):
|
||||
self.node = node
|
||||
@@ -239,7 +260,7 @@ class iSCSI(object):
|
||||
extra = dict()
|
||||
extra["node.startup"] = GLib.Variant("s", "automatic")
|
||||
|
||||
- args = GLib.Variant("(sisisa{sv})", tuple(list(node_info) + [extra]))
|
||||
+ args = GLib.Variant("(sisisa{sv})", node_info.conn_info + (extra,))
|
||||
self._call_initiator_method("Login", args)
|
||||
|
||||
@storaged_iscsi_required(critical=False, eval_mode=util.EvalMode.onetime)
|
||||
@@ -414,6 +435,14 @@ class iSCSI(object):
|
||||
node.name, node.address, node.port, node.iface)
|
||||
if not self._mark_node_active(node):
|
||||
log.error("iSCSI: node not found among discovered")
|
||||
+ if username:
|
||||
+ node.username = username
|
||||
+ if password:
|
||||
+ node.password = password
|
||||
+ if r_username:
|
||||
+ node.r_username = r_username
|
||||
+ if r_password:
|
||||
+ node.r_password = r_password
|
||||
except safe_dbus.DBusCallError as e:
|
||||
msg = str(e)
|
||||
log.warning("iSCSI: could not log into %s: %s", node.name, msg)
|
||||
--
|
||||
2.7.4
|
||||
|
34
blivet/0003-Revert-Adapt-to-logging-module-name-change.patch
Normal file
34
blivet/0003-Revert-Adapt-to-logging-module-name-change.patch
Normal file
@ -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
|
||||
|
@ -1,71 +0,0 @@
|
||||
From 4d0b9f8338bfc1634340bb191058b888094ca81d Mon Sep 17 00:00:00 2001
|
||||
From: Adam Williamson <awilliam@redhat.com>
|
||||
Date: Thu, 27 Oct 2016 15:17:29 -0700
|
||||
Subject: [PATCH 3/4] iSCSI: turn `iscsi.initiator_set` into a property
|
||||
|
||||
The iSCSI class has an `initiator_set` attribute whose meaning
|
||||
feels a bit slippery these days. It has always been set to
|
||||
True in `__init__()` if iBFT is active, right after we get the
|
||||
initiator name from the firmware. Prior to 9280eff7, it was
|
||||
also set true by `startup()` after it wrote out INITIATOR_FILE.
|
||||
In 9280eff7, that was removed, without any kind of replacement.
|
||||
Now `initiator_set` will never be True unless iBFT is being
|
||||
used.
|
||||
|
||||
This is a problem because `iscsi.write()` checks if it's True,
|
||||
and immediately bails if it isn't. The result of this is that
|
||||
when you do an iSCSI install with anaconda, the contents of
|
||||
`/var/lib/iscsi` from the installer environment are no longer
|
||||
copied in the installed system.
|
||||
|
||||
vpodzime asked for this fix: making it into a property which
|
||||
returns True if `self._initiator` is set, otherwise False.
|
||||
I used `== ""` as the test because that's what we use in other
|
||||
places, though in my own code I'd normally just use
|
||||
`if self._initiator:`.
|
||||
|
||||
Note that `if iscsi.initiator_set:` and `if iscsi.initiator:`
|
||||
are not quite equivalent, as the `initiator` property will try
|
||||
and read the initiator name from storaged if `self._initiator`
|
||||
is not set, but `initiator_set` will not. This best matches
|
||||
the previous behaviour, but I'm not sure if all of this makes
|
||||
any logical sense when considered from scratch.
|
||||
---
|
||||
blivet/iscsi.py | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/blivet/iscsi.py b/blivet/iscsi.py
|
||||
index 1969fc8..b221fd4 100644
|
||||
--- a/blivet/iscsi.py
|
||||
+++ b/blivet/iscsi.py
|
||||
@@ -149,7 +149,6 @@ class iSCSI(object):
|
||||
# This list contains nodes discovered through iBFT (or other firmware)
|
||||
self.ibft_nodes = []
|
||||
self._initiator = ""
|
||||
- self.initiator_set = False
|
||||
self.started = False
|
||||
self.ifaces = {}
|
||||
|
||||
@@ -159,7 +158,6 @@ class iSCSI(object):
|
||||
try:
|
||||
initiatorname = self._call_initiator_method("GetFirmwareInitiatorName")[0]
|
||||
self._initiator = initiatorname
|
||||
- self.initiator_set = True
|
||||
except Exception: # pylint: disable=broad-except
|
||||
log_exception_info(fmt_str="failed to get initiator name from iscsi firmware")
|
||||
|
||||
@@ -197,6 +195,11 @@ class iSCSI(object):
|
||||
connection=self._connection)
|
||||
|
||||
@property
|
||||
+ def initiator_set(self):
|
||||
+ """True if initiator is set at our level."""
|
||||
+ return self._initiator != ""
|
||||
+
|
||||
+ @property
|
||||
@storaged_iscsi_required(critical=False, eval_mode=util.EvalMode.onetime)
|
||||
def initiator(self):
|
||||
if self._initiator != "":
|
||||
--
|
||||
2.7.4
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 274b0bfb6aa923a82662e754030ebce4d8694901 Mon Sep 17 00:00:00 2001
|
||||
From: Vratislav Podzimek <vpodzime@redhat.com>
|
||||
Date: Thu, 3 Nov 2016 12:53:03 +0100
|
||||
Subject: [PATCH 4/4] Add device symlinks to the PVs dictionary for MD RAID PVs
|
||||
(#1389130)
|
||||
|
||||
Otherwise if the symlink is used to search for the PV info, it's not found and
|
||||
everything on that PV is ignored which leads e.g. to issues when removing the PV
|
||||
(as described in the bug) and others.
|
||||
---
|
||||
blivet/static_data/lvm_info.py | 18 +++++++++++++++++-
|
||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/blivet/static_data/lvm_info.py b/blivet/static_data/lvm_info.py
|
||||
index ed2e995..4f5a274 100644
|
||||
--- a/blivet/static_data/lvm_info.py
|
||||
+++ b/blivet/static_data/lvm_info.py
|
||||
@@ -57,7 +57,23 @@ class PVsInfo(object):
|
||||
def cache(self):
|
||||
if self._pvs_cache is None:
|
||||
pvs = blockdev.lvm.pvs()
|
||||
- self._pvs_cache = dict((pv.pv_name, pv) for pv in pvs) # pylint: disable=attribute-defined-outside-init
|
||||
+ self._pvs_cache = dict() # pylint: disable=attribute-defined-outside-init
|
||||
+ for pv in pvs:
|
||||
+ self._pvs_cache[pv.pv_name] = pv
|
||||
+ # TODO: add get_all_device_symlinks() and resolve_device_symlink() functions to
|
||||
+ # libblockdev and use them here
|
||||
+ if pv.pv_name.startswith("/dev/md/"):
|
||||
+ try:
|
||||
+ md_node = blockdev.md.node_from_name(pv.pv_name[len("/dev/md/"):])
|
||||
+ self._pvs_cache["/dev/" + md_node] = pv
|
||||
+ except blockdev.MDRaidError:
|
||||
+ pass
|
||||
+ elif pv.pv_name.startswith("/dev/md"):
|
||||
+ try:
|
||||
+ md_named_dev = blockdev.md.name_from_node(pv.pv_name[len("/dev/"):])
|
||||
+ self._pvs_cache["/dev/md/" + md_named_dev] = pv
|
||||
+ except blockdev.MDRaidError:
|
||||
+ pass
|
||||
|
||||
return self._pvs_cache
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
@ -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
|
||||
|
BIN
blivet/blivet-2.1.11.tar.gz
Normal file
BIN
blivet/blivet-2.1.11.tar.gz
Normal file
Binary file not shown.
Binary file not shown.
@ -1,11 +1,11 @@
|
||||
Summary: A python module for system storage configuration
|
||||
Name: python-blivet
|
||||
Url: http://fedoraproject.org/wiki/blivet
|
||||
Version: 2.1.6
|
||||
Version: 2.1.11
|
||||
|
||||
#%%global prerelease .b1
|
||||
# prerelease, if defined, should be something like .a1, .b1, .b2.dev1, or .c2
|
||||
Release: 5%{?prerelease}%{?dist}
|
||||
Release: 6%{?prerelease}%{?dist}
|
||||
Epoch: 2
|
||||
License: LGPLv2+
|
||||
Group: System Environment/Libraries
|
||||
@ -13,15 +13,17 @@ Group: System Environment/Libraries
|
||||
%global realversion %{version}%{?prerelease}
|
||||
Source0: http://github.com/rhinstaller/blivet/archive/%{realname}-%{realversion}.tar.gz
|
||||
|
||||
Patch0: 0001-Use-correct-type-for-port-in-GVariant-tuple.patch
|
||||
Patch1: 0002-iSCSI-Store-auth-info-in-NodeInfo-tuples.patch
|
||||
Patch2: 0003-iSCSI-turn-iscsi.initiator_set-into-a-property.patch
|
||||
Patch3: 0004-Add-device-symlinks-to-the-PVs-dictionary-for-MD-RAI.patch
|
||||
Patch4: 0001-Fix-detection-of-macefi-partitions-1393846.patch
|
||||
Patch5: 0001-Fix-unknown-SAS-device-sysfs-parsing.patch
|
||||
Patch6: 0001-Change-how-we-run-e2fsck-to-check-ext-filesystems.patch
|
||||
Patch7: 0002-Do-not-run-FS-check-as-part-of-updating-re-size-info.patch
|
||||
Patch8: 0001-Fix-AttributeError-in-fsminsize-1502587.patch
|
||||
Patch0: 0001-Fix-AttributeError-in-fsminsize-1502587.patch
|
||||
# make it compatible with fc25
|
||||
Patch1: 0001-Revert-FBA-DASD-should-use-the-msdos-disk-label-type.patch
|
||||
Patch2: 0002-Revert-Require-BlockDev-2.0-in-the-gi.require_versio.patch
|
||||
Patch3: 0003-Revert-Adapt-to-logging-module-name-change.patch
|
||||
Patch4: 0004-Backport-lvm-thin-pool-metadata-size-functions-from-.patch
|
||||
Patch5: 0005-Use-local-backport-of-BlockDev-2.0-interface.patch
|
||||
|
||||
# Qubes patches
|
||||
Patch100: 0001-Double-recommended-LVM-thin-pool-metadata-space.patch
|
||||
Patch101: 0001-Avoid-mounting-pre-existing-disks.patch
|
||||
|
||||
# Versions of required components (done so we make sure the buildrequires
|
||||
# match the requires versions of things).
|
||||
@ -77,9 +79,9 @@ configuration.
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
|
||||
%patch100 -p1
|
||||
%patch101 -p1
|
||||
|
||||
rm -rf %{py3dir}
|
||||
cp -a . %{py3dir}
|
||||
|
7
conf/iso-full-online.ks
Normal file
7
conf/iso-full-online.ks
Normal file
@ -0,0 +1,7 @@
|
||||
# Full ISO build using packages from online repositories instead of local build
|
||||
%include qubes-kickstart.cfg
|
||||
|
||||
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
|
||||
|
@ -1,8 +1,6 @@
|
||||
%include qubes-kickstart.cfg
|
||||
%include iso-full-online.ks
|
||||
|
||||
repo --name=qubes-r4.0-testing --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.0-primary --baseurl=http://mirrors.ukfast.co.uk/sites/qubes-os.org/repo/yum/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 --baseurl=http://mirrors.ukfast.co.uk/sites/qubes-os.org/repo/yum/r4.0/templates-itl --ignoregroups=true
|
||||
repo --name=qubes-r4.0-templates-itl-testing --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.0-primary --baseurl=http://mirrors.ukfast.co.uk/sites/qubes-os.org/repo/yum/r4.0/templates-itl-testing --ignoregroups=true
|
||||
repo --name=qubes-r4.0-templates-community --gpgkey=file:///tmp/qubes-installer/qubes-release/RPM-GPG-KEY-qubes-4.0-templates-community --baseurl=http://mirrors.ukfast.co.uk/sites/qubes-os.org/repo/yum/r4.0/templates-community --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 --baseurl=http://mirrors.ukfast.co.uk/sites/qubes-os.org/repo/yum/r4.0/templates-community-testing --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,5 +1,5 @@
|
||||
Name: lorax-templates-qubes
|
||||
Version: 4.0.5
|
||||
Version: 4.0.6
|
||||
Release: 1%{?dist}
|
||||
Summary: Lorax templates for Qubes installation ISO
|
||||
|
||||
|
@ -61,12 +61,12 @@ menu separator # insert an empty line
|
||||
label linux
|
||||
menu label ^Install @PRODUCT@ @VERSION@
|
||||
kernel mboot.c32
|
||||
append xen.gz console=none --- vmlinuz @ROOT@ i915.alpha_support=1 quiet rhgb --- initrd.img
|
||||
append xen.gz console=none --- vmlinuz @ROOT@ i915.alpha_support=1 quiet rhgb plymouth.ignore-serial-consoles --- initrd.img
|
||||
label check
|
||||
menu label Test this ^media & install @PRODUCT@ @VERSION@
|
||||
menu default
|
||||
kernel mboot.c32
|
||||
append xen.gz console=none --- vmlinuz @ROOT@ i915.alpha_support=1 quiet rhgb rd.live.check --- initrd.img
|
||||
append xen.gz console=none --- vmlinuz @ROOT@ i915.alpha_support=1 quiet rhgb plymouth.ignore-serial-consoles rd.live.check --- initrd.img
|
||||
|
||||
menu separator # insert an empty line
|
||||
|
||||
|
@ -3,12 +3,12 @@ default=qubes-verbose
|
||||
|
||||
[qubes-check]
|
||||
options=console=none
|
||||
kernel=vmlinuz @ROOT@ i915.alpha_support=1 quiet rhgb rd.live.check
|
||||
kernel=vmlinuz @ROOT@ i915.alpha_support=1 quiet rhgb plymouth.ignore-serial-consoles rd.live.check
|
||||
ramdisk=initrd.img
|
||||
|
||||
[qubes]
|
||||
options=console=none
|
||||
kernel=vmlinuz @ROOT@ i915.alpha_support=1 quiet rhgb
|
||||
kernel=vmlinuz @ROOT@ i915.alpha_support=1 quiet rhgb plymouth.ignore-serial-consoles
|
||||
ramdisk=initrd.img
|
||||
|
||||
[qubes-verbose]
|
||||
|
@ -1,160 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Failsafe minimal text-mode firstboot
|
||||
|
||||
# Welcome
|
||||
|
||||
if [ "x$1" = "x--help" ]; then
|
||||
echo "Failsafe minimal text-mode firstboot"
|
||||
echo "For unattended mode use: $0 <username> <userpass> <vm-creation-option-number>"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "########################################################"
|
||||
echo " Welcome to `cat /etc/qubes-release`"
|
||||
echo "########################################################"
|
||||
echo
|
||||
echo "This is failsafe text-mode firstboot. If you see this message, you have"
|
||||
echo "some problem with Xorg (most probably video driver)"
|
||||
echo
|
||||
echo "Anyway, some basic setup is needed to continue:"
|
||||
|
||||
# User creation
|
||||
|
||||
echo
|
||||
echo "1. Setup user account"
|
||||
exists=0
|
||||
user=$1
|
||||
while [ -z "$user" ]; do
|
||||
echo -n "Enter desired username (may already exist): "
|
||||
read user
|
||||
if echo "$user" | grep -q "[^a-z0-9]"; then
|
||||
echo "ERROR: Invalid characters in username, try again"
|
||||
user=
|
||||
elif id $user > /dev/null 2>&1; then
|
||||
if [ $(id -u ${user}) -ge 1000 ] && id -n -G ${user} | grep -q qubes; then
|
||||
echo "OK: Using an existing user: \"${user}\""
|
||||
exists=1
|
||||
break
|
||||
fi
|
||||
echo "ERROR: This user already exists or is not suitable. Please try again"
|
||||
user=
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${exists} -eq 0 ]; then
|
||||
useradd -G qubes -m "$user" || exit 1
|
||||
if [ -n "$2" ]; then
|
||||
echo -e "$2\n$2" | passwd --stdin "$user"
|
||||
else
|
||||
while ! passwd "$user"; do true; done
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create default VMs
|
||||
|
||||
echo
|
||||
echo "2. Create default VMs"
|
||||
echo
|
||||
echo "Choose one option:"
|
||||
echo " 1. Create default service VMs, and pre-defined AppVMs (personal, work, untrusted, vault)"
|
||||
echo " 2. Just create default service VMs"
|
||||
echo " 3. Do not create any VMs right now, but configure template(s)"
|
||||
echo " 4. Do not do anything (not recommended, for advanced users only)"
|
||||
vms_option=$3
|
||||
while true; do
|
||||
if [ -z "$vms_option" ]; then
|
||||
echo -n "Enter your choice (1/2/3/4): "
|
||||
read vms_option
|
||||
fi
|
||||
if [ "$vms_option" == "1" ]; then
|
||||
vms_template=yes
|
||||
vms_service=yes
|
||||
vms_app=yes
|
||||
break
|
||||
elif [ "$vms_option" == "2" ]; then
|
||||
vms_template=yes
|
||||
vms_service=yes
|
||||
break
|
||||
elif [ "$vms_option" == "3" ]; then
|
||||
vms_template=yes
|
||||
break
|
||||
elif [ "$vms_option" == "4" ]; then
|
||||
break
|
||||
else
|
||||
echo "ERROR: Invalid choice, try again"
|
||||
vms_option=
|
||||
fi
|
||||
done
|
||||
|
||||
set -e
|
||||
|
||||
for service in rdisc kdump libvirt-guests salt-minion; do
|
||||
systemctl disable ${service}.service || :
|
||||
systemctl stop ${service}.service || :
|
||||
done
|
||||
|
||||
if [ "$vms_template" == "yes" ]; then
|
||||
for template in `ls /var/lib/qubes/vm-templates`; do
|
||||
echo "-> Configuring template $template..."
|
||||
qvm-start --no-guid $template
|
||||
su -g "qubes" -c "qvm-sync-appmenus $template" - $user
|
||||
qvm-shutdown --wait $template
|
||||
done
|
||||
|
||||
qubes-prefs --set default-template 'fedora-29'
|
||||
fi
|
||||
|
||||
if [ "$vms_service" == "yes" -o "$vms_app" == "yes" ]; then
|
||||
echo "-> Configuring Qubes OS management framework..."
|
||||
|
||||
if test -e /var/log/salt/minion; then
|
||||
mv /var/log/salt/minion /var/log/salt/minion.install || :
|
||||
fi
|
||||
|
||||
qubesctl saltutil.clear_cache -l quiet --out quiet
|
||||
qubesctl saltutil.sync_all -l quiet --out quiet
|
||||
fi
|
||||
|
||||
states=()
|
||||
|
||||
if [ "$vms_service" == "yes" ]; then
|
||||
states=("${states[@]}" qvm.sys-net qvm.sys-firewall)
|
||||
fi
|
||||
|
||||
if [ "$vms_app" == "yes" ]; then
|
||||
states=("${states[@]}" qvm.personal qvm.work qvm.untrusted qvm.vault)
|
||||
fi
|
||||
|
||||
if [ "$vms_service" == "yes" -o "$vms_app" == "yes" ]; then
|
||||
for state in "${states[@]}"; do
|
||||
echo "-> Requesting creation of VM: ${state#qvm.}"
|
||||
qubesctl top.enable "${state}" -l quiet --out quiet
|
||||
done
|
||||
|
||||
echo "-> Creating VMs"
|
||||
qubesctl "state.highstate"
|
||||
fi
|
||||
|
||||
if [ "$vms_service" == "yes" ]; then
|
||||
echo "--> Configuring service VMs"
|
||||
default_netvm="sys-net"
|
||||
default_firewallvm="sys-firewall"
|
||||
|
||||
su -g "qubes" -c "qvm-prefs --set ${default_firewallvm} netvm ${default_netvm}" - $user
|
||||
su -g "qubes" -c "qubes-prefs --set default-netvm ${default_firewallvm}" - $user
|
||||
su -g "qubes" -c "qubes-prefs --set updatevm ${default_firewallvm}" - $user
|
||||
su -g "qubes" -c "qubes-prefs --set clockvm ${default_netvm}" - $user
|
||||
|
||||
echo "-> Starting network..."
|
||||
service qubes-netvm start
|
||||
|
||||
# DispVM creation fails with the following error message, most likely due to missing $DISPLAY:
|
||||
# "Cannot start qubes-guid!"
|
||||
#echo "-> Creating DispVM savefile (can take long time)..."
|
||||
#su -g "qubes" -c "/usr/bin/qvm-create-default-dvm --default-template --default-script" - $user || :
|
||||
fi
|
||||
|
||||
echo "-> Done."
|
@ -2,4 +2,4 @@
|
||||
# if X server is not yet running
|
||||
#import gui
|
||||
|
||||
import tui
|
||||
#import tui
|
||||
|
@ -4,4 +4,98 @@ work.
|
||||
|
||||
"""
|
||||
|
||||
import spokes
|
||||
import gi
|
||||
|
||||
gi.require_version('Gtk', '3.0')
|
||||
gi.require_version('Gdk', '3.0')
|
||||
gi.require_version('GLib', '2.0')
|
||||
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import GLib
|
||||
|
||||
import logging
|
||||
import threading
|
||||
|
||||
|
||||
class ThreadDialog(Gtk.Dialog):
|
||||
def __init__(self, title, fun, args, transient_for=None):
|
||||
Gtk.Dialog.__init__(self, title=title, transient_for=transient_for)
|
||||
|
||||
self.set_modal(True)
|
||||
self.set_default_size(500, 100)
|
||||
|
||||
self.connect('delete-event', self.on_delete_event)
|
||||
|
||||
self.progress = Gtk.ProgressBar()
|
||||
self.progress.set_pulse_step(100)
|
||||
self.progress.set_text("")
|
||||
self.progress.set_show_text(False)
|
||||
|
||||
self.label = Gtk.Label()
|
||||
self.label.set_line_wrap(True)
|
||||
self.label.set_text("")
|
||||
|
||||
self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
self.box.pack_start(self.progress, True, True, 0)
|
||||
self.box.pack_start(self.label, True, True, 0)
|
||||
|
||||
self.get_content_area().pack_start(self.box, True, True, 0)
|
||||
|
||||
self.fun = fun
|
||||
self.args = args
|
||||
|
||||
self.logger = logging.getLogger("anaconda")
|
||||
|
||||
self.thread = threading.Thread(target=self.run_fun)
|
||||
|
||||
def run_fun(self):
|
||||
try:
|
||||
self.fun(*self.args)
|
||||
except Exception as e:
|
||||
self.showErrorMessage(str(e))
|
||||
finally:
|
||||
self.done()
|
||||
|
||||
def on_delete_event(self, widget=None, *args):
|
||||
# Ignore the clicks on the close button by returning True.
|
||||
self.logger.info("Caught delete-event")
|
||||
return True
|
||||
|
||||
def set_text(self, text):
|
||||
Gdk.threads_add_timeout(GLib.PRIORITY_DEFAULT, 0, self.label.set_text, text)
|
||||
|
||||
def done(self):
|
||||
Gdk.threads_add_timeout(GLib.PRIORITY_DEFAULT, 100, self.done_helper, ())
|
||||
|
||||
def done_helper(self, *args):
|
||||
self.logger.info("Joining thread.")
|
||||
self.thread.join()
|
||||
|
||||
self.logger.info("Stopping self.")
|
||||
self.response(Gtk.ResponseType.ACCEPT)
|
||||
|
||||
def run_in_ui_thread(self, fun, *args):
|
||||
Gdk.threads_add_timeout(GLib.PRIORITY_DEFAULT, 0, fun, *args)
|
||||
|
||||
def run(self):
|
||||
self.thread.start()
|
||||
self.progress.pulse()
|
||||
self.show_all()
|
||||
|
||||
ret = None
|
||||
while ret in (None, Gtk.ResponseType.DELETE_EVENT):
|
||||
ret = super(ThreadDialog, self).run()
|
||||
|
||||
return ret
|
||||
|
||||
def showErrorMessage(self, text):
|
||||
self.run_in_ui_thread(self.showErrorMessageHelper, text)
|
||||
|
||||
def showErrorMessageHelper(self, text):
|
||||
dlg = Gtk.MessageDialog(title="Error", message_type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK, text=text)
|
||||
dlg.set_position(Gtk.WindowPosition.CENTER)
|
||||
dlg.set_modal(True)
|
||||
dlg.set_transient_for(self)
|
||||
dlg.run()
|
||||
dlg.destroy()
|
||||
|
@ -29,15 +29,7 @@
|
||||
_ = lambda x: x
|
||||
N_ = lambda x: x
|
||||
|
||||
import distutils.version
|
||||
import functools
|
||||
import grp
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
import pyudev
|
||||
import subprocess
|
||||
import threading
|
||||
|
||||
import gi
|
||||
|
||||
@ -46,10 +38,7 @@ gi.require_version('Gdk', '3.0')
|
||||
gi.require_version('GLib', '2.0')
|
||||
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import GLib
|
||||
|
||||
from pyanaconda import iutil
|
||||
from pyanaconda.ui.categories.system import SystemCategory
|
||||
from pyanaconda.ui.gui.spokes import NormalSpoke
|
||||
from pyanaconda.ui.common import FirstbootOnlySpokeMixIn
|
||||
@ -57,53 +46,15 @@ from pyanaconda.ui.common import FirstbootOnlySpokeMixIn
|
||||
# export only the spoke, no helper functions, classes or constants
|
||||
__all__ = ["QubesOsSpoke"]
|
||||
|
||||
def is_package_installed(pkgname):
|
||||
pkglist = subprocess.check_output(['rpm', '-qa', pkgname])
|
||||
return bool(pkglist)
|
||||
|
||||
def usb_keyboard_present():
|
||||
context = pyudev.Context()
|
||||
keyboards = context.list_devices(subsystem='input', ID_INPUT_KEYBOARD='1')
|
||||
return any([d.get('ID_USB_INTERFACES', False) for d in keyboards])
|
||||
|
||||
def started_from_usb():
|
||||
def get_all_used_devices(dev):
|
||||
stat = os.stat(dev)
|
||||
if stat.st_rdev:
|
||||
# XXX any better idea how to handle device-mapper?
|
||||
sysfs_slaves = '/sys/dev/block/{}:{}/slaves'.format(
|
||||
os.major(stat.st_rdev), os.minor(stat.st_rdev))
|
||||
if os.path.exists(sysfs_slaves):
|
||||
for slave_dev in os.listdir(sysfs_slaves):
|
||||
for d in get_all_used_devices('/dev/{}'.format(slave_dev)):
|
||||
yield d
|
||||
else:
|
||||
yield dev
|
||||
|
||||
context = pyudev.Context()
|
||||
mounts = open('/proc/mounts').readlines()
|
||||
for mount in mounts:
|
||||
device = mount.split(' ')[0]
|
||||
if not os.path.exists(device):
|
||||
continue
|
||||
for dev in get_all_used_devices(device):
|
||||
udev_info = pyudev.Device.from_device_file(context, dev)
|
||||
if udev_info.get('ID_USB_INTERFACES', False):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
class QubesChoice(object):
|
||||
instances = []
|
||||
|
||||
def __init__(self, label, states, depend=None, extra_check=None,
|
||||
replace=None, indent=False):
|
||||
def __init__(self, label, depend=None, extra_check=None,
|
||||
indent=False):
|
||||
self.widget = Gtk.CheckButton(label=label)
|
||||
self.states = states
|
||||
self.depend = depend
|
||||
self.extra_check = extra_check
|
||||
self.selected = None
|
||||
self.replace = replace
|
||||
|
||||
self._can_be_sensitive = True
|
||||
|
||||
@ -129,6 +80,11 @@ class QubesChoice(object):
|
||||
if self.selected is not None
|
||||
else self.widget.get_sensitive() and self.widget.get_active())
|
||||
|
||||
def set_selected(self, value):
|
||||
self.widget.set_active(value)
|
||||
if self.selected is not None:
|
||||
self.selected = value
|
||||
|
||||
def store_selected(self):
|
||||
self.selected = self.get_selected()
|
||||
|
||||
@ -146,27 +102,14 @@ class QubesChoice(object):
|
||||
choice.set_sensitive(not selected and
|
||||
(choice.depend is None or choice.depend.get_selected()))
|
||||
|
||||
@classmethod
|
||||
def get_states(cls):
|
||||
replaced = functools.reduce(
|
||||
lambda x, y: x+y if y else x,
|
||||
(choice.replace for choice in cls.instances if
|
||||
choice.get_selected()),
|
||||
()
|
||||
)
|
||||
for choice in cls.instances:
|
||||
if choice.get_selected():
|
||||
for state in choice.states:
|
||||
if state not in replaced:
|
||||
yield state
|
||||
|
||||
|
||||
class DisabledChoice(QubesChoice):
|
||||
def __init__(self, label):
|
||||
super(DisabledChoice, self).__init__(label, ())
|
||||
super(DisabledChoice, self).__init__(label)
|
||||
self.widget.set_sensitive(False)
|
||||
self._can_be_sensitive = False
|
||||
|
||||
|
||||
class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalSpoke):
|
||||
"""
|
||||
Since this class inherits from the FirstbootOnlySpokeMixIn, it will
|
||||
@ -226,55 +169,43 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalSpoke):
|
||||
self.main_box = self.builder.get_object("mainBox")
|
||||
self.thread_dialog = None
|
||||
|
||||
self.qubes_user = None
|
||||
self.qubes_gid = None
|
||||
self.default_template = 'fedora-29'
|
||||
|
||||
self.set_stage("Start-up")
|
||||
self.done = False
|
||||
self.qubes_data = self.data.addons.org_qubes_os_initial_setup
|
||||
|
||||
self.__init_qubes_choices()
|
||||
|
||||
def __init_qubes_choices(self):
|
||||
self.choice_network = QubesChoice(
|
||||
_('Create default system qubes (sys-net, sys-firewall, default DispVM)'),
|
||||
('qvm.sys-net', 'qvm.sys-firewall', 'qvm.default-dispvm'))
|
||||
self.choice_system = QubesChoice(
|
||||
_('Create default system qubes (sys-net, sys-firewall, default DispVM)'))
|
||||
|
||||
self.choice_default = QubesChoice(
|
||||
_('Create default application qubes '
|
||||
'(personal, work, untrusted, vault)'),
|
||||
('qvm.personal', 'qvm.work', 'qvm.untrusted', 'qvm.vault'),
|
||||
depend=self.choice_network)
|
||||
depend=self.choice_system)
|
||||
|
||||
if (is_package_installed('qubes-template-whonix-gw*') and
|
||||
is_package_installed('qubes-template-whonix-ws*')):
|
||||
if self.qubes_data.whonix_available:
|
||||
self.choice_whonix = QubesChoice(
|
||||
_('Create Whonix Gateway and Workstation qubes '
|
||||
'(sys-whonix, anon-whonix)'),
|
||||
('qvm.sys-whonix', 'qvm.anon-whonix'),
|
||||
depend=self.choice_network)
|
||||
depend=self.choice_system)
|
||||
else:
|
||||
self.choice_whonix = DisabledChoice(_("Whonix not installed"))
|
||||
|
||||
self.choice_whonix_updates = QubesChoice(
|
||||
_('Enable system and template updates over the Tor anonymity '
|
||||
'network using Whonix'),
|
||||
('qvm.updates-via-whonix',),
|
||||
depend=self.choice_whonix,
|
||||
indent=True)
|
||||
|
||||
if not usb_keyboard_present() and not started_from_usb():
|
||||
if self.qubes_data.usbvm_available:
|
||||
self.choice_usb = QubesChoice(
|
||||
_('Create USB qube holding all USB controllers (sys-usb)'),
|
||||
('qvm.sys-usb',))
|
||||
_('Create USB qube holding all USB controllers (sys-usb)'))
|
||||
else:
|
||||
self.choice_usb = DisabledChoice(
|
||||
_('USB qube configuration disabled - you are using USB '
|
||||
'keyboard or USB disk'))
|
||||
|
||||
self.choice_usb_with_net = QubesChoice(
|
||||
self.choice_usb_with_netvm = QubesChoice(
|
||||
_("Use sys-net qube for both networking and USB devices"),
|
||||
('pillar.qvm.sys-net-as-usbvm',),
|
||||
depend=self.choice_usb,
|
||||
indent=True
|
||||
)
|
||||
@ -289,7 +220,7 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalSpoke):
|
||||
|
||||
self.check_advanced.set_active(False)
|
||||
|
||||
self.choice_network.widget.set_active(True)
|
||||
self.choice_system.widget.set_active(True)
|
||||
self.choice_default.widget.set_active(True)
|
||||
if self.choice_whonix.widget.get_sensitive():
|
||||
self.choice_whonix.widget.set_active(True)
|
||||
@ -307,6 +238,7 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalSpoke):
|
||||
"""
|
||||
|
||||
NormalSpoke.initialize(self)
|
||||
self.qubes_data.gui_mode = True
|
||||
|
||||
def refresh(self):
|
||||
"""
|
||||
@ -318,8 +250,12 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalSpoke):
|
||||
|
||||
"""
|
||||
|
||||
# nothing to do here
|
||||
pass
|
||||
self.choice_system.set_selected(self.qubes_data.system_vms)
|
||||
self.choice_default.set_selected(self.qubes_data.default_vms)
|
||||
self.choice_whonix.set_selected(self.qubes_data.whonix_vms)
|
||||
self.choice_whonix_updates.set_selected(self.qubes_data.whonix_default)
|
||||
self.choice_usb.set_selected(self.qubes_data.usbvm)
|
||||
self.choice_usb_with_netvm.set_selected(self.qubes_data.usbvm_with_netvm)
|
||||
|
||||
def apply(self):
|
||||
"""
|
||||
@ -328,8 +264,16 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalSpoke):
|
||||
|
||||
"""
|
||||
|
||||
# nothing to do here
|
||||
pass
|
||||
self.qubes_data.skip = self.check_advanced.get_active()
|
||||
|
||||
self.qubes_data.system_vms = self.choice_system.get_selected()
|
||||
self.qubes_data.default_vms = self.choice_default.get_selected()
|
||||
self.qubes_data.whonix_vms = self.choice_whonix.get_selected()
|
||||
self.qubes_data.whonix_default = self.choice_whonix_updates.get_selected()
|
||||
self.qubes_data.usbvm = self.choice_usb.get_selected()
|
||||
self.qubes_data.usbvm_with_netvm = self.choice_usb_with_netvm.get_selected()
|
||||
|
||||
self.qubes_data.seen = True
|
||||
|
||||
@property
|
||||
def ready(self):
|
||||
@ -354,7 +298,7 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalSpoke):
|
||||
|
||||
"""
|
||||
|
||||
return self.done
|
||||
return self.qubes_data.seen
|
||||
|
||||
@property
|
||||
def mandatory(self):
|
||||
@ -388,274 +332,4 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalSpoke):
|
||||
the values set in the GUI elements.
|
||||
|
||||
"""
|
||||
for choice in QubesChoice.instances:
|
||||
choice.store_selected()
|
||||
|
||||
self.thread_dialog = ThreadDialog("Qubes OS Setup", self.do_setup, (), transient_for=self.main_window)
|
||||
self.thread_dialog.run()
|
||||
self.thread_dialog.destroy()
|
||||
|
||||
def do_setup(self, *args):
|
||||
try:
|
||||
self.qubes_gid = grp.getgrnam('qubes').gr_gid
|
||||
|
||||
qubes_users = grp.getgrnam('qubes').gr_mem
|
||||
|
||||
if len(qubes_users) < 1:
|
||||
self.showErrorMessage(_("You must create a user account to create default VMs."))
|
||||
return
|
||||
else:
|
||||
self.qubes_user = qubes_users[0]
|
||||
|
||||
if self.check_advanced.get_active():
|
||||
return
|
||||
|
||||
errors = []
|
||||
|
||||
os.setgid(self.qubes_gid)
|
||||
os.umask(0o0007)
|
||||
|
||||
self.configure_default_kernel()
|
||||
|
||||
# Finish template(s) installation, because it wasn't fully possible
|
||||
# from anaconda (it isn't possible to start a VM there).
|
||||
# This is specific to firstboot, not general configuration.
|
||||
for template in os.listdir('/var/lib/qubes/vm-templates'):
|
||||
try:
|
||||
self.configure_template(template,
|
||||
'/var/lib/qubes/vm-templates/' + template)
|
||||
except Exception as e:
|
||||
errors.append((self.stage, str(e)))
|
||||
|
||||
self.configure_dom0()
|
||||
self.configure_default_template()
|
||||
self.configure_qubes()
|
||||
if self.choice_network.get_selected():
|
||||
self.configure_network()
|
||||
if self.choice_usb.get_selected() and not self.choice_usb_with_net.get_selected():
|
||||
# Workaround for #1464 (so qvm.start from salt can't be used)
|
||||
self.run_command(['systemctl', 'start', 'qubes-vm@sys-usb.service'])
|
||||
|
||||
try:
|
||||
self.configure_default_dvm()
|
||||
except Exception as e:
|
||||
errors.append((self.stage, str(e)))
|
||||
|
||||
if errors:
|
||||
msg = ""
|
||||
for (stage, error) in errors:
|
||||
msg += "{} failed:\n{}\n\n".format(stage, error)
|
||||
|
||||
raise Exception(msg)
|
||||
|
||||
except Exception as e:
|
||||
self.showErrorMessage(str(e))
|
||||
|
||||
finally:
|
||||
self.thread_dialog.done()
|
||||
self.done = True
|
||||
|
||||
def set_stage(self, stage):
|
||||
self.stage = stage
|
||||
|
||||
if self.thread_dialog != None:
|
||||
self.thread_dialog.set_text(stage)
|
||||
|
||||
def run_command(self, command, stdin=None, ignore_failure=False):
|
||||
process_error = None
|
||||
|
||||
try:
|
||||
sys_root = iutil.getSysroot()
|
||||
|
||||
cmd = iutil.startProgram(command, stderr=subprocess.PIPE, stdin=stdin, root=sys_root)
|
||||
|
||||
(stdout, stderr) = cmd.communicate()
|
||||
|
||||
stdout = stdout.decode("utf-8")
|
||||
stderr = stderr.decode("utf-8")
|
||||
|
||||
if not ignore_failure and cmd.returncode != 0:
|
||||
process_error = "{} failed:\nstdout: \"{}\"\nstderr: \"{}\"".format(command, stdout, stderr)
|
||||
|
||||
except Exception as e:
|
||||
process_error = str(e)
|
||||
|
||||
if process_error:
|
||||
self.logger.error(process_error)
|
||||
raise Exception(process_error)
|
||||
|
||||
return (stdout, stderr)
|
||||
|
||||
def configure_default_kernel(self):
|
||||
self.set_stage("Setting up default kernel")
|
||||
installed_kernels = os.listdir('/var/lib/qubes/vm-kernels')
|
||||
installed_kernels = [distutils.version.LooseVersion(x) for x in installed_kernels]
|
||||
default_kernel = str(sorted(installed_kernels)[-1])
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'default-kernel', default_kernel])
|
||||
|
||||
def configure_dom0(self):
|
||||
self.set_stage("Setting up administration VM (dom0)")
|
||||
|
||||
for service in [ 'rdisc', 'kdump', 'libvirt-guests', 'salt-minion' ]:
|
||||
self.run_command(['systemctl', 'disable', '{}.service'.format(service) ], ignore_failure=True)
|
||||
self.run_command(['systemctl', 'stop', '{}.service'.format(service) ], ignore_failure=True)
|
||||
|
||||
def configure_qubes(self):
|
||||
self.set_stage('Executing qubes configuration')
|
||||
|
||||
try:
|
||||
# get rid of initial entries (from package installation time)
|
||||
os.rename('/var/log/salt/minion', '/var/log/salt/minion.install')
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# Refresh minion configuration to make sure all installed formulas are included
|
||||
self.run_command(['qubesctl', 'saltutil.clear_cache'])
|
||||
self.run_command(['qubesctl', 'saltutil.sync_all'])
|
||||
|
||||
for state in QubesChoice.get_states():
|
||||
print("Setting up state: {}".format(state))
|
||||
if state.startswith('pillar.'):
|
||||
self.run_command(['qubesctl', 'top.enable',
|
||||
state[len('pillar.'):], 'pillar=True'])
|
||||
else:
|
||||
self.run_command(['qubesctl', 'top.enable', state])
|
||||
|
||||
try:
|
||||
self.run_command(['qubesctl', 'state.highstate'])
|
||||
# After successful call disable all the states to not leave them
|
||||
# enabled, to not interfere with later user changes (like assigning
|
||||
# additional PCI devices)
|
||||
for state in QubesChoice.get_states():
|
||||
if not state.startswith('pillar.'):
|
||||
self.run_command(['qubesctl', 'top.disable', state])
|
||||
except Exception:
|
||||
raise Exception(
|
||||
("Qubes initial configuration failed. Login to the system and " +
|
||||
"check /var/log/salt/minion for details. " +
|
||||
"You can retry configuration by calling " +
|
||||
"'sudo qubesctl state.highstate' in dom0 (you will get " +
|
||||
"detailed state there)."))
|
||||
|
||||
def configure_default_template(self):
|
||||
self.set_stage('Setting default template')
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'default-template', self.default_template])
|
||||
|
||||
def configure_default_dvm(self):
|
||||
self.set_stage("Creating default DisposableVM")
|
||||
|
||||
dispvm_name = self.default_template + '-dvm'
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'default-dispvm',
|
||||
dispvm_name])
|
||||
|
||||
def configure_network(self):
|
||||
self.set_stage('Setting up networking')
|
||||
|
||||
default_netvm = 'sys-firewall'
|
||||
updatevm = default_netvm
|
||||
if self.choice_whonix_updates.get_selected():
|
||||
updatevm = 'sys-whonix'
|
||||
|
||||
self.run_command(['/usr/bin/qvm-prefs', 'sys-firewall', 'netvm', 'sys-net'])
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'default-netvm', default_netvm])
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'updatevm', updatevm])
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'clockvm', 'sys-net'])
|
||||
self.run_command(['/usr/bin/qvm-start', default_netvm])
|
||||
|
||||
def configure_template(self, template, path):
|
||||
self.set_stage("Configuring TemplateVM {}".format(template))
|
||||
self.run_command(['qvm-template-postprocess', '--really', 'post-install', template, path])
|
||||
|
||||
def showErrorMessage(self, text):
|
||||
self.thread_dialog.run_in_ui_thread(self.showErrorMessageHelper, text)
|
||||
|
||||
def showErrorMessageHelper(self, text):
|
||||
dlg = Gtk.MessageDialog(title="Error", message_type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK, text=text)
|
||||
dlg.set_position(Gtk.WindowPosition.CENTER)
|
||||
dlg.set_modal(True)
|
||||
dlg.set_transient_for(self.thread_dialog)
|
||||
dlg.run()
|
||||
dlg.destroy()
|
||||
|
||||
class ThreadDialog(Gtk.Dialog):
|
||||
def __init__(self, title, fun, args, transient_for=None):
|
||||
Gtk.Dialog.__init__(self, title=title, transient_for=transient_for)
|
||||
|
||||
self.set_modal(True)
|
||||
self.set_default_size(500, 100)
|
||||
|
||||
self.connect('delete-event', self.on_delete_event)
|
||||
|
||||
self.progress = Gtk.ProgressBar()
|
||||
self.progress.set_pulse_step(100)
|
||||
self.progress.set_text("")
|
||||
self.progress.set_show_text(False)
|
||||
|
||||
self.label = Gtk.Label()
|
||||
self.label.set_line_wrap(True)
|
||||
self.label.set_text("")
|
||||
|
||||
self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
self.box.pack_start(self.progress, True, True, 0)
|
||||
self.box.pack_start(self.label, True, True, 0)
|
||||
|
||||
self.get_content_area().pack_start(self.box, True, True, 0)
|
||||
|
||||
self.fun = fun
|
||||
self.args = args
|
||||
|
||||
self.logger = logging.getLogger("anaconda")
|
||||
|
||||
self.thread = threading.Thread(target=self.fun, args=self.args)
|
||||
|
||||
def on_delete_event(self, widget=None, *args):
|
||||
# Ignore the clicks on the close button by returning True.
|
||||
self.logger.info("Caught delete-event")
|
||||
return True
|
||||
|
||||
def set_text(self, text):
|
||||
Gdk.threads_add_timeout(GLib.PRIORITY_DEFAULT, 0, self.label.set_text, text)
|
||||
|
||||
def done(self):
|
||||
Gdk.threads_add_timeout(GLib.PRIORITY_DEFAULT, 100, self.done_helper, ())
|
||||
|
||||
def done_helper(self, *args):
|
||||
self.logger.info("Joining thread.")
|
||||
self.thread.join()
|
||||
|
||||
self.logger.info("Stopping self.")
|
||||
self.response(Gtk.ResponseType.ACCEPT)
|
||||
|
||||
def run_in_ui_thread(self, fun, *args):
|
||||
Gdk.threads_add_timeout(GLib.PRIORITY_DEFAULT, 0, fun, *args)
|
||||
|
||||
def run(self):
|
||||
self.thread.start()
|
||||
self.progress.pulse()
|
||||
self.show_all()
|
||||
|
||||
ret = None
|
||||
while ret in (None, Gtk.ResponseType.DELETE_EVENT):
|
||||
ret = super(ThreadDialog, self).run()
|
||||
|
||||
return ret
|
||||
|
||||
if __name__ == "__main__":
|
||||
import time
|
||||
|
||||
def hello_fun(*args):
|
||||
global thread_dialog
|
||||
thread_dialog.set_text("Hello, world! " * 30)
|
||||
time.sleep(2)
|
||||
thread_dialog.set_text("Goodbye, world!")
|
||||
time.sleep(1)
|
||||
thread_dialog.done()
|
||||
return
|
||||
|
||||
logger = logging.getLogger("anaconda")
|
||||
handler = logging.StreamHandler()
|
||||
logger.addHandler(handler)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
thread_dialog = ThreadDialog("Hello", hello_fun, ())
|
||||
thread_dialog.run()
|
||||
pass
|
||||
|
362
qubes-anaconda-addon/org_qubes_os_initial_setup/ks/qubes.py
Normal file
362
qubes-anaconda-addon/org_qubes_os_initial_setup/ks/qubes.py
Normal file
@ -0,0 +1,362 @@
|
||||
#
|
||||
# The Qubes OS Project, https://www.qubes-os.org/
|
||||
#
|
||||
# Copyright (C) 2019 Marek Marczykowski-Górecki
|
||||
# <marmarek@invisiblethingslab.com>
|
||||
#
|
||||
# This library 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 library 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
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this library; if not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
import grp
|
||||
import os
|
||||
|
||||
import distutils.version
|
||||
import pyudev
|
||||
import subprocess
|
||||
|
||||
from pyanaconda import iutil
|
||||
from pyanaconda.addons import AddonData
|
||||
from pykickstart.errors import KickstartValueError
|
||||
from pyanaconda.progress import progress_message
|
||||
|
||||
import logging
|
||||
log = logging.getLogger("anaconda")
|
||||
|
||||
__all__ = ['QubesData']
|
||||
|
||||
|
||||
def is_package_installed(pkgname):
|
||||
pkglist = subprocess.check_output(['rpm', '-qa', pkgname])
|
||||
return bool(pkglist)
|
||||
|
||||
def usb_keyboard_present():
|
||||
context = pyudev.Context()
|
||||
keyboards = context.list_devices(subsystem='input', ID_INPUT_KEYBOARD='1')
|
||||
return any([d.get('ID_USB_INTERFACES', False) for d in keyboards])
|
||||
|
||||
def started_from_usb():
|
||||
def get_all_used_devices(dev):
|
||||
stat = os.stat(dev)
|
||||
if stat.st_rdev:
|
||||
# XXX any better idea how to handle device-mapper?
|
||||
sysfs_slaves = '/sys/dev/block/{}:{}/slaves'.format(
|
||||
os.major(stat.st_rdev), os.minor(stat.st_rdev))
|
||||
if os.path.exists(sysfs_slaves):
|
||||
for slave_dev in os.listdir(sysfs_slaves):
|
||||
for d in get_all_used_devices('/dev/{}'.format(slave_dev)):
|
||||
yield d
|
||||
else:
|
||||
yield dev
|
||||
|
||||
context = pyudev.Context()
|
||||
mounts = open('/proc/mounts').readlines()
|
||||
for mount in mounts:
|
||||
device = mount.split(' ')[0]
|
||||
if not os.path.exists(device):
|
||||
continue
|
||||
for dev in get_all_used_devices(device):
|
||||
udev_info = pyudev.Device.from_device_file(context, dev)
|
||||
if udev_info.get('ID_USB_INTERFACES', False):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class QubesData(AddonData):
|
||||
"""
|
||||
Class providing and storing data for the Qubes initial setup addon
|
||||
"""
|
||||
|
||||
bool_options = (
|
||||
'system_vms', 'default_vms', 'whonix_vms', 'whonix_default', 'usbvm',
|
||||
'usbvm_with_netvm', 'skip')
|
||||
|
||||
def __init__(self, name):
|
||||
"""
|
||||
|
||||
:param name: name of the addon
|
||||
:type name: str
|
||||
"""
|
||||
|
||||
super(QubesData, self).__init__(name)
|
||||
|
||||
self.whonix_available = (
|
||||
is_package_installed('qubes-template-whonix-gw*') and
|
||||
is_package_installed('qubes-template-whonix-ws*'))
|
||||
self.usbvm_available = (
|
||||
not usb_keyboard_present() and not started_from_usb())
|
||||
self.system_vms = True
|
||||
self.default_vms = True
|
||||
|
||||
self.whonix_vms = self.whonix_available
|
||||
self.whonix_default = False
|
||||
|
||||
self.usbvm = self.usbvm_available
|
||||
self.usbvm_with_netvm = False
|
||||
|
||||
self.skip = False
|
||||
|
||||
# this is a hack, but initial-setup do not have progress hub or similar
|
||||
# provision for handling lengthy self.execute() call, so we must do it
|
||||
# ourselves
|
||||
self.gui_mode = False
|
||||
self.thread_dialog = None
|
||||
|
||||
# choose latest fedora template
|
||||
fedora_tpls = sorted(
|
||||
name for name in os.listdir('/var/lib/qubes/vm-templates')
|
||||
if 'fedora' in name)
|
||||
if fedora_tpls:
|
||||
self.default_template = fedora_tpls[-1]
|
||||
else:
|
||||
print(
|
||||
'ERROR: No Fedora template is installed, '
|
||||
'cannot set default template!')
|
||||
self.default_template = None
|
||||
|
||||
self.qubes_user = None
|
||||
|
||||
self.seen = False
|
||||
|
||||
def handle_header(self, lineno, args):
|
||||
pass
|
||||
|
||||
def handle_line(self, line):
|
||||
"""
|
||||
|
||||
:param line:
|
||||
:return:
|
||||
"""
|
||||
|
||||
try:
|
||||
(param, value) = line.strip().split(maxsplit=1)
|
||||
except ValueError:
|
||||
raise KickstartValueError('invalid line: %s' % line)
|
||||
if param in self.bool_options:
|
||||
if value.lower() not in ('true', 'false'):
|
||||
raise KickstartValueError(
|
||||
'invalid value for bool property: %s' % line)
|
||||
bool_value = value.lower() == 'true'
|
||||
setattr(self, param, bool_value)
|
||||
elif param == 'default_template':
|
||||
self.default_template = value
|
||||
else:
|
||||
raise KickstartValueError('invalid parameter: %s' % param)
|
||||
self.seen = True
|
||||
|
||||
def __str__(self):
|
||||
section = "%addon {}\n".format(self.name)
|
||||
|
||||
for param in self.bool_options:
|
||||
section += "{} {!s}\n".format(param, getattr(self, param))
|
||||
|
||||
section += 'default_template {}\n'.format(self.default_template)
|
||||
|
||||
section += '%end\n'
|
||||
return section
|
||||
|
||||
def execute(self, storage, ksdata, instClass, users, payload):
|
||||
if self.gui_mode:
|
||||
from ..gui import ThreadDialog
|
||||
self.thread_dialog = ThreadDialog(
|
||||
"Qubes OS Setup", self.do_setup, ())
|
||||
self.thread_dialog.run()
|
||||
self.thread_dialog.destroy()
|
||||
else:
|
||||
self.do_setup()
|
||||
|
||||
def set_stage(self, stage):
|
||||
if self.thread_dialog is not None:
|
||||
self.thread_dialog.set_text(stage)
|
||||
else:
|
||||
print(stage)
|
||||
|
||||
def do_setup(self):
|
||||
qubes_gid = grp.getgrnam('qubes').gr_gid
|
||||
|
||||
qubes_users = grp.getgrnam('qubes').gr_mem
|
||||
|
||||
if len(qubes_users) < 1:
|
||||
raise Exception(
|
||||
"You must create a user account to create default VMs.")
|
||||
else:
|
||||
self.qubes_user = qubes_users[0]
|
||||
|
||||
if self.skip:
|
||||
return
|
||||
|
||||
errors = []
|
||||
|
||||
os.setgid(qubes_gid)
|
||||
os.umask(0o0007)
|
||||
|
||||
self.configure_default_kernel()
|
||||
|
||||
# Finish template(s) installation, because it wasn't fully possible
|
||||
# from anaconda (it isn't possible to start a VM there).
|
||||
# This is specific to firstboot, not general configuration.
|
||||
for template in os.listdir('/var/lib/qubes/vm-templates'):
|
||||
try:
|
||||
self.configure_template(template,
|
||||
'/var/lib/qubes/vm-templates/' + template)
|
||||
except Exception as e:
|
||||
errors.append(('Templates', str(e)))
|
||||
|
||||
self.configure_dom0()
|
||||
self.configure_default_template()
|
||||
self.configure_qubes()
|
||||
if self.system_vms:
|
||||
self.configure_network()
|
||||
if self.usbvm and not self.usbvm_with_netvm:
|
||||
# Workaround for #1464 (so qvm.start from salt can't be used)
|
||||
self.run_command(['systemctl', 'start', 'qubes-vm@sys-usb.service'])
|
||||
|
||||
try:
|
||||
self.configure_default_dvm()
|
||||
except Exception as e:
|
||||
errors.append(('Default DVM', str(e)))
|
||||
|
||||
if errors:
|
||||
msg = ""
|
||||
for (stage, error) in errors:
|
||||
msg += "{} failed:\n{}\n\n".format(stage, error)
|
||||
|
||||
raise Exception(msg)
|
||||
|
||||
def run_command(self, command, stdin=None, ignore_failure=False):
|
||||
process_error = None
|
||||
|
||||
try:
|
||||
sys_root = iutil.getSysroot()
|
||||
|
||||
cmd = iutil.startProgram(command,
|
||||
stderr=subprocess.PIPE,
|
||||
stdin=stdin,
|
||||
root=sys_root)
|
||||
|
||||
(stdout, stderr) = cmd.communicate()
|
||||
|
||||
stdout = stdout.decode("utf-8")
|
||||
stderr = stderr.decode("utf-8")
|
||||
|
||||
if not ignore_failure and cmd.returncode != 0:
|
||||
process_error = "{} failed:\nstdout: \"{}\"\nstderr: \"{}\"".format(command, stdout, stderr)
|
||||
|
||||
except Exception as e:
|
||||
process_error = str(e)
|
||||
|
||||
if process_error:
|
||||
log.error(process_error)
|
||||
raise Exception(process_error)
|
||||
|
||||
return (stdout, stderr)
|
||||
|
||||
def configure_default_kernel(self):
|
||||
self.set_stage("Setting up default kernel")
|
||||
installed_kernels = os.listdir('/var/lib/qubes/vm-kernels')
|
||||
installed_kernels = [distutils.version.LooseVersion(x) for x in installed_kernels]
|
||||
default_kernel = str(sorted(installed_kernels)[-1])
|
||||
self.run_command([
|
||||
'/usr/bin/qubes-prefs', 'default-kernel', default_kernel])
|
||||
|
||||
def configure_dom0(self):
|
||||
self.set_stage("Setting up administration VM (dom0)")
|
||||
|
||||
for service in ['rdisc', 'kdump', 'libvirt-guests', 'salt-minion']:
|
||||
self.run_command(['systemctl', 'disable', '{}.service'.format(service) ], ignore_failure=True)
|
||||
self.run_command(['systemctl', 'stop', '{}.service'.format(service) ], ignore_failure=True)
|
||||
|
||||
def configure_qubes(self):
|
||||
self.set_stage('Executing qubes configuration')
|
||||
|
||||
states = []
|
||||
if self.system_vms:
|
||||
states.extend(
|
||||
('qvm.sys-net', 'qvm.sys-firewall', 'qvm.default-dispvm'))
|
||||
if self.default_vms:
|
||||
states.extend(
|
||||
('qvm.personal', 'qvm.work', 'qvm.untrusted', 'qvm.vault'))
|
||||
if self.whonix_available and self.whonix_vms:
|
||||
states.extend(
|
||||
('qvm.sys-whonix', 'qvm.anon-whonix'))
|
||||
if self.whonix_default:
|
||||
states.append('qvm.updates-via-whonix')
|
||||
if self.usbvm:
|
||||
states.append('qvm.sys-usb')
|
||||
if self.usbvm_with_netvm:
|
||||
states.append('pillar.qvm.sys-net-as-usbvm')
|
||||
|
||||
try:
|
||||
# get rid of initial entries (from package installation time)
|
||||
os.rename('/var/log/salt/minion', '/var/log/salt/minion.install')
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# Refresh minion configuration to make sure all installed formulas are included
|
||||
self.run_command(['qubesctl', 'saltutil.clear_cache'])
|
||||
self.run_command(['qubesctl', 'saltutil.sync_all'])
|
||||
|
||||
for state in states:
|
||||
print("Setting up state: {}".format(state))
|
||||
if state.startswith('pillar.'):
|
||||
self.run_command(['qubesctl', 'top.enable',
|
||||
state[len('pillar.'):], 'pillar=True'])
|
||||
else:
|
||||
self.run_command(['qubesctl', 'top.enable', state])
|
||||
|
||||
try:
|
||||
self.run_command(['qubesctl', '--all', 'state.highstate'])
|
||||
# After successful call disable all the states to not leave them
|
||||
# enabled, to not interfere with later user changes (like assigning
|
||||
# additional PCI devices)
|
||||
for state in states:
|
||||
if not state.startswith('pillar.'):
|
||||
self.run_command(['qubesctl', 'top.disable', state])
|
||||
except Exception:
|
||||
raise Exception(
|
||||
("Qubes initial configuration failed. Login to the system and " +
|
||||
"check /var/log/salt/minion for details. " +
|
||||
"You can retry configuration by calling " +
|
||||
"'sudo qubesctl state.highstate' in dom0 (you will get " +
|
||||
"detailed state there)."))
|
||||
|
||||
def configure_default_template(self):
|
||||
self.set_stage('Setting default template')
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'default-template', self.default_template])
|
||||
|
||||
def configure_default_dvm(self):
|
||||
self.set_stage("Creating default DisposableVM")
|
||||
|
||||
dispvm_name = self.default_template + '-dvm'
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'default-dispvm',
|
||||
dispvm_name])
|
||||
|
||||
def configure_network(self):
|
||||
self.set_stage('Setting up networking')
|
||||
|
||||
default_netvm = 'sys-firewall'
|
||||
updatevm = default_netvm
|
||||
if self.whonix_default:
|
||||
updatevm = 'sys-whonix'
|
||||
|
||||
self.run_command(['/usr/bin/qvm-prefs', 'sys-firewall', 'netvm', 'sys-net'])
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'default-netvm', default_netvm])
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'updatevm', updatevm])
|
||||
self.run_command(['/usr/bin/qubes-prefs', 'clockvm', 'sys-net'])
|
||||
self.run_command(['/usr/bin/qvm-start', default_netvm])
|
||||
|
||||
def configure_template(self, template, path):
|
||||
self.set_stage("Configuring TemplateVM {}".format(template))
|
||||
self.run_command([
|
||||
'qvm-template-postprocess', '--really', 'post-install', template, path])
|
||||
|
@ -27,11 +27,11 @@
|
||||
_ = lambda x: x
|
||||
N_ = lambda x: x
|
||||
|
||||
import subprocess
|
||||
|
||||
from pyanaconda.ui.categories.system import SystemCategory
|
||||
from pyanaconda.ui.tui.spokes import NormalTUISpoke
|
||||
from pyanaconda.constants_text import INPUT_PROCESSED, INPUT_DISCARDED
|
||||
from simpleline.render.containers import ListColumnContainer
|
||||
from simpleline.render.widgets import CheckboxWidget
|
||||
from simpleline.render.screen import InputState
|
||||
from pyanaconda.ui.common import FirstbootOnlySpokeMixIn
|
||||
|
||||
# export only the HelloWorldSpoke and HelloWorldEditSpoke classes
|
||||
@ -51,21 +51,14 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalTUISpoke):
|
||||
|
||||
### class attributes defined by API ###
|
||||
|
||||
# title of the spoke
|
||||
title = N_("Qubes OS")
|
||||
|
||||
# category this spoke belongs to
|
||||
category = SystemCategory
|
||||
|
||||
def __init__(self, app, data, storage, payload, instclass):
|
||||
def __init__(self, data, storage, payload, instclass):
|
||||
"""
|
||||
:see: pyanaconda.ui.tui.base.UIScreen
|
||||
:see: pyanaconda.ui.tui.base.App
|
||||
:param app: reference to application which is a main class for TUI
|
||||
screen handling, it is responsible for mainloop control
|
||||
and keeping track of the stack where all TUI screens are
|
||||
scheduled
|
||||
:type app: instance of pyanaconda.ui.tui.base.App
|
||||
:param data: data object passed to every spoke to load/store data
|
||||
from/to it
|
||||
:type data: pykickstart.base.BaseHandler
|
||||
@ -79,9 +72,22 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalTUISpoke):
|
||||
|
||||
"""
|
||||
|
||||
NormalTUISpoke.__init__(self, app, data, storage, payload, instclass)
|
||||
NormalTUISpoke.__init__(self, data, storage, payload, instclass)
|
||||
|
||||
self.initialize_start()
|
||||
|
||||
# title of the spoke
|
||||
self.title = N_("Qubes OS")
|
||||
|
||||
self._container = None
|
||||
|
||||
self.qubes_data = self.data.addons.org_qubes_os_initial_setup
|
||||
|
||||
for attr in self.qubes_data.bool_options:
|
||||
setattr(self, '_' + attr, getattr(self.qubes_data, attr))
|
||||
|
||||
self.initialize_done()
|
||||
|
||||
self.done = False
|
||||
|
||||
def initialize(self):
|
||||
"""
|
||||
@ -95,6 +101,10 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalTUISpoke):
|
||||
|
||||
NormalTUISpoke.initialize(self)
|
||||
|
||||
def _add_checkbox(self, name, title):
|
||||
w = CheckboxWidget(title=title, completed=getattr(self, name))
|
||||
self._container.add(w, self._set_checkbox, name)
|
||||
|
||||
def refresh(self, args=None):
|
||||
"""
|
||||
The refresh method that is called every time the spoke is displayed.
|
||||
@ -110,8 +120,44 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalTUISpoke):
|
||||
:rtype: bool
|
||||
|
||||
"""
|
||||
super(QubesOsSpoke, self).refresh()
|
||||
self._container = ListColumnContainer(1)
|
||||
|
||||
return True
|
||||
w = CheckboxWidget(title=_('Create default system qubes '
|
||||
'(sys-net, sys-firewall, default DispVM)'),
|
||||
completed=self._system_vms)
|
||||
self._container.add(w, self._set_checkbox, '_system_vms')
|
||||
w = CheckboxWidget(title=_('Create default application qubes '
|
||||
'(personal, work, untrusted, vault)'),
|
||||
completed=self._default_vms)
|
||||
self._container.add(w, self._set_checkbox, '_default_vms')
|
||||
if self.qubes_data.whonix_available:
|
||||
w = CheckboxWidget(
|
||||
title=_('Create Whonix Gateway and Workstation qubes '
|
||||
'(sys-whonix, anon-whonix)'),
|
||||
completed=self._whonix_vms)
|
||||
self._container.add(w, self._set_checkbox, '_whonix_vms')
|
||||
if self._whonix_vms:
|
||||
w = CheckboxWidget(
|
||||
title=_('Enable system and template updates over the Tor anonymity '
|
||||
'network using Whonix'),
|
||||
completed=self._whonix_default)
|
||||
self._container.add(w, self._set_checkbox, '_whonix_default')
|
||||
if self.qubes_data.usbvm_available:
|
||||
w = CheckboxWidget(
|
||||
title=_('Create USB qube holding all USB controllers (sys-usb)'),
|
||||
completed=self._usbvm)
|
||||
self._container.add(w, self._set_checkbox, '_usbvm')
|
||||
if self._usbvm:
|
||||
w = CheckboxWidget(
|
||||
title=_('Use sys-net qube for both networking and USB devices'),
|
||||
completed=self._usbvm_with_netvm)
|
||||
self._container.add(w, self._set_checkbox, '_usbvm_with_netvm')
|
||||
|
||||
self.window.add_with_separator(self._container)
|
||||
|
||||
def _set_checkbox(self, name):
|
||||
setattr(self, name, not getattr(self, name))
|
||||
|
||||
def apply(self):
|
||||
"""
|
||||
@ -120,10 +166,10 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalTUISpoke):
|
||||
|
||||
"""
|
||||
|
||||
proc = subprocess.Popen(["/usr/share/qubes/firstboot-qubes-text"])
|
||||
proc.wait()
|
||||
for attr in self.qubes_data.bool_options:
|
||||
setattr(self.qubes_data, attr, getattr(self, '_' + attr))
|
||||
|
||||
self.done = True
|
||||
self.qubes_data.seen = True
|
||||
|
||||
def execute(self):
|
||||
"""
|
||||
@ -147,7 +193,7 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalTUISpoke):
|
||||
|
||||
"""
|
||||
|
||||
return self.done
|
||||
return self.qubes_data.seen
|
||||
|
||||
@property
|
||||
def status(self):
|
||||
@ -179,28 +225,8 @@ class QubesOsSpoke(FirstbootOnlySpokeMixIn, NormalTUISpoke):
|
||||
|
||||
"""
|
||||
|
||||
if key:
|
||||
# Do something with the user's input.
|
||||
pass
|
||||
if self._container.process_user_input(key):
|
||||
self.apply()
|
||||
return InputState.PROCESSED_AND_REDRAW
|
||||
|
||||
# no other actions scheduled, apply changes
|
||||
self.apply()
|
||||
|
||||
# close the current screen (remove it from the stack)
|
||||
self.close()
|
||||
return INPUT_PROCESSED
|
||||
|
||||
def prompt(self, args=None):
|
||||
"""
|
||||
The prompt method that is called by the main loop to get the prompt
|
||||
for this screen.
|
||||
|
||||
:param args: optional argument that can be passed to App.switch_screen*
|
||||
methods
|
||||
:type args: anything
|
||||
:return: text that should be used in the prompt for the input
|
||||
:rtype: unicode|None
|
||||
|
||||
"""
|
||||
|
||||
return _("Please press enter to start Qubes OS configuration.")
|
||||
return super().input(args, key)
|
||||
|
@ -1,5 +1,5 @@
|
||||
Name: qubes-anaconda-addon
|
||||
Version: 4.0.9
|
||||
Version: 4.0.11
|
||||
Release: 1%{?dist}
|
||||
Summary: Anaconda addon useful for Qubes OS specific setup procedures
|
||||
|
||||
@ -25,16 +25,12 @@ at first boot time.
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
install -d $RPM_BUILD_ROOT/%{_datadir}/qubes
|
||||
install --mode 0755 firstboot-qubes-text $RPM_BUILD_ROOT/%{_datadir}/qubes/firstboot-qubes-text
|
||||
|
||||
install -d $RPM_BUILD_ROOT/%{_datadir}/anaconda/addons
|
||||
cp -a org_qubes_os_initial_setup $RPM_BUILD_ROOT/%{_datadir}/anaconda/addons/
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc LICENSE README
|
||||
%{_datadir}/qubes/firstboot-qubes-text
|
||||
%dir %{_datadir}/anaconda/addons/org_qubes_os_initial_setup
|
||||
%{_datadir}/anaconda/addons/org_qubes_os_initial_setup/*
|
||||
|
||||
|
@ -1398,24 +1398,31 @@
|
||||
<packagereq type="mandatory">qubes-gui-dom0</packagereq>
|
||||
<packagereq type="mandatory">qubes-desktop-linux-manager</packagereq>
|
||||
<packagereq type="mandatory">qubes-mgmt-salt-dom0</packagereq>
|
||||
<packagereq type="mandatory">qubes-template-fedora-29</packagereq>
|
||||
<packagereq type="mandatory">qubes-template-fedora-30</packagereq>
|
||||
<packagereq type="default">qubes-gpg-split-dom0</packagereq>
|
||||
<packagereq type="default">qubes-img-converter-dom0</packagereq>
|
||||
<packagereq type="default">qubes-input-proxy</packagereq>
|
||||
<packagereq type="default">qubes-pdf-converter-dom0</packagereq>
|
||||
<packagereq type="default">qubes-usb-proxy-dom0</packagereq>
|
||||
<packagereq type="default">libvirt-client</packagereq>
|
||||
<!--
|
||||
We add 'kernel-latest' and 'kernel-latest-qubes-vm' only as
|
||||
optional because it is not included in stable official releases
|
||||
but only in testing releases with latest kernels
|
||||
-->
|
||||
<packagereq type="optional">kernel-latest</packagereq>
|
||||
<packagereq type="optional">kernel-latest-qubes-vm</packagereq>
|
||||
</packagelist>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<id>debian</id>
|
||||
<name>Debian 9 (stretch) template</name>
|
||||
<description>Debian 9 (stretch) template</description>
|
||||
<name>Debian 10 (buster) template</name>
|
||||
<description>Debian 10 (buster) template</description>
|
||||
<default>true</default>
|
||||
<uservisible>true</uservisible>
|
||||
<packagelist>
|
||||
<packagereq>qubes-template-debian-9</packagereq>
|
||||
<packagereq>qubes-template-debian-10</packagereq>
|
||||
</packagelist>
|
||||
</group>
|
||||
|
||||
@ -1426,8 +1433,8 @@
|
||||
<description>Whonix templates (gateway and workstation)</description>
|
||||
<uservisible>true</uservisible>
|
||||
<packagelist>
|
||||
<packagereq>qubes-template-whonix-gw-14</packagereq>
|
||||
<packagereq>qubes-template-whonix-ws-14</packagereq>
|
||||
<packagereq>qubes-template-whonix-gw-15</packagereq>
|
||||
<packagereq>qubes-template-whonix-ws-15</packagereq>
|
||||
</packagelist>
|
||||
</group>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
[qubes-dom0-current]
|
||||
name = Qubes Dom0 Repository (updates)
|
||||
#baseurl = https://yum.qubes-os.org/r$releasever/current/dom0/%DIST%
|
||||
#baseurl = http://yum.sik5nlgfc5qylnnsr57qrbm64zbdx6t4lreyhpon3ychmxmiem7tioad.onion/r$releasever/current/dom0/%DIST%
|
||||
#baseurl = http://yum.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r$releasever/current/dom0/%DIST%
|
||||
metalink = https://yum.qubes-os.org/r$releasever/current/dom0/%DIST%/repodata/repomd.xml.metalink
|
||||
enabled = 1
|
||||
metadata_expire = 7d
|
||||
@ -11,7 +11,7 @@ gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-$releasever-primary
|
||||
[qubes-dom0-current-testing]
|
||||
name = Qubes Dom0 Repository (updates-testing)
|
||||
#baseurl = https://yum.qubes-os.org/r$releasever/current-testing/dom0/%DIST%
|
||||
#baseurl = http://yum.sik5nlgfc5qylnnsr57qrbm64zbdx6t4lreyhpon3ychmxmiem7tioad.onion/r$releasever/current-testing/dom0/%DIST%
|
||||
#baseurl = http://yum.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r$releasever/current-testing/dom0/%DIST%
|
||||
metalink = https://yum.qubes-os.org/r$releasever/current-testing/dom0/%DIST%/repodata/repomd.xml.metalink
|
||||
enabled = 0
|
||||
metadata_expire = 7d
|
||||
@ -21,7 +21,7 @@ gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-$releasever-primary
|
||||
[qubes-dom0-security-testing]
|
||||
name = Qubes Dom0 Repository (security-testing)
|
||||
#baseurl = https://yum.qubes-os.org/r$releasever/security-testing/dom0/%DIST%
|
||||
#baseurl = http://yum.sik5nlgfc5qylnnsr57qrbm64zbdx6t4lreyhpon3ychmxmiem7tioad.onion/r$releasever/security-testing/dom0/%DIST%
|
||||
#baseurl = http://yum.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r$releasever/security-testing/dom0/%DIST%
|
||||
metalink = https://yum.qubes-os.org/r$releasever/security-testing/dom0/%DIST%/repodata/repomd.xml.metalink
|
||||
enabled = 0
|
||||
metadata_expire = 7d
|
||||
@ -31,7 +31,7 @@ gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-$releasever-primary
|
||||
[qubes-dom0-unstable]
|
||||
name = Qubes Dom0 Repository (unstable)
|
||||
#baseurl = https://yum.qubes-os.org/r$releasever/unstable/dom0/%DIST%
|
||||
#baseurl = http://yum.sik5nlgfc5qylnnsr57qrbm64zbdx6t4lreyhpon3ychmxmiem7tioad.onion/r$releasever/unstable/dom0/%DIST%
|
||||
#baseurl = http://yum.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r$releasever/unstable/dom0/%DIST%
|
||||
metalink = https://yum.qubes-os.org/r$releasever/unstable/dom0/%DIST%/repodata/repomd.xml.metalink
|
||||
enabled = 0
|
||||
metadata_expire = 7d
|
||||
|
@ -5,7 +5,7 @@
|
||||
Summary: Qubes release files
|
||||
Name: qubes-release
|
||||
Version: %{dist_version}
|
||||
Release: 7
|
||||
Release: 8
|
||||
License: GPLv2
|
||||
Group: System Environment/Base
|
||||
Source0: %{name}-%{version}.tar.bz2
|
||||
|
@ -1,7 +1,7 @@
|
||||
[qubes-templates-itl]
|
||||
name = Qubes Templates repository
|
||||
#baseurl = https://yum.qubes-os.org/r$releasever/templates-itl
|
||||
#baseurl = http://yum.sik5nlgfc5qylnnsr57qrbm64zbdx6t4lreyhpon3ychmxmiem7tioad.onion/r$releasever/templates-itl
|
||||
#baseurl = http://yum.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r$releasever/templates-itl
|
||||
metalink = https://yum.qubes-os.org/r$releasever/templates-itl/repodata/repomd.xml.metalink
|
||||
enabled = 1
|
||||
fastestmirror = 1
|
||||
@ -12,7 +12,7 @@ gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-$releasever-primary
|
||||
[qubes-templates-itl-testing]
|
||||
name = Qubes Templates repository
|
||||
#baseurl = https://yum.qubes-os.org/r$releasever/templates-itl-testing
|
||||
#baseurl = http://yum.sik5nlgfc5qylnnsr57qrbm64zbdx6t4lreyhpon3ychmxmiem7tioad.onion/r$releasever/templates-itl-testing
|
||||
#baseurl = http://yum.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r$releasever/templates-itl-testing
|
||||
metalink = https://yum.qubes-os.org/r$releasever/templates-itl-testing/repodata/repomd.xml.metalink
|
||||
enabled = 0
|
||||
fastestmirror = 1
|
||||
@ -22,7 +22,7 @@ gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-$releasever-primary
|
||||
[qubes-templates-community]
|
||||
name = Qubes Community Templates repository
|
||||
#baseurl = https://yum.qubes-os.org/r$releasever/templates-community
|
||||
#baseurl = http://yum.sik5nlgfc5qylnnsr57qrbm64zbdx6t4lreyhpon3ychmxmiem7tioad.onion/r$releasever/templates-community
|
||||
#baseurl = http://yum.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r$releasever/templates-community
|
||||
metalink = https://yum.qubes-os.org/r$releasever/templates-community/repodata/repomd.xml.metalink
|
||||
enabled = 0
|
||||
fastestmirror = 1
|
||||
@ -33,7 +33,7 @@ gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-$releasever-templates-communi
|
||||
[qubes-templates-community-testing]
|
||||
name = Qubes Community Templates repository
|
||||
#baseurl = https://yum.qubes-os.org/r$releasever/templates-community-testing
|
||||
#baseurl = http://yum.sik5nlgfc5qylnnsr57qrbm64zbdx6t4lreyhpon3ychmxmiem7tioad.onion/r$releasever/templates-community-testing
|
||||
#baseurl = http://yum.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r$releasever/templates-community-testing
|
||||
metalink = https://yum.qubes-os.org/r$releasever/templates-community-testing/repodata/repomd.xml.metalink
|
||||
enabled = 0
|
||||
fastestmirror = 1
|
||||
|
@ -1,8 +1,9 @@
|
||||
createrepo="$(which createrepo_c createrepo | head -n 1)"
|
||||
for repo in dom0-updates installer qubes-dom0 ; do
|
||||
echo "---> Cleaning up repo: $repo..."
|
||||
rm -f $repo/rpm/*.rpm
|
||||
rm -f $repo/repodata/*
|
||||
createrepo -q $repo
|
||||
$createrepo -q $repo
|
||||
done
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user