41
41
def register_options(self):
42
group = self.vm.setting_group('Package options')
43
group.add_option('--addpkg', action='append', metavar='PKG', help='Install PKG into the guest (can be specfied multiple times).')
44
group.add_option('--removepkg', action='append', metavar='PKG', help='Remove PKG from the guest (can be specfied multiple times)')
45
self.vm.register_setting_group(group)
42
group = self.setting_group('Package options')
43
group.add_setting('addpkg', type='list', metavar='PKG', help='Install PKG into the guest (can be specfied multiple times).')
44
group.add_setting('removepkg', type='list', metavar='PKG', help='Remove PKG from the guest (can be specfied multiple times)')
47
group = self.vm.setting_group('General OS options')
46
group = self.setting_group('General OS options')
48
47
self.host_arch = run_cmd('dpkg', '--print-architecture').rstrip()
49
group.add_option('-a', '--arch', default=self.host_arch, help='Specify the target architecture. Valid options: amd64 i386 lpia (defaults to host arch)')
50
group.add_option('--hostname', default='ubuntu', help='Set NAME as the hostname of the guest. Default: ubuntu. Also uses this name as the VM name.')
51
self.vm.register_setting_group(group)
53
group = self.vm.setting_group('Installation options')
54
group.add_option('--suite', default='jaunty', help='Suite to install. Valid options: %s [default: %%default]' % ' '.join(self.suites))
55
group.add_option('--flavour', '--kernel-flavour', help='Kernel flavour to use. Default and valid options depend on architecture and suite')
56
group.add_option('--variant', metavar='VARIANT', help='Passed to debootstrap --variant flag; use minbase, buildd, or fakechroot.')
57
group.add_option('--iso', metavar='PATH', help='Use an iso image as the source for installation of file. Full path to the iso must be provided. If --mirror is also provided, it will be used in the final sources.list of the vm. This requires suite and kernel parameter to match what is available on the iso, obviously.')
58
group.add_option('--mirror', metavar='URL', help='Use Ubuntu mirror at URL instead of the default, which is http://archive.ubuntu.com/ubuntu for official arches and http://ports.ubuntu.com/ubuntu-ports otherwise')
59
group.add_option('--proxy', metavar='URL', help='Use proxy at URL for cached packages')
60
group.add_option('--install-mirror', metavar='URL', help='Use Ubuntu mirror at URL for the installation only. Apt\'s sources.list will still use default or URL set by --mirror')
61
group.add_option('--security-mirror', metavar='URL', help='Use Ubuntu security mirror at URL instead of the default, which is http://security.ubuntu.com/ubuntu for official arches and http://ports.ubuntu.com/ubuntu-ports otherwise.')
62
group.add_option('--install-security-mirror', metavar='URL', help='Use the security mirror at URL for installation only. Apt\'s sources.list will still use default or URL set by --security-mirror')
63
group.add_option('--components', metavar='COMPS', help='A comma seperated list of distro components to include (e.g. main,universe).')
64
group.add_option('--ppa', metavar='PPA', action='append', help='Add ppa belonging to PPA to the vm\'s sources.list.')
65
group.add_option('--lang', metavar='LANG', default=self.get_locale(), help='Set the locale to LANG [default: %default]')
66
group.add_option('--timezone', metavar='TZ', default='UTC', help='Set the timezone to TZ in the vm. [default: %default]')
67
self.vm.register_setting_group(group)
69
group = self.vm.setting_group('Settings for the initial user')
70
group.add_option('--user', default='ubuntu', help='Username of initial user [default: %default]')
71
group.add_option('--name', default='Ubuntu', help='Full name of initial user [default: %default]')
72
group.add_option('--pass', default='ubuntu', help='Password of initial user [default: %default]')
73
group.add_option('--rootpass', help='Initial root password (WARNING: this has strong security implications).')
74
group.add_option('--uid', help='Initial UID value.')
75
group.add_option('--gid', help='Initial GID value.')
76
group.add_option('--lock-user', action='store_true', help='Lock the initial user [default %default]')
77
self.vm.register_setting_group(group)
79
group = self.vm.setting_group('Other options')
80
group.add_option('--ssh-key', metavar='PATH', help='Add PATH to root\'s ~/.ssh/authorized_keys (WARNING: this has strong security implications).')
81
group.add_option('--ssh-user-key', help='Add PATH to the user\'s ~/.ssh/authorized_keys.')
82
group.add_option('--manifest', metavar='PATH', help='If passed, a manifest will be written to PATH')
83
self.vm.register_setting_group(group)
48
group.add_setting('arch', extra_args=['-a'], default=self.host_arch, help='Specify the target architecture. Valid options: amd64 i386 lpia (defaults to host arch)')
49
group.add_setting('hostname', default='ubuntu', help='Set NAME as the hostname of the guest. Default: ubuntu. Also uses this name as the VM name.')
51
group = self.setting_group('Installation options')
52
group.add_setting('suite', default='lucid', help='Suite to install. Valid options: %s [default: %%default]' % ' '.join(self.suites))
53
group.add_setting('flavour', extra_args=['--kernel-flavour'], help='Kernel flavour to use. Default and valid options depend on architecture and suite')
54
group.add_setting('variant', metavar='VARIANT', help='Passed to debootstrap --variant flag; use minbase, buildd, or fakechroot.')
55
group.add_setting('iso', metavar='PATH', help='Use an iso image as the source for installation of file. Full path to the iso must be provided. If --mirror is also provided, it will be used in the final sources.list of the vm. This requires suite and kernel parameter to match what is available on the iso, obviously.')
56
group.add_setting('mirror', metavar='URL', help='Use Ubuntu mirror at URL instead of the default, which is http://archive.ubuntu.com/ubuntu for official arches and http://ports.ubuntu.com/ubuntu-ports otherwise')
57
group.add_setting('proxy', metavar='URL', help='Use proxy at URL for cached packages')
58
group.add_setting('install-mirror', metavar='URL', help='Use Ubuntu mirror at URL for the installation only. Apt\'s sources.list will still use default or URL set by --mirror')
59
group.add_setting('security-mirror', metavar='URL', help='Use Ubuntu security mirror at URL instead of the default, which is http://security.ubuntu.com/ubuntu for official arches and http://ports.ubuntu.com/ubuntu-ports otherwise.')
60
group.add_setting('install-security-mirror', metavar='URL', help='Use the security mirror at URL for installation only. Apt\'s sources.list will still use default or URL set by --security-mirror')
61
group.add_setting('components', type='list', metavar='COMPS', help='A comma seperated list of distro components to include (e.g. main,universe).')
62
group.add_setting('ppa', metavar='PPA', type='list', help='Add ppa belonging to PPA to the vm\'s sources.list.')
63
group.add_setting('lang', metavar='LANG', default=self.get_locale(), help='Set the locale to LANG [default: %default]')
64
group.add_setting('timezone', metavar='TZ', default='UTC', help='Set the timezone to TZ in the vm. [default: %default]')
66
group = self.setting_group('Settings for the initial user')
67
group.add_setting('user', default='ubuntu', help='Username of initial user [default: %default]')
68
group.add_setting('name', default='Ubuntu', help='Full name of initial user [default: %default]')
69
group.add_setting('pass', default='ubuntu', help='Password of initial user [default: %default]')
70
group.add_setting('rootpass', help='Initial root password (WARNING: this has strong security implications).')
71
group.add_setting('uid', type='int', help='Initial UID value.')
72
group.add_setting('gid', help='Initial GID value.')
73
group.add_setting('lock-user', type='bool', default=False, help='Lock the initial user [default: %default]')
75
group = self.setting_group('Other options')
76
group.add_setting('ssh-key', metavar='PATH', help='Add PATH to root\'s ~/.ssh/authorized_keys (WARNING: this has strong security implications).')
77
group.add_setting('ssh-user-key', help='Add PATH to the user\'s ~/.ssh/authorized_keys.')
78
group.add_setting('manifest', metavar='PATH', help='If passed, a manifest will be written to PATH')
85
80
def set_defaults(self):
86
if not self.vm.mirror:
87
if self.vm.arch == 'lpia':
88
self.vm.mirror = 'http://ports.ubuntu.com/ubuntu-ports'
90
self.vm.mirror = 'http://archive.ubuntu.com/ubuntu'
92
if not self.vm.security_mirror:
93
if self.vm.arch == 'lpia':
94
self.vm.security_mirror = 'http://ports.ubuntu.com/ubuntu-ports'
96
self.vm.security_mirror = 'http://security.ubuntu.com/ubuntu'
98
if not self.vm.components:
99
self.vm.components = ['main', 'restricted', 'universe']
81
mirror = self.get_setting('mirror')
82
security_mirror = self.get_setting('security-mirror')
83
arch = self.get_setting('arch')
84
components = self.get_setting('components')
88
self.set_setting_default('mirror', 'http://ports.ubuntu.com/ubuntu-ports')
90
self.set_setting_default('mirror', 'http://archive.ubuntu.com/ubuntu')
92
if not security_mirror:
94
self.set_setting_default('security-mirror', 'http://ports.ubuntu.com/ubuntu-ports')
96
self.set_setting_default('security-mirror', 'http://security.ubuntu.com/ubuntu')
99
self.set_setting_default('components', ['main', 'restricted', 'universe'])
101
self.vm.components = self.vm.components.split(',')
101
self.set_setting_default('components', components.split(','))
103
103
def get_locale(self):
104
104
return os.getenv('LANG')
108
108
lead to failure, and since we can check them before we start setting up disk
109
109
and whatnot, we might as well go ahead an do this now."""
111
if not self.vm.suite in self.suites:
112
raise VMBuilderUserError('Invalid suite. Valid suites are: %s' % ' '.join(self.suites))
111
suite = self.get_setting('suite')
112
if not suite in self.suites:
113
raise VMBuilderUserError('Invalid suite: "%s". Valid suites are: %s' % (suite, ' '.join(self.suites)))
114
modname = 'VMBuilder.plugins.ubuntu.%s' % (self.vm.suite, )
115
mod = __import__(modname, fromlist=[self.vm.suite])
116
self.suite = getattr(mod, self.vm.suite.capitalize())(self.vm)
115
modname = 'VMBuilder.plugins.ubuntu.%s' % (suite, )
116
mod = __import__(modname, fromlist=[suite])
117
self.suite = getattr(mod, suite.capitalize())(self)
118
if self.vm.arch not in self.valid_archs[self.host_arch] or \
119
not self.suite.check_arch_validity(self.vm.arch):
120
raise VMBuilderUserError('%s is not a valid architecture. Valid architectures are: %s' % (self.vm.arch,
119
arch = self.get_setting('arch')
120
if arch not in self.valid_archs[self.host_arch] or \
121
not self.suite.check_arch_validity(arch):
122
raise VMBuilderUserError('%s is not a valid architecture. Valid architectures are: %s' % (arch,
121
123
' '.join(self.valid_archs[self.host_arch])))
123
if not self.vm.components:
124
self.vm.components = ['main', 'restricted', 'universe']
125
components = self.get_setting('components')
127
self.set_config_value_list = ['main', 'restricted', 'universe']
126
if type(self.vm.components) is str:
129
if type(components) is str:
127
130
self.vm.components = self.vm.components.split(',')
129
if self.vm.hypervisor.name == 'Xen':
130
logging.info('Xen kernel default: linux-image-%s %s', self.suite.xen_kernel_flavour, self.xen_kernel_version())
132
self.vm.virtio_net = self.use_virtio_net()
132
self.context.virtio_net = self.use_virtio_net()
134
lang = self.get_setting('lang')
136
run_cmd('locale-gen', '%s' % self.vm.lang)
137
run_cmd('locale-gen', '%s' % lang)
137
138
except VMBuilderException, e:
138
msg = "locale-gen does not recognize your locale '%s'" % self.vm.lang
139
raise VMBuilderUserError(msg)
141
if getattr(self.vm, 'ec2', False):
142
self.get_ec2_kernel()
143
self.get_ec2_ramdisk()
144
self.apply_ec2_settings()
139
raise VMBuilderUserError("Unrecognised locale: '%s'" % (lang, ))
142
# if getattr(self.vm, 'ec2', False):
143
# self.get_ec2_kernel()
144
# self.get_ec2_ramdisk()
145
# self.apply_ec2_settings()
148
self.suite.debootstrap()
149
self.suite.pre_install()
151
def configure_os(self):
152
self.suite.install_sources_list()
153
self.suite.install_apt_proxy()
154
self.suite.create_devices()
155
self.suite.prevent_daemons_starting()
156
self.suite.mount_dev_proc()
157
self.suite.install_extras()
158
self.suite.create_initial_user()
159
self.suite.install_authorized_keys()
160
self.suite.config_host_and_domainname()
161
self.suite.set_timezone()
163
self.suite.install_sources_list(final=True)
164
self.suite.run_in_target('apt-get', 'clean');
165
self.suite.unmount_volatile()
166
self.suite.unmount_proc()
167
self.suite.unmount_dev_pts()
168
self.suite.unmount_dev()
169
self.suite.unprevent_daemons_starting()
170
self.suite.create_manifest()
172
def configure_networking(self, nics):
173
self.suite.config_interfaces(nics)
175
def configure_mounting(self, disks, filesystems):
176
self.suite.install_fstab(disks, filesystems)
146
178
def install(self, destdir):
147
179
self.destdir = destdir
156
188
def use_virtio_net(self):
157
189
return self.suite.virtio_net
159
def install_bootloader_cleanup(self):
160
self.vm.cancel_cleanup(self.install_bootloader_cleanup)
161
tmpdir = '%s/tmp/vmbuilder-grub' % self.destdir
191
def install_bootloader_cleanup(self, chroot_dir):
192
self.context.cancel_cleanup(self.install_bootloader_cleanup)
193
tmpdir = '%s/tmp/vmbuilder-grub' % chroot_dir
162
194
for disk in os.listdir(tmpdir):
163
195
if disk != 'device.map':
164
196
run_cmd('umount', os.path.join(tmpdir, disk))
165
197
shutil.rmtree(tmpdir)
167
def install_bootloader(self):
199
def install_kernel(self, destdir):
200
self.suite.install_kernel(destdir)
202
def install_bootloader(self, chroot_dir, disks):
168
203
tmpdir = '/tmp/vmbuilder-grub'
169
os.makedirs('%s%s' % (self.destdir, tmpdir))
170
self.vm.add_clean_cb(self.install_bootloader_cleanup)
204
os.makedirs('%s%s' % (chroot_dir, tmpdir))
205
self.context.add_clean_cb(self.install_bootloader_cleanup)
171
206
devmapfile = os.path.join(tmpdir, 'device.map')
172
devmap = open('%s%s' % (self.destdir, devmapfile), 'w')
173
for (disk, id) in zip(self.vm.disks, range(len(self.vm.disks))):
207
devmap = open('%s%s' % (chroot_dir, devmapfile), 'w')
208
for (disk, id) in zip(disks, range(len(disks))):
174
209
new_filename = os.path.join(tmpdir, os.path.basename(disk.filename))
175
open('%s%s' % (self.destdir, new_filename), 'w').close()
176
run_cmd('mount', '--bind', disk.filename, '%s%s' % (self.destdir, new_filename))
210
open('%s%s' % (chroot_dir, new_filename), 'w').close()
211
run_cmd('mount', '--bind', disk.filename, '%s%s' % (chroot_dir, new_filename))
177
212
devmap.write("(hd%d) %s\n" % (id, new_filename))
214
self.suite.install_grub(chroot_dir)
179
215
self.run_in_target('grub', '--device-map=%s' % devmapfile, '--batch', stdin='''root (hd0,0)
182
self.install_bootloader_cleanup()
218
self.suite.install_menu_lst(disks)
219
self.install_bootloader_cleanup(chroot_dir)
184
221
def xen_kernel_version(self):
185
222
if self.suite.xen_kernel_flavour:
223
# if this is ec2, do not call rmadison.
224
# this could be replaced with a method to get most recent
225
# stable kernel, but really, this is not used at all for ec2
226
if hasattr(self.vm, 'ec2') and self.context.ec2:
227
logging.debug("selecting ec2 kernel")
228
self.xen_kernel = "2.6.ec2-kernel"
229
return self.xen_kernel
186
230
if not self.xen_kernel:
187
231
rmad = run_cmd('rmadison', 'linux-image-%s' % self.suite.xen_kernel_flavour)
188
232
version = ['0', '0','0', '0']