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
|
"""
Wrapper for UEFI operations
"""
# -*- coding: utf-8 -*-
#
# uefi.py
#
# Copyright 2015 Neil Williams <codehelp@debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=missing-docstring,duplicate-code
import os
import cliapp
import logging
from vmdebootstrap.base import (
Base,
runcmd,
mount_wrapper,
umount_wrapper,
)
from vmdebootstrap.constants import arch_table
class Uefi(Base):
name = 'uefi'
def __init__(self):
super(Uefi, self).__init__()
self.bootdir = None
def efi_packages(self):
packages = []
pkg = arch_table[self.settings['arch']]['package']
self.message("Adding %s" % pkg)
packages.append(pkg)
extra = arch_table[self.settings['arch']]['extra']
if extra and isinstance(extra, str):
bin_pkg = arch_table[str(extra)]['bin_package']
self.message("Adding support for %s using %s" % (extra, bin_pkg))
packages.append(bin_pkg)
return packages
def copy_efi_binary(self, efi_removable, efi_install):
logging.debug("using bootdir=%s", self.bootdir)
logging.debug("moving %s to %s", efi_removable, efi_install)
if efi_removable.startswith('/'):
efi_removable = efi_removable[1:]
if efi_install.startswith('/'):
efi_install = efi_install[1:]
efi_output = os.path.join(self.bootdir, efi_removable)
efi_input = os.path.join(self.bootdir, efi_install)
if not os.path.exists(efi_input):
logging.warning("%s does not exist (%s)", efi_input, efi_install)
raise cliapp.AppException("Missing %s" % efi_install)
if not os.path.exists(os.path.dirname(efi_output)):
os.makedirs(os.path.dirname(efi_output))
logging.debug(
'Moving UEFI support: %s -> %s', efi_input, efi_output)
if os.path.exists(efi_output):
os.unlink(efi_output)
os.rename(efi_input, efi_output)
def configure_efi(self, rootdir):
"""
Copy the bootloader file from the package into the location
so needs to be after grub and kernel already installed.
"""
self.message('Configuring EFI')
mount_wrapper(rootdir)
efi_removable = str(arch_table[self.settings['arch']]['removable'])
efi_install = str(arch_table[self.settings['arch']]['install'])
self.message('Installing UEFI support binary')
self.copy_efi_binary(efi_removable, efi_install)
umount_wrapper(rootdir)
def configure_extra_efi(self, rootdir):
extra = str(arch_table[self.settings['arch']]['extra'])
if extra:
mount_wrapper(rootdir)
efi_removable = str(arch_table[extra]['removable'])
efi_install = str(arch_table[extra]['install'])
self.message('Copying UEFI support binary for %s' % extra)
self.copy_efi_binary(efi_removable, efi_install)
umount_wrapper(rootdir)
def partition_esp(self):
espsize = self.settings['esp-size'] / (1024 * 1024)
self.message("Using ESP size: %smib %s bytes" % (espsize, self.settings['esp-size']))
runcmd(['parted', '-s', self.settings['image'],
'mkpart', 'primary', 'fat32',
'1', str(espsize)])
runcmd(['parted', '-s', self.settings['image'],
'set', '1', 'boot', 'on'])
runcmd(['parted', '-s', self.settings['image'],
'set', '1', 'esp', 'on'])
def prepare_esp(self, rootdir, bootdev):
bootdir = '%s/%s/%s' % (rootdir, 'boot', 'efi')
logging.debug("bootdir:%s", self.bootdir)
self.mkfs(bootdev, fstype='vfat')
os.makedirs(bootdir)
return bootdir
|