Add postinstall cleanup

Inject a postinstall config to curtin installer to cleanup cloud image
on target.

Signed-off-by: Ryan Harper <ryan.harper@canonical.com>
This commit is contained in:
Ryan Harper 2015-07-23 14:56:45 -05:00
parent 161764d030
commit 65b9cb396a
5 changed files with 65 additions and 20 deletions

View File

@ -1,6 +1,7 @@
#!/bin/bash -x
CMD="-v --showtrace install -c /tmp/subiquity-config.yaml cp:///"
CONFIGS="-c /tmp/subiquity-config.yaml -c /tmp/subiquity-postinst.yaml"
CMD="-v --showtrace install $CONFIGS cp:///"
CURTIN="/usr/local/curtin/bin/curtin"
OUTPUT="/tmp/.curtin_wrap_ran"
INSTALL_OK="Installation finished. No error reported."
@ -14,7 +15,8 @@ else
echo $CURTIN $CMD | tee -a $OUTPUT
fi
if tail -n 1 $OUTPUT | grep -q "$INSTALL_OK"; then
clear
if tail -n 2 $OUTPUT | grep -q "$INSTALL_OK"; then
echo "Curtin installed OK, rebooting (Press Any Key)"
read a
echo "Rebooting down after running $CURTIN $CMD"

View File

