1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 | #!/usr/bin/python3
import argparse
import json
import io
import os
import shutil
import subprocess
import tarfile
import tempfile
import urllib.request
from launchpadlib.launchpad import Launchpad
# Architecture mapping
arches = {"amd64": "x86_64",
"i386": "i686",
"armhf": "armv7l",
"arm64": "aarch64",
"powerpc": "ppc",
"ppc64el": "ppc64le",
"s390x": "s390x"}
# Argument parsing
parser = argparse.ArgumentParser(description="LXD Launchpad chroot")
parser.add_argument("-s", "--series", required=True)
parser.add_argument("-a", "--architecture", required=True)
parser.add_argument("-n", "--name", required=True)
parser.add_argument("-u", "--update", action="store_true")
args = parser.parse_args()
alias = "lp-%s-%s" % (args.series, args.architecture)
try:
with open("/dev/null", "w") as devnull:
subprocess.check_call(["lxc", "image", "info", alias],
stdout=devnull, stderr=devnull)
except Exception:
args.update = True
if args.update:
# Find the Launchpad chroot
lp = Launchpad.login_anonymously('lp-sbuild', 'production')
dist = lp.distributions["ubuntu"]
series = dist.getSeries(name_or_version=args.series)
arch = series.getDistroArchSeries(archtag=args.architecture)
chroot_url = arch.chroot_url
# Download the chroot
tempdir = tempfile.mkdtemp()
urllib.request.urlretrieve(chroot_url, os.path.join(tempdir,
"rootfs.tar.bz2"))
# Generate the metadata tarball
source_tarball = tarfile.open(os.path.join(tempdir, "rootfs.tar.bz2"), "r")
target_tarball = tarfile.open(os.path.join(tempdir, "lxd.tar.gz"), "w:gz")
creation_time = source_tarball.getmember("chroot-autobuild").mtime
metadata = {'architecture': arches[args.architecture],
'creation_date': creation_time,
'properties': {
'os': "Ubuntu",
'series': args.series,
'architecture': args.architecture,
'description': "Launchpad chroot for Ubuntu %s (%s)" %
(args.series, args.architecture),
},
}
metadata_yaml = json.dumps(metadata, sort_keys=True,
indent=4, separators=(',', ': '),
ensure_ascii=False).encode('utf-8') + b"\n"
metadata_file = tarfile.TarInfo()
metadata_file.size = len(metadata_yaml)
metadata_file.name = "metadata.yaml"
target_tarball.addfile(metadata_file,
io.BytesIO(metadata_yaml))
for entry in source_tarball:
fileptr = None
if entry.isfile():
try:
fileptr = source_tarball.extractfile(entry.name)
except KeyError:
pass
# Update hardlinks to point to the right target
if entry.islnk():
entry.linkname = "rootfs" + \
entry.linkname.split("chroot-autobuild", 1)[-1]
entry.name = "rootfs" + entry.name.split("chroot-autobuild", 1)[-1]
target_tarball.addfile(entry, fileobj=fileptr)
target_tarball.close()
# Import in LXD
with open("/dev/null", "w") as devnull:
subprocess.call(["lxc", "image", "delete", alias],
stdout=devnull, stderr=devnull)
subprocess.check_call(["lxc", "image", "import",
os.path.join(tempdir, "lxd.tar.gz"),
"--alias", alias])
shutil.rmtree(tempdir)
# Create the container
subprocess.check_call(["lxc", "init", alias, args.name])
# Set the configuration
def set_key(key, value):
subprocess.check_call(["lxc", "config", "set", args.name, key, value])
set_key("security.privileged", "true")
set_key("raw.lxc", """lxc.aa_profile=unconfined
lxc.cgroup.devices.deny=
lxc.cgroup.devices.allow=
""")
# Start the container
subprocess.check_call(["lxc", "start", args.name])
|