1
# Copyright 2012 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
"""Custom commissioning scripts, and their database backing."""
7
from __future__ import (
15
'CommissioningScript',
18
from io import BytesIO
21
from textwrap import dedent
24
from django.db.models import (
29
from metadataserver import DefaultMeta
30
from metadataserver.fields import BinaryField
32
# Path prefix for commissioning scripts. Commissioning scripts will be
33
# extracted into this directory.
34
ARCHIVE_PREFIX = "commissioning.d"
36
# Built-in script to run lshw.
37
LSHW_SCRIPT = dedent("""\
42
# Built-in commissioning scripts. These go into the commissioning
43
# tarball together with user-provided commissioning scripts.
44
# To keep namespaces separated, names of the built-in scripts must be
45
# prefixed with "00-maas-" or "99-maas-".
46
BUILTIN_COMMISSIONING_SCRIPTS = {
47
'00-maas-01-lshw': LSHW_SCRIPT.encode('ascii'),
51
def add_script_to_archive(tarball, name, content, mtime):
52
"""Add a commissioning script to an archive of commissioning scripts."""
53
assert isinstance(content, bytes), "Script content must be binary."
54
tarinfo = tarfile.TarInfo(name=os.path.join(ARCHIVE_PREFIX, name))
55
tarinfo.size = len(content)
56
# Mode 0755 means: u=rwx,go=rx
58
# Modification time defaults to Epoch, which elicits annoying
59
# warnings when decompressing.
61
tarball.addfile(tarinfo, BytesIO(content))
64
class CommissioningScriptManager(Manager):
65
"""Utility for the collection of `CommissioningScript`s."""
67
def get_archive(self):
68
"""Produce a tar archive of all commissioning scripts.
70
Each of the scripts will be in the `ARCHIVE_PREFIX` directory.
74
tarball = tarfile.open(mode='w', fileobj=binary)
76
BUILTIN_COMMISSIONING_SCRIPTS.items() +
77
[(script.name, script.content) for script in self.all()])
78
for name, content in scripts:
79
add_script_to_archive(
80
tarball=tarball, name=name, content=content, mtime=mtime)
86
class CommissioningScript(Model):
87
"""User-provided commissioning script.
89
Actually a commissioning "script" could be a binary, e.g. because a
90
hardware vendor supplied an update in the form of a binary executable.
93
class Meta(DefaultMeta):
94
"""Needed for South to recognize this model."""
96
objects = CommissioningScriptManager()
98
name = CharField(max_length=255, null=False, editable=True, unique=True)
99
content = BinaryField(null=False)