@ -34,6 +34,7 @@ SRC_DEPS=(
"git" "https://github.com/CanonicalLtd/probert.git" "probert"
)
INSTALLER_DEPS=(
"petname"
"python3-parted"
"python3-urwid"
"python3-pyudev"

View File

@ -19,7 +19,8 @@ import urwid.curses_display
import subprocess
from subiquity.signals import Signal
from subiquity.palette import STYLES, STYLES_MONO
from subiquity.curtin import curtin_write_storage_actions
from subiquity.curtin import (curtin_write_storage_actions,
curtin_write_postinst_config)
# Modes import ----------------------------------------------------------------
from subiquity.welcome import WelcomeView, WelcomeModel
@ -224,6 +225,8 @@ class Controller:
log.info("Rendering curtin config from user choices")
curtin_write_storage_actions(actions=actions)
log.info("Generating post-install config")
curtin_write_postinst_config()
if self.opts.dry_run:
log.debug("filesystem: this is a dry-run")
print("\033c")
@ -270,14 +273,14 @@ class Controller:
def add_disk_partition_handler(self, disk, spec):
current_disk = self.models["filesystem"].get_disk(disk)
if spec["fstype"] in ["swap"]:
current_disk.add_partition(spec["partnum"],
spec["bytes"],
spec["fstype"])
current_disk.add_partition(partnum=spec["partnum"],
size=spec["bytes"],
fstype=spec["fstype"])
else:
current_disk.add_partition(spec["partnum"],
spec["bytes"],
spec["fstype"],
spec["mountpoint"])
current_disk.add_partition(partnum=spec["partnum"],
size=spec["bytes"],
fstype=spec["fstype"],
mountpoint=spec["mountpoint"])
log.debug("FS Table: {}".format(current_disk.get_fs_table()))
self.signal.emit_signal('filesystem:show-disk-partition', disk)

View File

@ -20,7 +20,11 @@ import yaml
CURTIN_STORAGE_CONFIG_FILE = '/tmp/subiquity-config.yaml'
CURTIN_STORAGE_CONFIG_HEADER = """
# Autogenerated by SUbiquity: {{DATE}} UTC
reporter:
subiquity:
path: /tmp/curtin_progress_subiquity
progress: True
partitioning_commands:
builtin: curtin block-meta custom
@ -28,6 +32,11 @@ storage:
"""
CURTIN_STORAGE_CONFIG_TEMPLATE = """
# Autogenerated by SUbiquity: {{DATE}} UTC
reporter:
subiquity:
path: /tmp/curtin_progress_subiquity
progress: True
partitioning_commands:
builtin: curtin block-meta custom
@ -66,10 +75,26 @@ storage:
device: {{TARGET_DISK_NAME}}2_home
"""
POST_INSTALL_CONFIG_FILE = '/tmp/subiquity-postinst.yaml'
# TODO, this should be moved to the in-target cloud-config seed so on first boot
# of the target, it reconfigures datasource_list to none for subsequent boots
# 12_ds_to_none: [curtin, in-target, --, sh, '-c', "echo 'datasource_list: [ None ]' > /etc/cloud/cloud.cfg.d/
POST_INSTALL = '''
late_commands:
10_set_hostname: curtin in-target -- sh -c 'echo $(petname) > /etc/hostname'
11_postinst_seed: [curtin, in-target, --, sh, '-c',"/bin/echo -e '#cloud-config\\npassword: passw0rd\\nchpasswd: { expire: False }\\n' > /var/lib/cloud/seed/nocloud-net/user-data"]
12_disable_subiquity: curtin in-target -- systemctl disable subiquity.service
13_delete_subiquity: curtin in-target -- rm -f /lib/systemd/system/subiquity.service
14_remove_subiquity: curtin in-target -- sh -c 'for d in probert curtin subiquity; do rm -rf /usr/local/${d}; rm -rf /usr/local/bin/${d}*; done'
'''
def curtin_write_storage_actions(actions):
curtin_config = yaml.dump(actions, default_flow_style=False)
datestr = '# Autogenerated by SUbiquity: {} UTC'.format(
str(datetime.datetime.utcnow()))
with open(CURTIN_STORAGE_CONFIG_FILE, 'w') as conf:
conf.write(datestr)
conf.write(CURTIN_STORAGE_CONFIG_HEADER)
conf.write(curtin_config)
conf.close()
@ -97,3 +122,12 @@ def curtin_write_storage_template(disk_name, disk_model, disk_serial):
conf.close()
return CURTIN_STORAGE_CONFIG_FILE
def curtin_write_postinst_config():
with open(POST_INSTALL_CONFIG_FILE, 'w') as conf:
datestr = '# Autogenerated by SUbiquity: {} UTC'.format(
str(datetime.datetime.utcnow()))
conf.write(datestr)
conf.write(POST_INSTALL)
conf.close()

View File

@ -133,13 +133,17 @@ class Blockdev():
# find and remove from self.fstable
pass
def add_partition(self, partnum, size, fstype, mountpoint, flag=None):
def add_partition(self, partnum, size, fstype, mountpoint=None, flag=None):
''' add a new partition to this disk '''
log.debug('add_partition:'
' partnum:%s size:%s fstype:%s mountpoint:%s flag=%s' % (
partnum, size, fstype, mountpoint, flag))
if size > self.freepartition:
raise Exception('Not enough space')
if fstype in ["swap"]:
fstype = "linux-swap(v1)"
if fstype in ["swap"]:
fstype = "linux-swap(v1)"
geometry = self._get_largest_free_region()
if not geometry:
@ -167,7 +171,7 @@ class Blockdev():
start=data['start'],
end=data['end'])
# create partition
if fstype not in ['bcache cache', 'bcache store']:
if fstype not in [None, 'bcache cache', 'bcache store']:
fs = parted.FileSystem(type=fstype, geometry=geometry)
else:
fs = None
@ -191,7 +195,7 @@ class Blockdev():
newpart = self.disk.getPartitionByPath(partpath)
# create bcachedev if neded
if fstype.startswith('bcache'):
if fstype and fstype.startswith('bcache'):
mode = fstype.split()[-1]
self.bcache.append(Bcachedev(backing=newpart, mode=mode))
@ -220,9 +224,10 @@ class Blockdev():
format_action = FormatAction(partition_action,
fs_type)
actions.append(format_action)
mountpoint = self.mounts[part.path]
mount_action = MountAction(format_action, mountpoint)
actions.append(mount_action)
mountpoint = self.mounts.get(part.path)
if mountpoint:
mount_action = MountAction(format_action, mountpoint)
actions.append(mount_action)
return [action] + [a.get() for a in actions]
@ -231,7 +236,7 @@ class Blockdev():
fs_table = []
for part in self.disk.partitions:
if part.fileSystem:
mntpoint = self.mounts[part.path]
mntpoint = self.mounts.get(part.path, part.fileSystem.type)
fs_size = int(part.getSize(unit='GB'))
fs_type = part.fileSystem.type
devpath = part.path