firstboot: make initial setup more defensive
Do not abort the whole process when some part fails. Cleanup *-dvm if DispVM preparation failed.
This commit is contained in:
parent
3d5bcb5b18
commit
168e34510d
@ -43,6 +43,7 @@ class moduleClass(Module):
|
|||||||
self.title = N_("Create Service VMs")
|
self.title = N_("Create Service VMs")
|
||||||
self.icon = "qubes.png"
|
self.icon = "qubes.png"
|
||||||
self.admin = libuser.admin()
|
self.admin = libuser.admin()
|
||||||
|
self.default_template = 'fedora-21'
|
||||||
|
|
||||||
def _showErrorMessage(self, text):
|
def _showErrorMessage(self, text):
|
||||||
dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, text)
|
dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, text)
|
||||||
@ -83,15 +84,36 @@ class moduleClass(Module):
|
|||||||
|
|
||||||
interface.nextButton.set_sensitive(False)
|
interface.nextButton.set_sensitive(False)
|
||||||
|
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
try:
|
||||||
self.configure_template()
|
self.configure_template()
|
||||||
|
except Exception as e:
|
||||||
|
errors.append((self.stage, str(e)))
|
||||||
|
try:
|
||||||
self.create_default_netvm()
|
self.create_default_netvm()
|
||||||
self.create_default_fwvm()
|
self.create_default_fwvm()
|
||||||
self.set_networking_type(netvm=True)
|
self.set_networking_type(netvm=True)
|
||||||
self.start_qubes_networking()
|
self.start_qubes_networking()
|
||||||
|
except Exception as e:
|
||||||
|
errors.append((self.stage, str(e)))
|
||||||
|
try:
|
||||||
self.create_default_dvm()
|
self.create_default_dvm()
|
||||||
|
except Exception as e:
|
||||||
|
errors.append((self.stage, str(e)))
|
||||||
|
|
||||||
if self.radio_servicevms_and_appvms.get_active():
|
if self.radio_servicevms_and_appvms.get_active():
|
||||||
|
try:
|
||||||
self.create_appvms()
|
self.create_appvms()
|
||||||
|
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)
|
||||||
|
self.stage = "firstboot"
|
||||||
|
raise Exception(msg)
|
||||||
|
|
||||||
interface.nextButton.set_sensitive(True)
|
interface.nextButton.set_sensitive(True)
|
||||||
return RESULT_SUCCESS
|
return RESULT_SUCCESS
|
||||||
@ -114,7 +136,7 @@ class moduleClass(Module):
|
|||||||
self.progress.set_text(stage)
|
self.progress.set_text(stage)
|
||||||
|
|
||||||
def set_default_template(self):
|
def set_default_template(self):
|
||||||
subprocess.call(['/usr/bin/qubes-prefs', '--set', 'default-template', 'fedora-21'])
|
subprocess.call(['/usr/bin/qubes-prefs', '--set', 'default-template', self.default_template])
|
||||||
|
|
||||||
def configure_template(self):
|
def configure_template(self):
|
||||||
self.show_stage(_("Configuring default TemplateVM"))
|
self.show_stage(_("Configuring default TemplateVM"))
|
||||||
@ -160,16 +182,18 @@ class moduleClass(Module):
|
|||||||
self.show_stage(_("Creating handy AppVMs"))
|
self.show_stage(_("Creating handy AppVMs"))
|
||||||
self.run_in_thread(self.do_create_appvms)
|
self.run_in_thread(self.do_create_appvms)
|
||||||
|
|
||||||
def run_command(self, command):
|
def run_command(self, command, stdin=None):
|
||||||
try:
|
try:
|
||||||
os.setgid(self.qubes_gid)
|
os.setgid(self.qubes_gid)
|
||||||
os.umask(0007)
|
os.umask(0007)
|
||||||
cmd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
cmd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=stdin)
|
||||||
out = cmd.communicate()[0]
|
out = cmd.communicate()[0]
|
||||||
if cmd.returncode == 0:
|
if cmd.returncode == 0:
|
||||||
self.process_error = None
|
self.process_error = None
|
||||||
else:
|
else:
|
||||||
self.process_error = out
|
self.process_error = "{} failed:\n{}".format(command, out)
|
||||||
|
# Actually only self.process_error will be visible to the user
|
||||||
|
raise Exception("{} failed".format(command))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.process_error = str(e)
|
self.process_error = str(e)
|
||||||
|
|
||||||
@ -211,7 +235,14 @@ class moduleClass(Module):
|
|||||||
self.run_command(['su', '-c', '/usr/bin/qvm-create --proxy --label green %s' % self.fwvm_name, '-', self.qubes_user])
|
self.run_command(['su', '-c', '/usr/bin/qvm-create --proxy --label green %s' % self.fwvm_name, '-', self.qubes_user])
|
||||||
|
|
||||||
def do_create_dvm(self):
|
def do_create_dvm(self):
|
||||||
|
try:
|
||||||
self.run_command(['su', '-c', '/usr/bin/qvm-create-default-dvm --default-template --default-script', self.qubes_user])
|
self.run_command(['su', '-c', '/usr/bin/qvm-create-default-dvm --default-template --default-script', self.qubes_user])
|
||||||
|
except:
|
||||||
|
# Kill DispVM template if still running
|
||||||
|
# Do not use self.run_command to not clobber process output
|
||||||
|
subprocess.call(['qvm-kill', '{}-dvm'.format(self.default_template)])
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
def do_set_netvm_networking(self):
|
def do_set_netvm_networking(self):
|
||||||
self.run_command(['/usr/bin/qvm-prefs', '--force-root', '--set', self.fwvm_name, 'netvm', self.netvm_name])
|
self.run_command(['/usr/bin/qvm-prefs', '--force-root', '--set', self.fwvm_name, 'netvm', self.netvm_name])
|
||||||
@ -221,19 +252,19 @@ class moduleClass(Module):
|
|||||||
self.run_command(['/usr/bin/qubes-prefs', '--set', 'default-netvm', 'dom0'])
|
self.run_command(['/usr/bin/qubes-prefs', '--set', 'default-netvm', 'dom0'])
|
||||||
|
|
||||||
def do_start_networking(self):
|
def do_start_networking(self):
|
||||||
subprocess.check_call(['/usr/sbin/service', 'qubes_netvm', 'start'])
|
self.run_command(['/usr/sbin/service', 'qubes-netvm', 'start'])
|
||||||
|
|
||||||
def do_configure_template(self):
|
def do_configure_template(self):
|
||||||
for template in os.listdir('/var/lib/qubes/vm-templates'):
|
for template in os.listdir('/var/lib/qubes/vm-templates'):
|
||||||
subprocess.check_call(['qvm-start', '--no-guid', template])
|
self.run_command(['qvm-start', '--no-guid', template])
|
||||||
# Copy timezone setting from Dom0 to template
|
# Copy timezone setting from Dom0 to template
|
||||||
subprocess.check_call(['qvm-run', '--nogui', '--pass-io',
|
self.run_command(['qvm-run', '--nogui', '--pass-io',
|
||||||
'-u', 'root', template, 'cat > /etc/locale.conf'],
|
'-u', 'root', template, 'cat > /etc/locale.conf'],
|
||||||
stdin=open('/etc/locale.conf', 'r'))
|
stdin=open('/etc/locale.conf', 'r'))
|
||||||
subprocess.check_call(['su', '-c',
|
self.run_command(['su', '-c',
|
||||||
'qvm-sync-appmenus {}'.format(template),
|
'qvm-sync-appmenus {}'.format(template),
|
||||||
'-', self.qubes_user])
|
'-', self.qubes_user])
|
||||||
subprocess.check_call(['qvm-shutdown', '--wait', template])
|
self.run_command(['qvm-shutdown', '--wait', template])
|
||||||
|
|
||||||
def do_create_appvms(self):
|
def do_create_appvms(self):
|
||||||
self.run_command(['su', '-c', '/usr/bin/qvm-create work --label green', '-', self.qubes_user])
|
self.run_command(['su', '-c', '/usr/bin/qvm-create work --label green', '-', self.qubes_user])
|
||||||
|
Loading…
Reference in New Issue
Block a user