~lutostag/ubuntu/trusty/maas/1.5.4+keystone

« back to all changes in this revision

Viewing changes to src/metadataserver/models/commissioningscript.py

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2013-03-04 11:49:44 UTC
  • mto: This revision was merged to the branch mainline in revision 25.
  • Revision ID: package-import@ubuntu.com-20130304114944-azcvu9anlf8mizpa
Tags: upstream-1.3+bzr1452+dfsg
ImportĀ upstreamĀ versionĀ 1.3+bzr1452+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
"""Custom commissioning scripts, and their database backing."""
 
5
 
 
6
 
 
7
from __future__ import (
 
8
    absolute_import,
 
9
    print_function,
 
10
    unicode_literals,
 
11
    )
 
12
 
 
13
__metaclass__ = type
 
14
__all__ = [
 
15
    'CommissioningScript',
 
16
    ]
 
17
 
 
18
from io import BytesIO
 
19
import os.path
 
20
import tarfile
 
21
from textwrap import dedent
 
22
import time
 
23
 
 
24
from django.db.models import (
 
25
    CharField,
 
26
    Manager,
 
27
    Model,
 
28
    )
 
29
from metadataserver import DefaultMeta
 
30
from metadataserver.fields import BinaryField
 
31
 
 
32
# Path prefix for commissioning scripts.  Commissioning scripts will be
 
33
# extracted into this directory.
 
34
ARCHIVE_PREFIX = "commissioning.d"
 
35
 
 
36
# Built-in script to run lshw.
 
37
LSHW_SCRIPT = dedent("""\
 
38
    #!/bin/sh
 
39
    lshw -xml
 
40
    """)
 
41
 
 
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'),
 
48
}
 
49
 
 
50
 
 
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
 
57
    tarinfo.mode = 0755
 
58
    # Modification time defaults to Epoch, which elicits annoying
 
59
    # warnings when decompressing.
 
60
    tarinfo.mtime = mtime
 
61
    tarball.addfile(tarinfo, BytesIO(content))
 
62
 
 
63
 
 
64
class CommissioningScriptManager(Manager):
 
65
    """Utility for the collection of `CommissioningScript`s."""
 
66
 
 
67
    def get_archive(self):
 
68
        """Produce a tar archive of all commissioning scripts.
 
69
 
 
70
        Each of the scripts will be in the `ARCHIVE_PREFIX` directory.
 
71
        """
 
72
        mtime = time.time()
 
73
        binary = BytesIO()
 
74
        tarball = tarfile.open(mode='w', fileobj=binary)
 
75
        scripts = sorted(
 
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)
 
81
        tarball.close()
 
82
        binary.seek(0)
 
83
        return binary.read()
 
84
 
 
85
 
 
86
class CommissioningScript(Model):
 
87
    """User-provided commissioning script.
 
88
 
 
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.
 
91
    """
 
92
 
 
93
    class Meta(DefaultMeta):
 
94
        """Needed for South to recognize this model."""
 
95
 
 
96
    objects = CommissioningScriptManager()
 
97
 
 
98
    name = CharField(max_length=255, null=False, editable=True, unique=True)
 
99
    content = BinaryField(null=False)