23
23
from . import populate_one_subcmd
29
SIMPLE_BOOT = 'simple-boot'
26
32
((('-D', '--devices'),
27
33
{'help': 'which devices to operate on', 'action': 'append',
28
34
'metavar': 'DEVICE', 'default': None, }),
29
('--fstype', {'help': 'root filesystem type',
35
('--fstype', {'help': 'root partition filesystem type',
30
36
'choices': ['ext4', 'ext3'], 'default': 'ext4'}),
31
('mode', {'help': 'meta-mode to use', 'choices': ['raid0', 'simple']}),
37
('--boot-fstype', {'help': 'boot partition filesystem type',
38
'choices': ['ext4', 'ext3'], 'default': None}),
39
('mode', {'help': 'meta-mode to use',
40
'choices': ['raid0', SIMPLE, SIMPLE_BOOT]}),
36
45
def block_meta(args):
37
46
# main entry point for the block-meta command.
38
if args.mode == "simple":
47
if args.mode in (SIMPLE, SIMPLE_BOOT):
41
raise NotImplementedError("mode=%s is not implemenbed" % args.mode)
50
raise NotImplementedError("mode=%s is not implemented" % args.mode)
44
53
def logtime(msg, func, *args, **kwargs):
46
55
return func(*args, **kwargs)
58
def write_image_to_disk(source, dev):
60
Write disk image to block device
62
(devname, devnode) = block.get_dev_name_entry(dev)
63
util.subp(args=['sh', '-c',
64
('wget "$1" --progress=dot:mega -O - |'
65
'tar -SxOzf - | dd of="$2"'),
66
'--', source, devnode])
67
util.subp(['partprobe'])
68
util.subp(['udevadm', 'settle'])
69
return block.get_root_device([devname, ])
72
def get_bootpt_cfg(cfg, enabled=False, fstype=None):
75
# fstype: filesystem type (default to 'fstype')
76
# label: filesystem label (default to 'boot')
77
# parm enable can enable, but not disable
78
# parm fstype overrides cfg['fstype']
79
def_boot = platform.machine() in ('aarch64')
80
ret = {'enabled': def_boot, 'fstype': None, 'label': 'boot'}
85
if fstype and not ret['fstype']:
86
ret['fstype'] = fstype
49
90
def meta_simple(args):
91
"""Creates a root partition. If args.mode == SIMPLE_BOOT, it will also
92
create a separate /boot partition.
50
94
state = util.load_command_environment()
52
96
cfg = util.load_command_config(args, state)
55
99
if devices is None:
56
100
devices = cfg.get('block-meta', {}).get('devices', [])
102
bootpt = get_bootpt_cfg(
103
cfg.get('block-meta', {}).get('boot-partition', {}),
104
enabled=args.mode == SIMPLE_BOOT, fstype=args.boot_fstype)
58
106
# Remove duplicates but maintain ordering.
59
107
devices = list(OrderedDict.fromkeys(devices))
61
109
if len(devices) == 0:
62
110
devices = block.get_installable_blockdevs()
63
LOG.warn("simple mode, no devices given. unused list: %s", devices)
111
LOG.warn("'%s' mode, no devices given. unused list: %s",
112
(args.mode, devices))
65
114
if len(devices) > 1:
66
115
if args.devices is not None:
67
LOG.warn("simple mode but multiple devices given. "
116
LOG.warn("'%s' mode but multiple devices given. "
117
"using first found", args.mode)
69
118
available = [f for f in devices
70
119
if block.is_valid_device(f)]
71
120
target = sorted(available)[0]
72
LOG.warn("mode is 'simple'. multiple devices given. using '%s' "
73
"(first available)", target)
121
LOG.warn("mode is '%s'. multiple devices given. using '%s' "
122
"(first available)", (args.mode, target))
75
124
target = devices[0]
80
129
(devname, devnode) = block.get_dev_name_entry(target)
82
LOG.info("installing in simple mode to '%s'", devname)
131
LOG.info("installing in '%s' mode to '%s'", (args.mode, devname))
133
sources = cfg.get('sources', {})
134
dd_images = util.get_dd_images(sources)
137
# we have at least one dd-able image
138
# we will only take the first one
139
rootdev = write_image_to_disk(dd_images[0], devname)
140
util.subp(['mount', rootdev, state['target']])
84
143
# helper partition will forcibly set up partition there
85
144
if util.is_uefi_bootable():
87
146
"partition --format uefi %s" % devnode,
88
147
util.subp, ("partition", "--format", "uefi", devnode))
148
bootpt['enabled'] = False
149
elif bootpt['enabled']:
150
logtime("partition --boot %s" % devnode,
151
util.subp, ("partition", "--boot", devnode))
152
bootdev = devnode + "1"
153
rootdev = devnode + "2"
91
156
"partition %s" % devnode,
92
157
util.subp, ("partition", devnode))
94
rootdev = devnode + "1"
158
rootdev = devnode + "1"
160
# mkfs for root partition first and mount
96
161
cmd = ['mkfs.%s' % args.fstype, '-q', '-L', 'cloudimg-rootfs', rootdev]
97
162
logtime(' '.join(cmd), util.subp, cmd)
99
163
util.subp(['mount', rootdev, state['target']])
165
if bootpt['enabled']:
166
# create 'boot' directory in state['target']
167
boot_dir = os.path.join(state['target'], 'boot')
168
util.subp(['mkdir', boot_dir])
169
# mkfs for boot partition and mount
170
cmd = ['mkfs.%s' % bootpt['fstype'],
171
'-q', '-L', bootpt['label'], bootdev]
172
logtime(' '.join(cmd), util.subp, cmd)
173
util.subp(['mount', bootdev, boot_dir])
101
175
with open(state['fstab'], "w") as fp:
102
fp.write("LABEL=%s / %s defaults 0 0\n" % ('cloudimg-rootfs', 'ext4'))
176
if bootpt['enabled']:
177
fp.write("LABEL=%s /boot %s defaults 0 0\n" %
178
(bootpt['label'], bootpt['fstype']))
179
fp.write("LABEL=%s / %s defaults 0 0\n" %
180
('cloudimg-rootfs', args.fstype))