~ubuntu-branches/ubuntu/quantal/maas/quantal-security

« back to all changes in this revision

Viewing changes to src/provisioningserver/kernel_opts.py

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2012-08-02 09:01:43 UTC
  • mto: (1.2.1)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20120802090143-dutqktdjpiz61b61
Tags: upstream-0.1+bzr971+dfsg
ImportĀ upstreamĀ versionĀ 0.1+bzr971+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2012 Canonical Ltd.  This software is licensed under the
 
2
# GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
"""Generate kernel command-line options for inclusion in PXE configs."""
 
5
 
 
6
from __future__ import (
 
7
    absolute_import,
 
8
    print_function,
 
9
    unicode_literals,
 
10
    )
 
11
 
 
12
__metaclass__ = type
 
13
__all__ = [
 
14
    'compose_kernel_command_line_new',
 
15
    'KernelParameters',
 
16
    ]
 
17
 
 
18
from collections import namedtuple
 
19
import os
 
20
 
 
21
from provisioningserver.config import Config
 
22
from provisioningserver.pxe.tftppath import compose_image_path
 
23
from provisioningserver.utils import parse_key_value_file
 
24
 
 
25
 
 
26
class EphemeralImagesDirectoryNotFound(Exception):
 
27
    """The ephemeral images directory cannot be found."""
 
28
 
 
29
 
 
30
KernelParametersBase = namedtuple(
 
31
    "KernelParametersBase", (
 
32
        "arch",  # Machine architecture, e.g. "i386"
 
33
        "subarch",  # Machine subarchitecture, e.g. "generic"
 
34
        "release",  # Ubuntu release, e.g. "precise"
 
35
        "purpose",  # Boot purpose, e.g. "commissioning"
 
36
        "hostname",  # Machine hostname, e.g. "coleman"
 
37
        "domain",  # Machine domain name, e.g. "example.com"
 
38
        "preseed_url",  # URL from which a preseed can be obtained.
 
39
        "log_host",  # Host/IP to which syslog can be streamed.
 
40
        "fs_host",  # Host/IP on which ephemeral filesystems are hosted.
 
41
        ))
 
42
 
 
43
 
 
44
class KernelParameters(KernelParametersBase):
 
45
 
 
46
    # foo._replace() is just ugly, so alias it to __call__.
 
47
    __call__ = KernelParametersBase._replace
 
48
 
 
49
 
 
50
def compose_initrd_opt(arch, subarch, release, purpose):
 
51
    path = "%s/initrd.gz" % compose_image_path(arch, subarch, release, purpose)
 
52
    return "initrd=%s" % path
 
53
 
 
54
 
 
55
def compose_preseed_opt(preseed_url):
 
56
    """Compose a kernel option for preseed URL.
 
57
 
 
58
    :param preseed_url: The URL from which a preseed can be fetched.
 
59
    """
 
60
    return "auto url=%s" % preseed_url
 
61
 
 
62
 
 
63
def compose_suite_opt(release):
 
64
    return "suite=%s" % release
 
65
 
 
66
 
 
67
def compose_hostname_opt(hostname):
 
68
    return "hostname=%s" % hostname
 
69
 
 
70
 
 
71
def compose_domain_opt(domain):
 
72
    return "domain=%s" % domain
 
73
 
 
74
 
 
75
def compose_locale_opt():
 
76
    locale = 'en_US'
 
77
    return "locale=%s" % locale
 
78
 
 
79
 
 
80
def compose_logging_opts(log_host):
 
81
    return [
 
82
        'log_host=%s' % log_host,
 
83
        'log_port=%d' % 514,
 
84
        'text priority=%s' % 'critical',
 
85
        ]
 
86
 
 
87
 
 
88
def get_last_directory(root):
 
89
    """Return the last directory from the directories in the given root.
 
90
 
 
91
    This is used to get the most recent ephemeral import directory.
 
92
    The ephemeral directories are named after the release date: 20120424,
 
93
    20120424, 20120301, etc. so fetching the last one (sorting by name)
 
94
    returns the most recent.
 
95
    """
 
96
    dirs = [
 
97
        os.path.join(root, directory) for directory in os.listdir(root)]
 
98
    dirs = filter(os.path.isdir, dirs)
 
99
    return sorted(dirs)[-1]
 
100
 
 
101
 
 
102
ISCSI_TARGET_NAME_PREFIX = "iqn.2004-05.com.ubuntu:maas"
 
103
 
 
104
 
 
105
def get_ephemeral_name(release, arch):
 
106
    """Return the name of the most recent ephemeral image.
 
107
 
 
108
    That information is read from the config file named 'info' in the
 
109
    ephemeral directory e.g:
 
110
    /var/lib/maas/ephemeral/precise/ephemeral/i386/20120424/info
 
111
    """
 
112
    config = Config.load_from_cache()
 
113
    root = os.path.join(
 
114
        config["boot"]["ephemeral"]["directory"],
 
115
        release, 'ephemeral', arch)
 
116
    try:
 
117
        filename = os.path.join(get_last_directory(root), 'info')
 
118
    except OSError:
 
119
        raise EphemeralImagesDirectoryNotFound(
 
120
            "The directory containing the ephemeral images/info is missing "
 
121
            "(%r).  Make sure to run the script "
 
122
            "'maas-import-pxe-files'." % root)
 
123
    name = parse_key_value_file(filename, separator="=")['name']
 
124
    return name
 
125
 
 
126
 
 
127
def compose_purpose_opts(params):
 
128
    """Return the list of the purpose-specific kernel options."""
 
129
    if params.purpose == "commissioning":
 
130
        return [
 
131
            "iscsi_target_name=%s:%s" % (
 
132
                ISCSI_TARGET_NAME_PREFIX,
 
133
                get_ephemeral_name(params.release, params.arch)),
 
134
            "ip=dhcp",
 
135
            "ro root=LABEL=cloudimg-rootfs",
 
136
            "iscsi_target_ip=%s" % params.fs_host,
 
137
            "iscsi_target_port=3260",
 
138
            ]
 
139
    else:
 
140
        return [
 
141
            "netcfg/choose_interface=auto"
 
142
            ]
 
143
 
 
144
 
 
145
def compose_arch_opts(params):
 
146
    """Return any architecture-specific options required"""
 
147
    if (params.arch, params.subarch) == ("armhf", "highbank"):
 
148
        return ["console=ttyAMA0"]
 
149
    else:
 
150
        return []
 
151
 
 
152
 
 
153
def compose_kernel_command_line_new(params):
 
154
    """Generate a line of kernel options for booting `node`.
 
155
 
 
156
    :type params: `KernelParameters`.
 
157
    """
 
158
    options = [
 
159
        compose_initrd_opt(
 
160
            params.arch, params.subarch,
 
161
            params.release, params.purpose),
 
162
        compose_preseed_opt(params.preseed_url),
 
163
        compose_suite_opt(params.release),
 
164
        compose_hostname_opt(params.hostname),
 
165
        compose_domain_opt(params.domain),
 
166
        compose_locale_opt(),
 
167
        ]
 
168
    options += compose_purpose_opts(params)
 
169
    options += compose_logging_opts(params.log_host)
 
170
    options += compose_arch_opts(params)
 
171
    return ' '.join(options)