From d9d7a69c273f72bff242559ba18a35bd6c99d5ba Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 22 Jun 2011 00:44:48 +0200 Subject: [PATCH] dom0+vm: Tools for downloading dom0 update by VM (#198) Mainly 4 parts: - scripts for providing rpmdb and yum repos to VM (choosen by qvm-set-updatevm) - VM script for downloading updates (qubes_download_dom0_updates.sh) - qfile-dom0-unpacker which receive updates, check signatures and place its in dom0 local yum repo - qvm-dom0-upgrade which calls all of above and after all yum gpk-update-viewer Besides qvm-dom0-upgrade, updates are checked every 6h and user is prompted if want to download it. At dom0 side gpk-update-icon (disabled yet) should notice new updates in "local" repo. --- appvm/Makefile | 4 +- {appvm => common}/copy_file.c | 0 {appvm => common}/crc32.c | 0 {appvm => common}/crc32.h | 0 {appvm => common}/filecopy.h | 0 common/qubes_download_dom0_updates.sh | 51 +++++++++++++ {appvm => common}/unpack.c | 0 dom0/aux-tools/.gitignore | 1 + dom0/aux-tools/Makefile | 4 + dom0/aux-tools/qfile-dom0-unpacker.c | 86 ++++++++++++++++++++++ dom0/aux-tools/sync_rpmdb_updatevm.sh | 10 +++ dom0/misc/qubes_sync_rpmdb_updatevm.action | 1 + dom0/qubes-cached.repo | 5 ++ dom0/qvm-core/qubes.py | 31 +++++++- dom0/qvm-tools/qvm-dom0-upgrade | 20 +++++ dom0/qvm-tools/qvm-get-updatevm | 39 ++++++++++ dom0/qvm-tools/qvm-set-updatevm | 46 ++++++++++++ dom0/restore/qfile-daemon | 40 ++++++++++ rpm_spec/core-commonvm.spec | 3 + rpm_spec/core-dom0.spec | 20 +++++ 20 files changed, 358 insertions(+), 3 deletions(-) rename {appvm => common}/copy_file.c (100%) rename {appvm => common}/crc32.c (100%) rename {appvm => common}/crc32.h (100%) rename {appvm => common}/filecopy.h (100%) create mode 100755 common/qubes_download_dom0_updates.sh rename {appvm => common}/unpack.c (100%) create mode 100644 dom0/aux-tools/.gitignore create mode 100644 dom0/aux-tools/Makefile create mode 100644 dom0/aux-tools/qfile-dom0-unpacker.c create mode 100755 dom0/aux-tools/sync_rpmdb_updatevm.sh create mode 100644 dom0/misc/qubes_sync_rpmdb_updatevm.action create mode 100644 dom0/qubes-cached.repo create mode 100755 dom0/qvm-tools/qvm-dom0-upgrade create mode 100755 dom0/qvm-tools/qvm-get-updatevm create mode 100755 dom0/qvm-tools/qvm-set-updatevm diff --git a/appvm/Makefile b/appvm/Makefile index df9989e2..d1e1040f 100644 --- a/appvm/Makefile +++ b/appvm/Makefile @@ -5,9 +5,9 @@ dvm_file_editor: dvm_file_editor.o ../common/ioall.o $(CC) -pie -g -o $@ $^ qfile-agent-dvm: qfile-agent-dvm.o ../common/ioall.o ../common/gui-fatal.o $(CC) -pie -g -o $@ $^ -qfile-agent: qfile-agent.o ../common/ioall.o ../common/gui-fatal.o copy_file.o crc32.o +qfile-agent: qfile-agent.o ../common/ioall.o ../common/gui-fatal.o ../common/copy_file.o ../common/crc32.o $(CC) -pie -g -o $@ $^ -qfile-unpacker: qfile-unpacker.o ../common/ioall.o ../common/gui-fatal.o copy_file.o unpack.o crc32.o +qfile-unpacker: qfile-unpacker.o ../common/ioall.o ../common/gui-fatal.o ../common/copy_file.o ../common/unpack.o ../common/crc32.o $(CC) -pie -g -o $@ $^ clean: diff --git a/appvm/copy_file.c b/common/copy_file.c similarity index 100% rename from appvm/copy_file.c rename to common/copy_file.c diff --git a/appvm/crc32.c b/common/crc32.c similarity index 100% rename from appvm/crc32.c rename to common/crc32.c diff --git a/appvm/crc32.h b/common/crc32.h similarity index 100% rename from appvm/crc32.h rename to common/crc32.h diff --git a/appvm/filecopy.h b/common/filecopy.h similarity index 100% rename from appvm/filecopy.h rename to common/filecopy.h diff --git a/common/qubes_download_dom0_updates.sh b/common/qubes_download_dom0_updates.sh new file mode 100755 index 00000000..488eecb7 --- /dev/null +++ b/common/qubes_download_dom0_updates.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +DOM0_UPDATES_DIR=/var/lib/qubes/dom0-updates + +DOIT=0 +GUI=1 +while [ -n "$1" ]; do + if [ "x--doit" = "x$1" ]; then + DOIT=1 + elif [ "x--nogui" = "x$1" ]; then + GUI=0 + fi + shift +done + +if ! [ -d "$DOM0_UPDATES_DIR" ]; then + echo "Dom0 updates dir does not exists: $DOM0_UPDATES_DIR" + exit 1 +fi + +mkdir -p $DOM0_UPDATES_DIR/etc +cp /etc/yum.conf $DOM0_UPDATES_DIR/etc/ + +echo "Checking for updates..." +PKGLIST=`yum --installroot $DOM0_UPDATES_DIR check-update -q | cut -f 1 -d ' '` + +if [ -z $PKGLIST ]; then + # No new updates + exit 0 +fi + +if [ "$DOIT" != "1" ]; then + zenity --question --title="Qubes Dom0 updates" \ + --text="Updates for dom0 available. Do you want to download its now?" || exit 0 +fi + +mkdir -p "$DOM0_UPDATES_DIR/packages" + +set -e + +if [ "$GUI" = 1 ]; then + ( echo "1" + yumdownloader --destdir "$DOM0_UPDATES_DIR/packages" --installroot "$DOM0_UPDATES_DIR" $PKGLIST + echo 100 ) | zenity --progress --pulsate --auto-close --auto-kill \ + --text="Downloading updates for Dom0, please wait..." --title="Qubes Dom0 updates" +else + yumdownloader --destdir "$DOM0_UPDATES_DIR/packages" --installroot "$DOM0_UPDATES_DIR" $PKGLIST +fi + +# qvm-copy-to-vm works only from user +su -c "qvm-copy-to-vm @dom0updates $DOM0_UPDATES_DIR/packages/*.rpm" user diff --git a/appvm/unpack.c b/common/unpack.c similarity index 100% rename from appvm/unpack.c rename to common/unpack.c diff --git a/dom0/aux-tools/.gitignore b/dom0/aux-tools/.gitignore new file mode 100644 index 00000000..bc50fb19 --- /dev/null +++ b/dom0/aux-tools/.gitignore @@ -0,0 +1 @@ +qfile-dom0-unpacker diff --git a/dom0/aux-tools/Makefile b/dom0/aux-tools/Makefile new file mode 100644 index 00000000..6e2b40d1 --- /dev/null +++ b/dom0/aux-tools/Makefile @@ -0,0 +1,4 @@ +CC=gcc +CFLAGS=-g -Wall -I../../common -fPIC -pie +qfile-dom0-unpacker: qfile-dom0-unpacker.o ../../common/ioall.o ../../common/gui-fatal.o ../../common/copy_file.o ../../common/unpack.o ../../common/crc32.o + $(CC) -pie -g -o $@ $^ diff --git a/dom0/aux-tools/qfile-dom0-unpacker.c b/dom0/aux-tools/qfile-dom0-unpacker.c new file mode 100644 index 00000000..8ad8261a --- /dev/null +++ b/dom0/aux-tools/qfile-dom0-unpacker.c @@ -0,0 +1,86 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "filecopy.h" +int prepare_creds_return_uid(char *username) +{ + struct passwd *pwd; + pwd = getpwnam(username); + if (!pwd) { + perror("getpwnam"); + exit(1); + } + setenv("HOME", pwd->pw_dir, 1); + setenv("USER", username, 1); + setgid(pwd->pw_gid); + initgroups(username, pwd->pw_gid); + setfsuid(pwd->pw_uid); + return pwd->pw_uid; +} + +void wait_for_child(int statusfd) +{ + int status; + if (read(statusfd, &status, sizeof status)!=sizeof status) + gui_fatal("File copy error: Internal error reading status from unpacker"); + errno = status; + switch (status) { + case LEGAL_EOF: break; + case 0: gui_fatal("File copy: Connection terminated unexpectedly"); break; + case EINVAL: gui_fatal("File copy: Corrupted data from packer"); break; + case EEXIST: gui_fatal("File copy: not overwriting existing file. Clean ~/incoming, and retry copy"); break; + default: gui_fatal("File copy"); + } +} + +extern void do_unpack(int); + +int main(int argc, char ** argv) +{ + char *incoming_dir; + int pipefds[2]; + int uid; + + if (argc < 3) { + fprintf(stderr, "Invalid parameters, usage: %s user dir\n", argv[0]); + exit(1); + } + + pipe(pipefds); + + uid = prepare_creds_return_uid(argv[1]); + + incoming_dir = argv[2]; + mkdir(incoming_dir, 0700); + if (chdir(incoming_dir)) + gui_fatal("Error chdir to %s", incoming_dir); + switch (fork()) { + case -1: + perror("fork"); + exit(1); + case 0: + if (chroot(incoming_dir)) //impossible + gui_fatal("Error chroot to %s", incoming_dir); + setuid(uid); + close(pipefds[0]); + do_unpack(pipefds[1]); + exit(0); + default:; + } + + setuid(uid); + close(pipefds[1]); + wait_for_child(pipefds[0]); + + return 0; +} diff --git a/dom0/aux-tools/sync_rpmdb_updatevm.sh b/dom0/aux-tools/sync_rpmdb_updatevm.sh new file mode 100755 index 00000000..19c98214 --- /dev/null +++ b/dom0/aux-tools/sync_rpmdb_updatevm.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +UPDATEVM=`qvm-get-updatevm` + +if [ -n "$UPDATEVM" ]; then + qvm-run -u root --pass_io --localcmd='tar c /var/lib/rpm /etc/yum.repos.d' "$UPDATEVM" 'tar x -C /var/lib/qubes/dom0-updates' +fi + +# Ignore errors (eg VM not running) +exit 0 diff --git a/dom0/misc/qubes_sync_rpmdb_updatevm.action b/dom0/misc/qubes_sync_rpmdb_updatevm.action new file mode 100644 index 00000000..d56c2af3 --- /dev/null +++ b/dom0/misc/qubes_sync_rpmdb_updatevm.action @@ -0,0 +1 @@ +*:any:/usr/lib/qubes/sync_rpmdb_updatevm.sh diff --git a/dom0/qubes-cached.repo b/dom0/qubes-cached.repo new file mode 100644 index 00000000..948d4876 --- /dev/null +++ b/dom0/qubes-cached.repo @@ -0,0 +1,5 @@ +[qubes-dom0-cached] +name = Qubes OS Repository for Dom0 +baseurl = file:///var/lib/qubes/updates +gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-1-primary +gpgcheck = 1 diff --git a/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index 8f333b4d..36fdafaf 100755 --- a/dom0/qvm-core/qubes.py +++ b/dom0/qvm-core/qubes.py @@ -74,6 +74,8 @@ default_firewall_conf_file = "firewall.xml" default_memory = 400 default_servicevm_vcpus = 1 +dom0_update_check_interval = 6*3600 + # do not allow to start a new AppVM if Dom0 mem was to be less than this dom0_min_memory = 700*1024*1024 @@ -937,6 +939,13 @@ class QubesVm(object): print "--> Preparing config template for DispVM" self.create_config_file(file_path = self.dir_path + '/dvm.conf', prepare_dvm = True) + if qvm_collection.updatevm_qid == self.qid: + # Sync RPMDB + subprocess.call(["/usr/lib/qubes/sync_rpmdb_updatevm.sh"]) + # Start polling + subprocess.call([qrexec_client_path, '-d', xid, '-e', + "while true; do sleep %d; /usr/lib/qubes/qubes_download_dom0_updates.sh; done" % dom0_update_check_interval]) + # perhaps we should move it before unpause and fork? # FIXME: this uses obsolete xm api if debug_console: @@ -1609,6 +1618,7 @@ class QubesVmCollection(dict): self.default_netvm_qid = None self.default_fw_netvm_qid = None self.default_template_qid = None + self.updatevm_qid = None self.qubes_store_filename = store_filename def values(self): @@ -1769,6 +1779,15 @@ class QubesVmCollection(dict): else: return self[self.default_fw_netvm_qid] + def set_updatevm_vm(self, vm): + self.updatevm_qid = vm.qid + + def get_updatevm_vm(self): + if self.updatevm_qid is None: + return None + else: + return self[self.updatevm_qid] + def get_vm_by_name(self, name): for vm in self.values(): if (vm.name == name): @@ -1872,7 +1891,10 @@ class QubesVmCollection(dict): if self.default_netvm_qid is not None else "None", default_fw_netvm=str(self.default_fw_netvm_qid) \ - if self.default_fw_netvm_qid is not None else "None" + if self.default_fw_netvm_qid is not None else "None", + + updatevm=str(self.updatevm_qid) \ + if self.updatevm_qid is not None else "None" ) for vm in self.values(): @@ -2002,6 +2024,13 @@ class QubesVmCollection(dict): if default_fw_netvm != "None" else None #assert self.default_netvm_qid is not None + updatevm = element.get("updatevm") + if updatevm is not None: + self.updatevm_qid = int(updatevm) \ + if updatevm != "None" else None + #assert self.default_netvm_qid is not None + + # Then, read in the TemplateVMs, because a reference to template VM # is needed to create each AppVM for element in tree.findall("QubesTemplateVm"): diff --git a/dom0/qvm-tools/qvm-dom0-upgrade b/dom0/qvm-tools/qvm-dom0-upgrade new file mode 100755 index 00000000..2d47edaa --- /dev/null +++ b/dom0/qvm-tools/qvm-dom0-upgrade @@ -0,0 +1,20 @@ +#!/bin/bash + +UPDATEVM=`qvm-get-updatevm` +if [ -z "$UPDATEVM" ]; then + echo "UpdateVM not set, exiting" + exit 1 +fi + +echo "Checking for dom0 updates" + +# Start VM if not running already +qvm-run -a $UPDATEVM true || exit 1 +/usr/lib/qubes/sync_rpmdb_updatevm.sh || exit 1 +qvm-run -u root --pass_io $UPDATEVM "/usr/lib/qubes/qubes_download_dom0_updates.sh --doit $@" || exit 1 +yum check-update +if [ $? -ne 100 ]; then + exit 0 +fi +gpk-update-viewer + diff --git a/dom0/qvm-tools/qvm-get-updatevm b/dom0/qvm-tools/qvm-get-updatevm new file mode 100755 index 00000000..e746587b --- /dev/null +++ b/dom0/qvm-tools/qvm-get-updatevm @@ -0,0 +1,39 @@ +#!/usr/bin/python2.6 +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010 Joanna Rutkowska +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + +from qubes.qubes import QubesVmCollection +from optparse import OptionParser; + +def main(): + qvm_collection = QubesVmCollection() + qvm_collection.lock_db_for_reading() + qvm_collection.load() + qvm_collection.unlock_db() + updatevm = qvm_collection.get_updatevm_vm() + if updatevm is None: + print "" + else: + print updatevm.name + + + +main() diff --git a/dom0/qvm-tools/qvm-set-updatevm b/dom0/qvm-tools/qvm-set-updatevm new file mode 100755 index 00000000..4fb3a6d4 --- /dev/null +++ b/dom0/qvm-tools/qvm-set-updatevm @@ -0,0 +1,46 @@ +#!/usr/bin/python2.6 +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010 Joanna Rutkowska +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + +from qubes.qubes import QubesVmCollection +from optparse import OptionParser; + +def main(): + usage = "usage: %prog " + parser = OptionParser (usage) + (options, args) = parser.parse_args () + if (len (args) != 1): + parser.error ("Missing argument!") + vmname = args[0] + + qvm_collection = QubesVmCollection() + qvm_collection.lock_db_for_writing() + qvm_collection.load() + vm = qvm_collection.get_vm_by_name(vmname) + if vm is None or vm.qid not in qvm_collection: + print "A VM with the name '{0}' does not exist in the system.".format(vmname) + exit(1) + + qvm_collection.set_updatevm_vm(vm) + qvm_collection.save() + qvm_collection.unlock_db() + +main() diff --git a/dom0/restore/qfile-daemon b/dom0/restore/qfile-daemon index 6b589279..aca6f25f 100755 --- a/dom0/restore/qfile-daemon +++ b/dom0/restore/qfile-daemon @@ -22,8 +22,13 @@ import os import sys import subprocess +import shutil +import glob from qubes.qubes import QubesVmCollection +updates_dir = "/var/lib/qubes/updates" +updates_rpm_dir = updates_dir + "/rpm" + def is_copy_allowed(vm): # if vm.copy_allowed: # return True @@ -33,6 +38,36 @@ def is_copy_allowed(vm): retcode = subprocess.call(['/usr/bin/kdialog', '--yesno', q, '--title', 'File transfer confirmation']) return retcode == 0 +def dom0updates_fatal(msg): + print >> sys.stderr, msg + shutil.rmtree(updates_rpm_dir) + exit(1) + +def handle_dom0updates(updatevm): + source=os.getenv("QREXEC_REMOTE_DOMAIN") + if source != updatevm.name: + print >> sys.stderr, 'Domain ' + source + ' not allowed to send dom0 updates' + exit(1) + # Clean old packages + if os.path.exists(updates_rpm_dir): + shutil.rmtree(updates_rpm_dir) + subprocess.check_call(["/usr/lib/qubes/qfile-dom0-unpacker", os.getlogin(), updates_rpm_dir]) + # Verify received files + for f in os.listdir(updates_rpm_dir): + if glob.fnmatch.fnmatch(f, "*.rpm"): + p = subprocess.Popen (["/bin/rpm", "-K", updates_rpm_dir + "/" + f], + stdout=subprocess.PIPE) + output = p.communicate()[0] + if p.returncode != 0: + dom0updates_fatal('Error while verifing %s signature: %s' % (f, output)) + if output.find("pgp") < 0: + dom0updates_fatal('Domain ' + source + ' sent not signed rpm: ' + f) + else: + dom0updates_fatal('Domain ' + source + ' sent unexpected file: ' + f) + # After updates received - create repo metadata + subprocess.check_call(["/usr/bin/createrepo", "-q", "/var/lib/qubes/updates"]) + exit(0) + def main(): FILECOPY_VMNAME_SIZE = 32 blob=os.read(0, FILECOPY_VMNAME_SIZE) @@ -42,6 +77,11 @@ def main(): qvm_collection.lock_db_for_reading() qvm_collection.load() qvm_collection.unlock_db() + + if vmname == '@dom0updates': + updatevm = qvm_collection.get_updatevm_vm() + handle_dom0updates(updatevm) + # handle_dom0updates never returns vm = qvm_collection.get_vm_by_name(vmname) # we do not want to flood dom0 with error windows; so just log to stderr diff --git a/rpm_spec/core-commonvm.spec b/rpm_spec/core-commonvm.spec index 993b277f..d754c361 100644 --- a/rpm_spec/core-commonvm.spec +++ b/rpm_spec/core-commonvm.spec @@ -79,10 +79,12 @@ mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d cp qubes_network.rules $RPM_BUILD_ROOT/etc/udev/rules.d/ mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes/ cp setup_ip $RPM_BUILD_ROOT/usr/lib/qubes/ +cp qubes_download_dom0_updates.sh $RPM_BUILD_ROOT/usr/lib/qubes/ mkdir -p $RPM_BUILD_ROOT/etc/yum/post-actions cp qubes_trigger_sync_appmenus.action $RPM_BUILD_ROOT/etc/yum/post-actions/ mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes cp qubes_trigger_sync_appmenus.sh $RPM_BUILD_ROOT/usr/lib/qubes/ +mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/dom0-updates %triggerin -- initscripts cp /var/lib/qubes/serial.conf /etc/init/serial.conf @@ -233,3 +235,4 @@ rm -rf $RPM_BUILD_ROOT /usr/lib/qubes/setup_ip /etc/yum/post-actions/qubes_trigger_sync_appmenus.action /usr/lib/qubes/qubes_trigger_sync_appmenus.sh +/usr/lib/qubes/qubes_download_dom0_updates.sh diff --git a/rpm_spec/core-dom0.spec b/rpm_spec/core-dom0.spec index 47252bec..7960b923 100644 --- a/rpm_spec/core-dom0.spec +++ b/rpm_spec/core-dom0.spec @@ -39,6 +39,7 @@ URL: http://www.qubes-os.org BuildRequires: xen-devel Requires: python, xen-runtime, pciutils, python-inotify, python-daemon, kernel-qubes-dom0 Conflicts: qubes-gui-dom0 < 1.1.13 +Requires: yum-plugin-post-transaction-actions Requires: NetworkManager >= 0.8.1-1 Requires: xen >= 4.1.0-2 %define _builddir %(pwd)/dom0 @@ -50,6 +51,7 @@ The Qubes core files for installation on Dom0. python -m compileall qvm-core qmemman python -O -m compileall qvm-core qmemman make -C restore +make -C aux-tools make -C ../common make -C ../vchan make -C ../u2mfn @@ -89,10 +91,12 @@ cp aux-tools/convert_dirtemplate2vm.sh $RPM_BUILD_ROOT/usr/lib/qubes cp aux-tools/create_apps_for_appvm.sh $RPM_BUILD_ROOT/usr/lib/qubes cp aux-tools/remove_appvm_appmenus.sh $RPM_BUILD_ROOT/usr/lib/qubes cp aux-tools/reset_vm_configs.py $RPM_BUILD_ROOT/usr/lib/qubes +cp aux-tools/sync_rpmdb_updatevm.sh $RPM_BUILD_ROOT/usr/lib/qubes/ cp qmemman/server.py $RPM_BUILD_ROOT/usr/lib/qubes/qmemman_daemon.py cp ../common/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes/ cp ../qrexec/qrexec_daemon $RPM_BUILD_ROOT/usr/lib/qubes/ cp ../qrexec/qrexec_client $RPM_BUILD_ROOT/usr/lib/qubes/ +cp aux-tools/qfile-dom0-unpacker $RPM_BUILD_ROOT/usr/lib/qubes/ cp restore/qvm-create-default-dvm $RPM_BUILD_ROOT/usr/bin cp restore/xenstore-watch $RPM_BUILD_ROOT/usr/bin/xenstore-watch-qubes @@ -101,6 +105,12 @@ cp restore/qubes_prepare_saved_domain.sh $RPM_BUILD_ROOT/usr/lib/qubes cp restore/qfile-daemon-dvm $RPM_BUILD_ROOT/usr/lib/qubes cp restore/qfile-daemon $RPM_BUILD_ROOT/usr/lib/qubes +mkdir -p $RPM_BUILD_ROOT/etc/yum.real.repos.d +cp qubes-cached.repo $RPM_BUILD_ROOT/etc/yum.real.repos.d/ + +mkdir -p $RPM_BUILD_ROOT/etc/yum/post-actions +cp misc/qubes_sync_rpmdb_updatevm.action $RPM_BUILD_ROOT/etc/yum/post-actions/ + mkdir -p $RPM_BUILD_ROOT/var/lib/qubes mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/vm-templates mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/appvms @@ -109,6 +119,8 @@ mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/servicevms mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/backup mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/dvmdata +mkdir -p $RPM_BUILD_ROOT/var/lib/qubes/updates + mkdir -p $RPM_BUILD_ROOT/usr/share/qubes/icons cp icons/*.png $RPM_BUILD_ROOT/usr/share/qubes/icons cp misc/qubes-vm.directory.template $RPM_BUILD_ROOT/usr/share/qubes/ @@ -158,6 +170,9 @@ fi sed 's/^net.ipv4.ip_forward.*/net.ipv4.ip_forward = 1/' -i /etc/sysctl.conf +sed '/^reposdir=/d' -i /etc/yum.conf +echo reposdir=/etc/yum.real.repos.d >> /etc/yum.conf + chkconfig --add qubes_core || echo "WARNING: Cannot add service qubes_core!" chkconfig --add qubes_netvm || echo "WARNING: Cannot add service qubes_netvm!" chkconfig --add qubes_setupdvm || echo "WARNING: Cannot add service qubes_setupdvm!" @@ -267,12 +282,15 @@ fi /usr/lib/qubes/meminfo-writer /usr/lib/qubes/qfile-daemon-dvm* /usr/lib/qubes/qfile-daemon +/usr/lib/qubes/sync_rpmdb_updatevm.sh +%attr(4750,root,qubes) /usr/lib/qubes/qfile-dom0-unpacker %attr(770,root,qubes) %dir /var/lib/qubes %attr(770,root,qubes) %dir /var/lib/qubes/vm-templates %attr(770,root,qubes) %dir /var/lib/qubes/appvms %attr(770,root,qubes) %dir /var/lib/qubes/servicevms %attr(770,root,qubes) %dir /var/lib/qubes/backup %attr(770,root,qubes) %dir /var/lib/qubes/dvmdata +%attr(770,root,qubes) %dir /var/lib/qubes/updates %dir /usr/share/qubes/icons/*.png /usr/share/qubes/qubes-vm.directory.template /usr/share/qubes/qubes-templatevm.directory.template @@ -299,7 +317,9 @@ fi %attr(770,root,qubes) %dir /var/run/qubes %{_libdir}/libvchan.so %{_libdir}/libu2mfn.so +/etc/yum.real.repos.d/qubes-cached.repo /etc/sudoers.d/qubes /etc/xdg/autostart/qubes-guid.desktop /etc/security/limits.d/99-qubes.conf /etc/xen/xl.conf +/etc/yum/post-actions/qubes_sync_rpmdb_updatevm.action