Update TemplateVM with running AppVM: part 2
- support for template modify in qvm-core - tool for commit changes to template
This commit is contained in:
parent
e104f82e36
commit
14aaccbc5f
@ -624,13 +624,14 @@ class QubesTemplateVm(QubesVm):
|
||||
|
||||
dir_path = kwargs["dir_path"]
|
||||
|
||||
# TempleteVM doesn't use root-cow image
|
||||
if root_img is not None and os.path.isabs(root_img):
|
||||
self.root_img = root_img
|
||||
else:
|
||||
self.root_img = dir_path + "/" + (
|
||||
root_img if root_img is not None else default_root_img)
|
||||
|
||||
self.rootcow_img = dir_path + "/" + default_rootcow_img
|
||||
|
||||
if private_img is not None and os.path.isabs(private_img):
|
||||
self.private_img = private_img
|
||||
else:
|
||||
@ -711,6 +712,14 @@ class QubesTemplateVm(QubesVm):
|
||||
format(src_template_vm.root_img, self.root_img)
|
||||
# We prefer to use Linux's cp, because it nicely handles sparse files
|
||||
retcode = subprocess.call (["cp", src_template_vm.root_img, self.root_img])
|
||||
if retcode != 0:
|
||||
raise IOError ("Error while copying {0} to {1}".\
|
||||
format(src_template_vm.root_img, self.root_img))
|
||||
if verbose:
|
||||
print "--> Copying the template's root COW image:\n{0} ==>\n{1}".\
|
||||
format(src_template_vm.rootcow_img, self.rootcow_img)
|
||||
# We prefer to use Linux's cp, because it nicely handles sparse files
|
||||
retcode = subprocess.call (["cp", src_template_vm.rootcow_img, self.rootcow_img])
|
||||
if retcode != 0:
|
||||
raise IOError ("Error while copying {0} to {1}".\
|
||||
format(src_template_vm.root_img, self.root_img))
|
||||
@ -779,13 +788,29 @@ class QubesTemplateVm(QubesVm):
|
||||
if not self.is_updateable():
|
||||
raise QubesException ("Cannot start Template VM that is marked \"nonupdatable\"")
|
||||
|
||||
# First ensure that none of our appvms is running:
|
||||
for appvm in self.appvms.values():
|
||||
if appvm.is_running():
|
||||
raise QubesException ("Cannot start TemplateVM when one of its AppVMs is running!")
|
||||
# TODO?: check if none of running appvms are outdated
|
||||
|
||||
return super(QubesTemplateVm, self).start(debug_console=debug_console, verbose=verbose)
|
||||
|
||||
def commit_changes (self):
|
||||
|
||||
assert not self.is_running(), "Attempt to commit changes on running Template VM!"
|
||||
|
||||
print "--> Commiting template updates... COW: {0}...".format (self.rootcow_img)
|
||||
|
||||
if dry_run:
|
||||
return
|
||||
if os.path.exists (self.rootcow_img):
|
||||
os.remove (self.rootcow_img)
|
||||
|
||||
|
||||
f_cow = open (self.rootcow_img, "w")
|
||||
f_root = open (self.root_img, "r")
|
||||
f_root.seek(0, os.SEEK_END)
|
||||
f_cow.truncate (f_root.tell()) # make empty sparse file of the same size as root.img
|
||||
f_cow.close ()
|
||||
f_root.close()
|
||||
|
||||
def create_xml_element(self):
|
||||
element = xml.etree.ElementTree.Element(
|
||||
"QubesTemplateVm",
|
||||
@ -795,6 +820,7 @@ class QubesTemplateVm(QubesVm):
|
||||
conf_file=self.conf_file,
|
||||
appvms_conf_file=self.appvms_conf_file,
|
||||
root_img=self.root_img,
|
||||
rootcow_img=self.rootcow_img,
|
||||
private_img=self.private_img,
|
||||
uses_default_netvm=str(self.uses_default_netvm),
|
||||
netvm_qid=str(self.netvm_vm.qid) if self.netvm_vm is not None else "none",
|
||||
@ -1194,10 +1220,6 @@ class QubesAppVm(QubesVm):
|
||||
if self.is_running():
|
||||
raise QubesException("VM is already running!")
|
||||
|
||||
# First ensure that our template is *not* running:
|
||||
if self.template_vm.is_running():
|
||||
raise QubesException ("Cannot start AppVM when its template is running!")
|
||||
|
||||
if not self.is_updateable():
|
||||
self.reset_cow_storage()
|
||||
self.reset_swap_cow_storage()
|
||||
@ -1728,3 +1750,4 @@ class QubesDaemonPidfile(object):
|
||||
self.remove_pidfile()
|
||||
|
||||
|
||||
# vim:sw=4:et:
|
||||
|
@ -42,6 +42,8 @@ def do_list(vm):
|
||||
print fmt.format ("config", vm.conf_file)
|
||||
if not vm.is_appvm():
|
||||
print fmt.format ("root img", vm.root_img)
|
||||
if vm.is_templete():
|
||||
print fmt.format ("root COW img", vm.rootcow_img)
|
||||
if vm.is_appvm():
|
||||
print fmt.format ("root img", vm.template_vm.root_img)
|
||||
print fmt.format ("root COW img", vm.rootcow_img)
|
||||
|
67
dom0/qvm-tools/qvm-template-commit
Executable file
67
dom0/qvm-tools/qvm-template-commit
Executable file
@ -0,0 +1,67 @@
|
||||
#!/usr/bin/python2.6
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2011 Marek Marczykowski <marmarek@mimuw.edu.pl>
|
||||
#
|
||||
# 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 qubes.qubes import QubesException
|
||||
from optparse import OptionParser
|
||||
import subprocess
|
||||
|
||||
qubes_guid_path = "/usr/bin/qubes_guid"
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] <vm-name>"
|
||||
parser = OptionParser (usage)
|
||||
|
||||
(options, args) = parser.parse_args ()
|
||||
if (len (args) != 1):
|
||||
parser.error ("You must specify VM name!")
|
||||
vmname = args[0]
|
||||
|
||||
qvm_collection = QubesVmCollection()
|
||||
qvm_collection.lock_db_for_reading()
|
||||
qvm_collection.load()
|
||||
qvm_collection.unlock_db()
|
||||
|
||||
vm = qvm_collection.get_vm_by_name(vmname)
|
||||
if vm is None:
|
||||
print "A VM with the name '{0}' does not exist in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
if not vm.is_templatevm():
|
||||
print "A VM '{0}' is not template.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
if vm.is_running():
|
||||
print "You must stop VM first."
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
vm.verify_files()
|
||||
vm.commit_changes()
|
||||
except (IOError, OSError, QubesException) as err:
|
||||
print "ERROR: {0}".format(err)
|
||||
exit (1)
|
||||
|
||||
exit (0)
|
||||
|
||||
|
||||
main()
|
Loading…
Reference in New Issue
Block a user