~allenap/maas/xxx-a-thon

« back to all changes in this revision

Viewing changes to src/maasserver/management/commands/template.py

  • Committer: LaMont Jones
  • Date: 2016-03-07 23:20:52 UTC
  • mfrom: (4657.1.84 maas)
  • mto: (4657.1.93 maas)
  • mto: This revision was merged to the branch mainline in revision 4660.
  • Revision ID: lamont@canonical.com-20160307232052-rgfxbq7dujj6s093
MergeĀ fromĀ trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2016 Canonical Ltd.  This software is licensed under the
 
2
# GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
"""Django command: Update database-backed templates."""
 
5
 
 
6
__all__ = []
 
7
 
 
8
 
 
9
from optparse import (
 
10
    make_option,
 
11
    SUPPRESS_HELP,
 
12
)
 
13
import sys
 
14
from textwrap import dedent
 
15
 
 
16
from django.core.management.base import (
 
17
    BaseCommand,
 
18
    CommandError,
 
19
)
 
20
from maasserver.data import templates
 
21
from maasserver.models import Template
 
22
 
 
23
 
 
24
def _update_templates(verbosity, stdout):
 
25
    """Updates each template embedded in the Python code at
 
26
    src/maasserver/data/templates.py.
 
27
    """
 
28
    for filename in sorted(templates):
 
29
        data = templates[filename]
 
30
        Template.objects.create_or_update_default(
 
31
            filename, data, verbosity=verbosity, stdout=stdout)
 
32
 
 
33
 
 
34
def _force_delete_all(verbosity, stdout):
 
35
    """Forcibly deletes all templates and their corresponding data."""
 
36
    if verbosity > 0:
 
37
        stdout.write("Deleting %d templates...\n" % Template.objects.count())
 
38
    # Need to iterate here so that the custom delete() code gets called.
 
39
    for template in Template.objects.all():
 
40
        template.delete()
 
41
    if verbosity > 0:
 
42
        stdout.write("It would now be wise to run:\n")
 
43
        stdout.write("    sudo maas-region template update-defaults\n")
 
44
 
 
45
 
 
46
class Command(BaseCommand):
 
47
    # Note: we don't actually need any options (all of these commands simply
 
48
    # look at the `args` list), but Django's command framework will complain
 
49
    # if we don't have at least one. So we'll go "above and beyond" and take
 
50
    # filenames in argument format, for commands that use them.
 
51
    option_list = BaseCommand.option_list + (
 
52
        make_option(
 
53
            '--filename', dest='filename', default=None, help=SUPPRESS_HELP),
 
54
    )
 
55
    help = (dedent("""\
 
56
        Used to manage MAAS template files.
 
57
 
 
58
        Commands:
 
59
            list
 
60
                Shows a list of all the template files in the database.
 
61
 
 
62
            show <filename>
 
63
                Displays the current value of the specified template.
 
64
 
 
65
            show-default <filename>
 
66
                Displays the default value of the specified template.
 
67
 
 
68
            update-defaults
 
69
                Updates the default value of all templates in the database
 
70
                based on the currently-installed MAAS version. (Intended
 
71
                to be called automatically during an upgrade or a fresh
 
72
                install.)
 
73
 
 
74
            force-delete-all
 
75
                Forcibly deletes all templates, and associated versioned
 
76
                text files stored in the database. Intended to be used in
 
77
                the event of a corrupted database.
 
78
 
 
79
                IMPORTANT: It would be wise to run the 'update-defaults'
 
80
                command immediately after running this, to avoid breaking
 
81
                the operation of MAAS.
 
82
 
 
83
                VERY IMPORTANT: This will delete any modified templates
 
84
                in addition to the templates' default values.
 
85
        """))
 
86
 
 
87
    def print_error_with_help(self, message, stdout):
 
88
        stdout.write(self.help)
 
89
        raise CommandError(message)
 
90
 
 
91
    def handle(self, *args, **options):
 
92
        verbosity = options.get('verbosity')
 
93
        filename = options.get('filename')
 
94
        stdout = options.get('stdout')
 
95
        if stdout is None:
 
96
            stdout = sys.stdout
 
97
        if len(args) == 0:
 
98
            self.print_error_with_help("Command required.", stdout)
 
99
        elif args[0] == 'show':
 
100
            self._template_show(args, filename, stdout)
 
101
        elif args[0] == 'show-default':
 
102
            self._template_show_default(args, filename, stdout)
 
103
        elif args[0] == 'list':
 
104
            self._template_list(args, verbosity, stdout)
 
105
        elif args[0] == 'revert':
 
106
            self._template_revert(args, filename, verbosity, stdout)
 
107
        elif args[0] == 'update-defaults':
 
108
            _update_templates(verbosity, stdout)
 
109
        elif args[0] == 'force-delete-all':
 
110
            _force_delete_all(verbosity, stdout)
 
111
        else:
 
112
            self.print_error_with_help("Invalid command.", stdout)
 
113
 
 
114
    def _template_list(self, args, verbosity, stdout):
 
115
        for template in Template.objects.order_by('filename'):
 
116
            stdout.write("%s\n" % template.filename)
 
117
 
 
118
    def _template_revert(self, args, filename, verbosity, stdout):
 
119
        if len(args) > 1:
 
120
            filename = args[1]
 
121
        template = Template.objects.get_by_filename(filename)
 
122
        if template is None:
 
123
            raise CommandError("Template not found: %s" % filename)
 
124
        template.revert(verbosity=verbosity, stdout=stdout)
 
125
 
 
126
    def _template_show_default(self, args, filename, stdout):
 
127
        # 'template show-default' command
 
128
        if len(args) > 1:
 
129
            filename = args[1]
 
130
        if filename is None:
 
131
            raise CommandError(dedent("""\
 
132
                Invalid usage. Required:
 
133
                    template show-default <filename>
 
134
                """))
 
135
        template = Template.objects.get_by_filename(filename)
 
136
        if template is not None:
 
137
            stdout.write(template.default_value)
 
138
        else:
 
139
            raise CommandError("Template not found: %s" % filename)
 
140
 
 
141
    def _template_show(self, args, filename, stdout):
 
142
        # 'template show' command
 
143
        if len(args) > 1:
 
144
            filename = args[1]
 
145
        if filename is None:
 
146
            raise CommandError(dedent("""\
 
147
                Invalid usage. Required:
 
148
                    template show <filename>
 
149
                """))
 
150
        template = Template.objects.get_by_filename(filename)
 
151
        if template is not None:
 
152
            stdout.write(template.value)
 
153
        else:
 
154
            raise CommandError("Template not found: %s" % filename)