~ubuntu-branches/ubuntu/precise/vm-builder/precise

« back to all changes in this revision

Viewing changes to VMBuilder/plugins/__init__.py

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2010-02-22 13:56:18 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20100222135618-la13e3mu397rg0m1
Tags: 0.12.0-0ubuntu1
* New upstream release. (FFe: LP: #525741)
  - All patches incorporated upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
18
#
19
19
import os
 
20
import re
 
21
 
20
22
import VMBuilder
21
 
from VMBuilder.util import run_cmd
 
23
import VMBuilder.util as util
 
24
from VMBuilder.exception import VMBuilderException
22
25
 
23
26
def load_plugins():
24
27
    for plugin in find_plugins():
34
37
    return retval
35
38
 
36
39
class Plugin(object):
37
 
    def __init__(self, vm):
38
 
        self.vm = vm
 
40
    priority = 10
 
41
 
 
42
    def __init__(self, context):
 
43
        self.context = context
 
44
        self._setting_groups = []
39
45
        self.register_options()
40
46
 
41
47
    def register_options(self):
58
64
        """
59
65
        pass
60
66
 
61
 
    def deploy(self):
62
 
        """
63
 
        Perform deployment of the VM.
64
 
 
65
 
        If True is returned, no further deployment will be done.
66
 
        """
67
 
        return False
 
67
    def install_file(self, path, contents=None, source=None, mode=None):
 
68
        fullpath = '%s%s' % (self.chroot_dir, path)
 
69
        if not os.path.isdir(os.path.dirname(fullpath)):
 
70
            os.makedirs(os.path.dirname(fullpath))
 
71
        if source and not contents:
 
72
            shutil.copy(source, fullpath) 
 
73
        else:
 
74
            fp = open(fullpath, 'w')
 
75
            fp.write(contents)
 
76
            fp.close()
 
77
        if mode:
 
78
            os.chmod(fullpath, mode)
 
79
        return fullpath
68
80
 
69
81
    def install_from_template(self, path, tmplname, context=None, mode=None):
70
 
        if not self.vm.fsmounted:
71
 
            raise VMBuilderException('install_from_template called while file system is not mounted')
72
 
        return self.vm.install_file(path, VMBuilder.util.render_template(self.__module__.split('.')[2], self.vm, tmplname, context), mode=mode)
 
82
        return self.install_file(path, VMBuilder.util.render_template(self.__module__.split('.')[2], self.context, tmplname, context), mode=mode)
73
83
 
74
84
    def run_in_target(self, *args, **kwargs):
75
 
        if not self.vm.fsmounted:
76
 
            raise VMBuilderException('install_from_template called while file system is not mounted')
77
 
        return run_cmd('chroot', self.vm.installdir, *args, **kwargs)
 
85
        return util.run_cmd('chroot', self.chroot_dir, *args, **kwargs)
 
86
 
 
87
    def call_hooks(self, *args, **kwargs):
 
88
        return util.call_hooks(self.context, *args, **kwargs)
 
89
 
 
90
    # Settings
 
91
    class SettingGroup(object):
 
92
        def __init__(self, plugin, context, name):
 
93
            # The plugin that owns this setting
 
94
            self.plugin = plugin
 
95
            # The VM object
 
96
            self.context = context
 
97
            # Name of the Setting Group
 
98
            self.name = name
 
99
            # A list of Setting objects
 
100
            self._settings = []
 
101
 
 
102
        def add_setting(self, *args, **kwargs):
 
103
            # kwarg['type'] is used to determine which type of Setting object to create
 
104
            # but we don't want to pass it on to its __init__.
 
105
            if 'type' in kwargs:
 
106
                type = kwargs['type']
 
107
                del kwargs['type']
 
108
            else:
 
109
                type = 'str'
 
110
 
 
111
            if type == 'str':
 
112
                setting = self.plugin.StringSetting(self, *args, **kwargs)
 
113
            elif type == 'bool':
 
114
                setting = self.plugin.BooleanSetting(self, *args, **kwargs)
 
115
            elif type == 'list':
 
116
                setting = self.plugin.ListSetting(self, *args, **kwargs)
 
117
            elif type == 'int':
 
118
                setting = self.plugin.IntSetting(self, *args, **kwargs)
 
119
            else:
 
120
                raise VMBuilderException("Unknown setting type: '%s' (Plugin: '%s', Setting group: '%s', Setting: '%s')" % 
 
121
                                            (type,
 
122
                                             self.plugin.__module__,
 
123
                                             self.name,
 
124
                                             args[0]))
 
125
            self._settings.append(setting)
 
126
 
 
127
    class Setting(object):
 
128
        default = None
 
129
 
 
130
        def __init__(self, setting_group, name, metavar=None, help=None, extra_args=None, valid_options=None, action=None, **kwargs):
 
131
            # The Setting Group object that owns this Setting
 
132
            self.setting_group = setting_group
 
133
            # The name if the setting
 
134
            name_regex = '[a-z0-9-]+$'
 
135
            if not re.match(name_regex, name):
 
136
                raise VMBuilderException('Invalid name for Setting: %s. Must match regex: %s' % (name, name_regex))
 
137
            else:
 
138
                self.name = name
 
139
 
 
140
            self.default = kwargs.get('default', self.default)
 
141
            self.help = help
 
142
            # Alternate names (for the CLI)
 
143
            self.extra_args = extra_args or []
 
144
            self.metavar = metavar
 
145
            self.value = None
 
146
            self.value_set = False
 
147
            self.valid_options = valid_options
 
148
 
 
149
            if self.name in self.setting_group.context._config:
 
150
                raise VMBuilderException("Setting named %s already exists. Previous definition in %s/%s/%s." % 
 
151
                                            (self.name,
 
152
                                             self.setting_group.plugin.__name__,
 
153
                                             self.setting_group.plugin._config[self.name].setting_group.name,
 
154
                                             self.setting_group.plugin._config[self.name].name))
 
155
 
 
156
            self.setting_group.context._config[self.name] = self
 
157
 
 
158
        def get_value(self):
 
159
            """
 
160
            If a value has previously been set, return it.
 
161
            If not, return the default value.
 
162
            """
 
163
 
 
164
            if self.value_set:
 
165
                return self.value
 
166
            else:
 
167
                return self.default
 
168
 
 
169
        def do_check_value(self, value):
 
170
            """
 
171
            Checks the value's validity.
 
172
            """
 
173
            if self.valid_options is not None:
 
174
                if value not in self.valid_options:
 
175
                    raise VMBuilderException('%r is not a valid option for %s. Valid options are: %s' % (value, self.name, ' '.join(self.valid_options)))
 
176
            else:
 
177
                self.check_value(value)
 
178
 
 
179
        def get_valid_options(self):
 
180
            return self.valid_options
 
181
 
 
182
        def set_valid_options(self, valid_options):
 
183
            """
 
184
            Set the list of valid options for this setting.
 
185
            """
 
186
            if not type(valid_options) == list and valid_options is not None:
 
187
                raise VMBuilderException('set_valid_options only accepts lists or None')
 
188
            if valid_options:
 
189
                for option in valid_options:
 
190
                    self.check_value(option)
 
191
            self.valid_options = valid_options
 
192
 
 
193
        def get_default(self):
 
194
            """
 
195
            Return the default value.
 
196
            """
 
197
            return self.default
 
198
 
 
199
        def set_default(self, value):
 
200
            """
 
201
            Set a new default value.
 
202
            """
 
203
            self.do_check_value(value)
 
204
            self.default = value
 
205
 
 
206
        def set_value(self, value):
 
207
            """
 
208
            Set a new value.
 
209
            """
 
210
            self.do_check_value(value)
 
211
            self.value = value
 
212
            self.value_set = True
 
213
 
 
214
    class ListSetting(Setting):
 
215
        def __init__(self, *args, **kwargs):
 
216
            self.default = []
 
217
            super(Plugin.ListSetting, self).__init__(*args, **kwargs)
 
218
 
 
219
        def check_value(self, value):
 
220
            if not type(value) == list:
 
221
                raise VMBuilderException('%r is type %s, expected list.' % (value, type(value)))
 
222
 
 
223
    class IntSetting(Setting):
 
224
        def check_value(self, value):
 
225
            if not type(value) == int:
 
226
                raise VMBuilderException('%r is type %s, expected int.' % (value, type(value)))
 
227
 
 
228
    class BooleanSetting(Setting):
 
229
        def check_value(self, value):
 
230
            if not type(value) == bool:
 
231
                raise VMBuilderException('%r is type %s, expected bool.' % (value, type(value)))
 
232
 
 
233
    class StringSetting(Setting):
 
234
        def check_value(self, value):
 
235
            if not type(value) == str:
 
236
                raise VMBuilderException('%r is type %s, expected str.' % (value, type(value)))
 
237
 
 
238
    def setting_group(self, name):
 
239
        setting_group = self.SettingGroup(self, self.context, name)
 
240
        self._setting_groups.append(setting_group)
 
241
        return setting_group
 
242
 
 
243
    def has_setting(self, name):
 
244
        return name in self.context._config
 
245
 
 
246
    def get_setting(self, name):
 
247
        if not name in self.context._config:
 
248
            raise VMBuilderException('Unknown config key: %s' % name)
 
249
        return self.context._config[name].get_value()
 
250
 
 
251
    def set_setting(self, name, value):
 
252
        if not name in self.context._config:
 
253
            raise VMBuilderException('Unknown config key: %s' % name)
 
254
        self.context._config[name].set_value(value)
 
255
 
 
256
    def set_setting_default(self, name, value):
 
257
        if not name in self.context._config:
 
258
            raise VMBuilderException('Unknown config key: %s' % name)
 
259
        self.context._config[name].set_default(value)
 
260
 
 
261
    def get_setting_default(self, name):
 
262
        if not name in self.context._config:
 
263
            raise VMBuilderException('Unknown config key: %s' % name)
 
264
        return self.context._config[name].get_default()
 
265
 
 
266
    def get_setting_valid_options(self, name):
 
267
        if not name in self.context._config:
 
268
            raise VMBuilderException('Unknown config key: %s' % name)
 
269
        return self.context._config[name].get_valid_options()
 
270
 
 
271
    def set_setting_valid_options(self, name, valid_options):
 
272
        if not name in self.context._config:
 
273
            raise VMBuilderException('Unknown config key: %s' % name)
 
274
        self.context._config[name].set_valid_options(valid_options)
 
275