40
38
parser = argparse.ArgumentParser(description="Unity8 inside LXC")
41
39
parser.add_argument(
42
40
"--rebuild-all", action="store_true",
43
help=("Wipe and replace the container rootfs and configuration."))
45
"--rebuild-config", action="store_true",
46
help=("Wipe and regenerate the container configuration."))
41
help=("Wipe and replace the container rootfs."))
47
42
parser.add_argument(
48
43
"--rebuild-rootfs", action="store_true",
49
44
help=("Wipe and replace the container rootfs."))
50
45
parser.add_argument(
51
"--redownload", action="store_true",
52
help=("Re-download the ISO image instead of using the local version."))
54
46
"--test", type=int, metavar="SECONDS", default=None,
55
47
help=("Test mode, argument is time in seconds for the session."))
56
48
parser.add_argument(
110
94
if args.rebuild_all:
111
args.rebuild_config = True
112
95
args.rebuild_rootfs = True
114
if args.rebuild_config:
115
generate_config = True
116
container.clear_config()
118
97
if args.rebuild_rootfs:
98
print("Deleting current unity8-lxc container...")
119
99
generate_rootfs = True
120
if os.path.exists(rootfs_path):
121
shutil.rmtree(rootfs_path)
102
container = lxc.Container(CONTAINER_NAME)
103
#if os.path.exists(container_path):
104
# shutil.rmtree(container_path)
123
if not generate_config and not generate_rootfs and not args.test and not args.update_lxc:
106
if not generate_rootfs and not args.test and not args.update_lxc:
124
107
parser.error("The container already exists.")
128
# Setup the container config
129
## Load the default LXC config keys
130
container.load_config("/usr/share/lxc/config/ubuntu.common.conf")
132
## Setup the network ##
133
container.append_config_item("lxc.network.type", "veth")
134
container.append_config_item("lxc.network.link", "lxcbr0")
135
container.append_config_item("lxc.network.hwaddr", "00:16:3e:xx:xx:xx")
138
container.set_config_item("lxc.arch", "x86_64")
141
container.set_config_item("lxc.rootfs", rootfs_path)
144
container.set_config_item("lxc.utsname", CONTAINER_NAME)
148
container.append_config_item("lxc.cgroup.devices.allow", "c 4:* rwm")
151
container.append_config_item("lxc.cgroup.devices.allow", "c 13:* rwm")
152
container.append_config_item("lxc.mount.entry",
153
"/dev/input dev/input none bind,create=dir")
156
container.append_config_item("lxc.cgroup.devices.allow", "c 226:* rwm")
157
container.append_config_item("lxc.mount.entry",
158
"/dev/dri dev/dri none bind,create=dir")
161
container.append_config_item("lxc.cgroup.devices.allow", "c 116:* rwm")
162
container.append_config_item("lxc.mount.entry",
163
"/dev/snd dev/snd none bind,create=dir")
165
## Enable cgmanager access
166
container.set_config_item("lxc.mount.auto", "cgroup:mixed proc:mixed sys:mixed")
168
## Allow nested containers
169
container.set_config_item("lxc.aa_profile", "lxc-container-default-with-nesting")
171
## Disable the lxc autodev
172
container.append_config_item("lxc.autodev", "0")
174
# Setup the /home bind-mount
175
container.append_config_item("lxc.mount.entry", "/home home none bind")
177
# Setup the /etc/shadow bind-mount
178
container.append_config_item("lxc.mount.entry",
179
"/etc/shadow etc/shadow none bind")
181
# Setup the local time and timezone
182
container.append_config_item("lxc.mount.entry",
183
"/etc/localtime etc/localtime none bind")
184
container.append_config_item("lxc.mount.entry",
185
"/etc/timezone etc/timezone none bind")
188
container.append_config_item("lxc.mount.entry",
189
"/run/udev var/lib/host-udev none bind,ro,create=dir")
192
container.append_config_item("lxc.mount.entry",
193
"/run/systemd var/lib/host-systemd none bind,ro,create=dir")
195
## Dump it all to disk
196
container.save_config()
199
109
if generate_rootfs:
200
110
# Setup the container rootfs
213
123
except DistroDataOutdated:
214
124
current_release = UbuntuDistroInfo().stable()
216
## Download the ISO image
218
iso_url = ISO_URL.replace("ARCH", architecture)
219
iso_url = iso_url.replace("RELEASE", current_release)
221
### Use zsync to fetch the ISO
222
cmd = "cd %s && zsync -i %s -o %s %s" % (container_path, iso_filename, iso_filename, iso_url)
225
### Remove the ISO backup since it's not needed
226
if os.path.exists(iso_filename+".zs-old"):
227
os.remove(iso_filename+".zs-old")
229
if not os.path.exists(iso_filename):
230
parser.error("No Unity 8 Desktop Next ISO exists!")
233
if not os.path.exists(iso_path):
235
subprocess.call(["mount", "-o", "loop,ro", iso_filename, iso_path])
237
if not os.path.exists(squashfs_path):
238
os.mkdir(squashfs_path)
239
subprocess.call(["mount", "-o", "loop,ro",
240
os.path.join(iso_path, "casper", "filesystem.squashfs"),
244
print("Unpacking the ISO image...")
245
subprocess.call(["rsync", "-aA", "--hard-links", "--numeric-ids",
246
"%s/" % squashfs_path, "%s/" % rootfs_path])
249
subprocess.call(["umount", squashfs_path])
250
os.rmdir(squashfs_path)
252
subprocess.call(["umount", iso_path])
126
print("Creating the new unity8-lxc container...")
127
container.create("download", 0,
129
"release": current_release,
130
"arch": architecture})
256
133
print("Configuring the Unity8 LXC...")
270
147
ff02::2 ip6-allrouters
273
### Disable some upstart jobs
150
# Generate the package install policy override
151
with open(os.path.join(rootfs_path, 'usr', 'sbin', 'policy-rc.d'), 'w+') as fd:
152
fd.write("""#!/bin/sh
163
os.chmod(os.path.join(rootfs_path, 'usr', 'sbin', 'policy-rc.d'), 0o755)
167
# Copy the ubuntu-desktop-next metapackage to the rootfs
168
lxc_archive = os.path.join(rootfs_path, 'tmp', 'ubuntu-desktop-next.deb')
169
glob_name = "ubuntu-desktop-next_*_%s.deb" % architecture
170
metapackage = glob.glob(os.path.join('/', 'usr', 'share', 'unity8-lxc', glob_name))
171
shutil.copy(metapackage[0], lxc_archive)
173
# Remove the default ubuntu user in the container
174
container.attach_wait(lxc.attach_run_command,
175
["userdel", "-r", "ubuntu"])
177
container.attach_wait(lxc.attach_run_command,
178
["apt-get", "update"])
180
container.attach_wait(lxc.attach_run_command,
181
["dpkg", "-i", os.path.join('/', 'tmp', 'ubuntu-desktop-next.deb')])
182
container.attach_wait(lxc.attach_run_command,
183
["apt-get", "install", "-f", "-y"])
185
container.attach_wait(lxc.attach_run_command,
186
["systemctl", "disable", "lightdm.service"])
189
# Disable some upstart jobs
274
190
for job in glob.glob("%s/etc/init/*.conf" % rootfs_path):
275
191
if os.path.basename(job).rsplit(".conf", 1)[0] in SKIP_JOB:
276
192
with open("%s.override" % job.rsplit(".conf", 1)[0], "w+") as fd:
277
193
fd.write("manual")
279
### Create any missing devices
281
tty_path = os.path.join(rootfs_path, "dev", "tty%s" % i)
282
if not os.path.exists(tty_path):
283
os.mknod(tty_path, 0o620 | stat.S_IFCHR, device=os.makedev(4, i))
284
os.chown(tty_path, 0, 5)
286
### Generate /run/udev
287
with open(os.path.join(rootfs_path, "etc", "init", "udev-db.conf"), "w+") as fd:
288
fd.write("""start on starting udev
291
cp -R /var/lib/host-udev /run/udev
295
### Switch back to upstart instead of systemd
296
with open(os.path.join(rootfs_path, "etc", "X11", "default-display-manager"), "w+") as fd:
299
os.chdir(container_path)
301
files = glob.glob("%s/upstart-sysv_*.deb" % container_path)
306
upstart_file = files[0]
308
if args.redownload or not os.path.exists(upstart_file):
309
if os.path.exists(upstart_file):
310
os.remove(upstart_file)
312
rmadison_cmd = "rmadison -s %s upstart-sysv | cut -d '|' -f 2 | tr -d '[[:space:]]'" % current_release
313
upstart_sysv_ver = subprocess.getoutput(rmadison_cmd)
314
upstart_file = "upstart-sysv_%s_%s.deb" % (upstart_sysv_ver, architecture)
316
dget_url = "http://archive.ubuntu.com/ubuntu/pool/main/u/upstart/%s" % upstart_file
317
subprocess.call(["dget", dget_url])
319
if args.rebuild_rootfs:
320
rootfs_archive_path = os.path.join(rootfs_path, "var", "cache", "apt", "archives")
321
shutil.copy(upstart_file, rootfs_archive_path)
323
start_container(False)
325
print("Generating locale...")
326
r = os.popen("locale", "r").read().split("\n")
327
locale = ["locale-gen"]
332
i = i.split('=')[1].replace("\"", "")
333
if not i in locale and i != "":
336
container.attach_wait(lxc.attach_run_command, locale)
338
print("Switching to upstart...")
339
container.attach_wait(lxc.attach_run_command,
340
["apt-get", "install", "upstart-sysv", "-y", "--no-download", "--ignore-missing"])
195
with open(os.path.join(container_path, 'config'), 'a') as fd:
196
fd.write("lxc.include = " + os.path.join('/', 'usr', 'share', 'unity8-lxc', 'unity8-lxc.conf'))
345
200
# Start a test session