~ubuntu-branches/ubuntu/saucy/maas/saucy-updates

« back to all changes in this revision

Viewing changes to src/provisioningserver/tests/test_maas_import_pxe_files.py

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez, Julian Edwards, Raphaël Badin, Jeroen Vermeulen, Andres Rodriguez, Robie Basak, Scott Moser, Diogo Matsubara
  • Date: 2012-10-08 13:10:23 UTC
  • mfrom: (1.1.18)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20121008131023-68glibh0pbqrgtfq
Tags: 0.1+bzr1223+dfsg-0ubuntu1
* New upstream release. (LP: #1062518)

[ Julian Edwards ]
* Split packaging of 'maas' into maas-{region,cluster}-controller
  - debian/control: Update accordingly.
  - debian/*.install: Move files accordingly
  - debian/*.{postinst,postrm,preinst}: Move files accordingly.
* Ensure isc-dhcp-server is disabled when installing maas-dhcp.
* Ensure maas-dns creates the maas user before trying to chown files.
* Make maas-cluster-controller autoconfigure itself when upgrading from the
  old maas package. (LP: #1059416)
* Add missing prerm file for maas-cluster-controller so that .pyc files
  are cleaned up. (LP: #1059973)

[ Raphaël Badin ]
* Install maas_local_celeryconfig.py in /etc/maas and symlink to
  /usr/share/maas.
* debian/maas.postinst: Create rabbitmq celery user/vhost.
* debian/maas.postinst: Update BROKER_URL in maas_local_celeryconfig.py.
* Use maas_local_celeryconfig_cluster.py as the local celery
  configuration file for the cluster worker.
* debian/maas-region-controller.maas-region-celery.upstart: Add region
  worker upstart script.
* Rename cluster worker upstart script into
  maas-cluster-controller.maas-clluster-celery.upstart.
* maas-cluster-controller.maas-celery.upstart: use "celeryconfig_cluster"
  as the Celery config module.
* debian/maas-common.install: Install celeryconfig_common.py.
* debian/maas-cluster-controller.install: Install celeryconfig_cluster.py.
* debian/maas-region-controller.install: Install celeryconfig.py.
* Split celery config into cluster and region configs.
* Add region celeryd upstart config.
* Define CELERY_CONFIG_MODULE in
  maas-cluster-controller.maas-cluster-celery.upstart

[ Jeroen Vermeulen ]
* Make maas_local_celery_config.py non-world readable.
* Make maas_local_celeryconfig_cluster.py non-world readable.
* Set root:maas ownership of local cluster config only *after*
  the maas user/group have been created

[ Andres Rodriguez ]
* debian/maas.postinst:
  - Always restart apache2.
  - Handle upgrades for new upstream release.
  - Handle upgrades for celery rabbitmq worker.
* Add binary package to install client tool.
  - debian/extras/maas-cli: Add binary.
  - debian/maas-cli.install: Add. Install maascli and apiclient.
  - debian/control: Add binary package.
* debian/control:
  - Depends on freeipmi-tools instead of ipmitool.
  - Conflicts/Replaces on maas for python-maas-client.
  - Depends on python-netifaces, python-lxml.
* Add python-maas-client binary package:
  - debian/python-maas-client.install: Add. Install 'apiclient' python module.
  - debian/control: Add package. python-django-maas and maas-cli now
    Depend on it.
* debian/rules: Install maas-dhcp-server upstart job.
* debian/maas.postrm: Remove celery worker rabbitmq user and host.
* debian/extras/99-maas-sudoers: Add for maas-dhcp-server upstart job
  instead of isc-dhcp-server (LP: #1055951)
* debian/maas-region-controller.postinst: Cleanup upgrade rules.
* debian/maas-cluster-controller.postinst: Fix 'local' usage.
* debian/maas-common.install: Install celeryconfig in appropriate location.
* debian/maas-cluster-controller.postrm: Add and delete maas user.
* debian/maas-dhcp.postinst: Stop isc-dhcp-server not isc_dhcp_server.
* debian/maas-region-controller.postinst:
  - Always update passwords on upgrade. No longer check versioning. (LP: #1060094).
  - Add MAAS server to allowed mirror in squid-deb-proxy
  - Source dbconfig conf file for maas-region-controller on upgrade because
    it writes a new config file and no longer preservers the previous password.
* debian/maas-cluster-controller.maas-cluster-celery.upstart: Remove set{uid/gid}.
* debian/maas-region-controller.install: Install maas-import-squashfs
* Handle removal of non existant files (LP: #1059556):
  - debian/maintscript: Added to handle removal of conffiles.
  - debian/control: Add Pre-depends and bump debhelper version.
* update po files for the templates.
* debian/extras/99-maas: Install in usr/share/maas/conf and symlink to the
  appropriate etc dir.
* debian/maas-cluster-controller.config: Source debconf at the beginning of the
  script. (LP: #1063857)
* debian/patches/99-temporary-fix-constraints.patch: Fix constraints maaping
  when deploying with juju. Temporary until it gets merged upstream

[ Robie Basak ]
* Add maas-cluster-controller dependency on uuid-runtime, needed for uuidgen
  by postinst.

[ Scott Moser ]
* debian/maas-dhcp.{install,apparmor,postrm} install apparmor profile into
  /etc/apparmor.d/dhcpd.d (LP: #1049177), and update apparmor profile for
  /usr/sbin/dhcpd on install/remove
* get the ip address for the dhcp server in config

[ Diogo Matsubara ]
* Add initial tests to be run by autotests:
  - debian/control: XS-Testsuite: autopkgtest
  - debian/tests/control: Add
  - debian/tests/maas-package-test: Add
  - tests/maas-integration.py: Add

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
    :return: Full absolute path to the directory holding the requisite files
48
48
        for this archive, arch, and release.
49
49
    """
50
 
    return os.path.join(
51
 
        archive, 'dists', release, 'main', 'installer-%s' % arch, 'current',
52
 
        'images', 'netboot', 'ubuntu-installer', arch)
 
50
    if arch[0] in {'amd64', 'i386'}:
 
51
        return os.path.join(
 
52
            archive, 'dists', release, 'main', 'installer-%s' % arch[0],
 
53
            'current', 'images', 'netboot', 'ubuntu-installer', arch[0])
 
54
    elif arch[0] == 'armhf':
 
55
        return os.path.join(
 
56
            archive, 'dists', '%s-updates' % release, 'main',
 
57
            'installer-%s' % arch[0], 'current', 'images', arch[1], 'netboot')
 
58
    else:
 
59
        raise NotImplementedError('Unknown architecture: %r' % arch)
 
60
 
 
61
 
 
62
def compose_download_kernel_name(arch, release):
 
63
    """Name the kernel file expected to be found in a netboot archive.
 
64
 
 
65
    :param archive: Archive directory (corresponding to the script's ARCHIVE
 
66
        setting, except here it's a filesystem path not a URL).
 
67
    :param arch: Architecture.
 
68
    :return: the kernel name string, eg. "vmlinuz" or "linux" as appropriate
 
69
    """
 
70
    if arch[0] in {'amd64', 'i386'}:
 
71
        return 'linux'
 
72
    elif arch[0] == 'armhf':
 
73
        return 'vmlinuz'
 
74
    else:
 
75
        raise NotImplementedError('Unknown architecture: %r' % arch)
 
76
 
 
77
 
 
78
def compose_download_filenames(arch, release):
 
79
    """Name files expected to be found in the directory of a netboot archive.
 
80
 
 
81
    :param archive: Archive directory (corresponding to the script's ARCHIVE
 
82
        setting, except here it's a filesystem path not a URL).
 
83
    :param arch: Architecture.
 
84
    :return: list of names to be found in the netboot directory for this
 
85
        particular arch and release. Eg: ['vmlinuz', 'initrd.gz'] or
 
86
        ['linux', 'initrd.gz'] as appropriate.
 
87
    """
 
88
    return [compose_download_kernel_name(arch, release), 'initrd.gz']
53
89
 
54
90
 
55
91
def compose_tftp_bootloader_path(tftproot):
67
103
    """
68
104
    return os.path.join(
69
105
        tftppath.locate_tftp_path(
70
 
            tftppath.compose_image_path(arch, "generic", release, purpose),
 
106
            tftppath.compose_image_path(arch[0], arch[1], release, purpose),
71
107
            tftproot),
72
108
        *path)
73
109
 
74
110
 
75
111
class TestImportPXEFiles(TestCase):
76
112
 
 
113
    scenarios = (
 
114
        ("i386/generic", dict(arch=("i386", "generic"))),
 
115
        ("amd64/generic", dict(arch=("amd64", "generic"))),
 
116
        ("armhf/highbank", dict(arch=("armhf", "highbank"))),
 
117
        )
 
118
 
77
119
    def setUp(self):
78
120
        super(TestImportPXEFiles, self).setUp()
79
121
        self.tftproot = self.make_dir()
88
130
        """
89
131
        if release is None:
90
132
            release = factory.make_name('release')
91
 
        if arch is None:
92
 
            arch = factory.make_name('arch')
93
133
        archive = self.make_dir()
94
134
        download = compose_download_dir(archive, arch, release)
95
135
        os.makedirs(download)
96
 
        for filename in ['initrd.gz', 'linux']:
 
136
        for filename in compose_download_filenames(arch, release):
97
137
            factory.make_file(download, filename)
98
138
        return archive
99
139
 
100
140
    def call_script(self, archive_dir, tftproot, arch=None, release=None):
101
 
        """Call the maas-download-pxe-files script with given settings.
 
141
        """Call the maas-import-pxe-files script with given settings.
102
142
 
103
143
        The ARCHIVE URL and TFTPROOT path must be set, or the script will try
104
144
        to download from the Ubuntu server and store into the system's real
120
160
            # Suppress running of maas-import-ephemerals.  It gets too
121
161
            # intimate with the system to test here.
122
162
            'IMPORT_EPHEMERALS': '0',
 
163
            # Suppress running of maas-import-squashfs.  It gets too
 
164
            # intimate with the system to test here.
 
165
            'IMPORT_SQUASHFS': '0',
123
166
        }
124
167
        env.update(self.config_fixture.environ)
125
168
        if arch is not None:
126
 
            env['ARCHES'] = arch
 
169
            env['ARCHES'] = '/'.join(arch)
127
170
        if release is not None:
128
171
            env['RELEASES'] = release
129
172
 
131
174
            check_call(script, env=env, stdout=dev_null)
132
175
 
133
176
    def test_procures_pre_boot_loader(self):
134
 
        arch = factory.make_name('arch')
135
177
        release = 'precise'
136
 
        archive = self.make_downloads(arch=arch, release=release)
137
 
        self.call_script(archive, self.tftproot, arch=arch, release=release)
 
178
        archive = self.make_downloads(arch=self.arch, release=release)
 
179
        self.call_script(
 
180
            archive, self.tftproot, arch=self.arch, release=release)
138
181
        tftp_path = compose_tftp_bootloader_path(self.tftproot)
139
182
        expected_contents = read_file('/usr/lib/syslinux', 'pxelinux.0')
140
183
        self.assertThat(tftp_path, FileContains(expected_contents))
141
184
 
142
185
    def test_updates_pre_boot_loader(self):
143
 
        arch = factory.make_name('arch')
144
186
        release = 'precise'
145
187
        tftp_path = compose_tftp_bootloader_path(self.tftproot)
146
188
        with open(tftp_path, 'w') as existing_file:
147
189
            existing_file.write(factory.getRandomString())
148
 
        archive = self.make_downloads(arch=arch, release=release)
149
 
        self.call_script(archive, self.tftproot, arch=arch, release=release)
 
190
        archive = self.make_downloads(arch=self.arch, release=release)
 
191
        self.call_script(
 
192
            archive, self.tftproot, arch=self.arch, release=release)
150
193
        expected_contents = read_file('/usr/lib/syslinux', 'pxelinux.0')
151
194
        self.assertThat(tftp_path, FileContains(expected_contents))
152
195
 
153
196
    def test_procures_install_image(self):
154
 
        arch = factory.make_name('arch')
155
197
        release = 'precise'
156
 
        archive = self.make_downloads(arch=arch, release=release)
157
 
        self.call_script(archive, self.tftproot, arch=arch, release=release)
 
198
        archive = self.make_downloads(arch=self.arch, release=release)
 
199
        self.call_script(
 
200
            archive, self.tftproot, arch=self.arch, release=release)
158
201
        tftp_path = compose_tftp_path(
159
 
            self.tftproot, arch, release, 'install', 'linux')
160
 
        download_path = compose_download_dir(archive, arch, release)
161
 
        expected_contents = read_file(download_path, 'linux')
 
202
            self.tftproot, self.arch, release, 'install', 'linux')
 
203
        download_path = compose_download_dir(archive, self.arch, release)
 
204
        expected_contents = read_file(download_path,
 
205
            compose_download_kernel_name(self.arch, release))
162
206
        self.assertThat(tftp_path, FileContains(expected_contents))
163
207
 
164
208
    def test_updates_install_image(self):
165
 
        arch = factory.make_name('arch')
166
209
        release = 'precise'
167
210
        tftp_path = compose_tftp_path(
168
 
            self.tftproot, arch, release, 'install', 'linux')
 
211
            self.tftproot, self.arch, release, 'install', 'linux')
169
212
        os.makedirs(os.path.dirname(tftp_path))
170
213
        with open(tftp_path, 'w') as existing_file:
171
214
            existing_file.write(factory.getRandomString())
172
 
        archive = self.make_downloads(arch=arch, release=release)
173
 
        self.call_script(archive, self.tftproot, arch=arch, release=release)
174
 
        download_path = compose_download_dir(archive, arch, release)
175
 
        expected_contents = read_file(download_path, 'linux')
 
215
        archive = self.make_downloads(arch=self.arch, release=release)
 
216
        self.call_script(
 
217
            archive, self.tftproot, arch=self.arch, release=release)
 
218
        download_path = compose_download_dir(archive, self.arch, release)
 
219
        expected_contents = read_file(download_path,
 
220
            compose_download_kernel_name(self.arch, release))
176
221
        self.assertThat(tftp_path, FileContains(expected_contents))
177
222
 
178
223
    def test_leaves_install_image_untouched_if_unchanged(self):
179
 
        arch = factory.make_name('arch')
180
224
        release = 'precise'
181
 
        archive = self.make_downloads(arch=arch, release=release)
182
 
        self.call_script(archive, self.tftproot, arch=arch, release=release)
 
225
        archive = self.make_downloads(arch=self.arch, release=release)
 
226
        self.call_script(
 
227
            archive, self.tftproot, arch=self.arch, release=release)
183
228
        tftp_path = compose_tftp_path(
184
 
            self.tftproot, arch, release, 'install', 'linux')
 
229
            self.tftproot, self.arch, release, 'install', 'linux')
185
230
        backdate(tftp_path)
186
231
        original_timestamp = get_write_time(tftp_path)
187
 
        self.call_script(archive, self.tftproot, arch=arch, release=release)
 
232
        self.call_script(
 
233
            archive, self.tftproot, arch=self.arch, release=release)
188
234
        self.assertEqual(original_timestamp, get_write_time(tftp_path))