Statistics
| Branch: | Tag: | Revision:

root / tools / snf-admin @ 13d2b7f7

History | View | Annotate | Download (13 kB)

1 8cdde414 Giorgos Verigakis
#!/usr/bin/env python
2 8cdde414 Giorgos Verigakis
3 8cdde414 Giorgos Verigakis
# Copyright 2011 GRNET S.A. All rights reserved.
4 8cdde414 Giorgos Verigakis
# 
5 8cdde414 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
6 8cdde414 Giorgos Verigakis
# without modification, are permitted provided that the following
7 8cdde414 Giorgos Verigakis
# conditions are met:
8 8cdde414 Giorgos Verigakis
# 
9 8cdde414 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
10 8cdde414 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
11 8cdde414 Giorgos Verigakis
#      disclaimer.
12 8cdde414 Giorgos Verigakis
# 
13 8cdde414 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
14 8cdde414 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
15 8cdde414 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
16 8cdde414 Giorgos Verigakis
#      provided with the distribution.
17 8cdde414 Giorgos Verigakis
# 
18 8cdde414 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 8cdde414 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 8cdde414 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 8cdde414 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 8cdde414 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 8cdde414 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 8cdde414 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 8cdde414 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 8cdde414 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 8cdde414 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 8cdde414 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 8cdde414 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
30 8cdde414 Giorgos Verigakis
# 
31 8cdde414 Giorgos Verigakis
# The views and conclusions contained in the software and
32 8cdde414 Giorgos Verigakis
# documentation are those of the authors and should not be
33 8cdde414 Giorgos Verigakis
# interpreted as representing official policies, either expressed
34 8cdde414 Giorgos Verigakis
# or implied, of GRNET S.A.
35 8cdde414 Giorgos Verigakis
36 8cdde414 Giorgos Verigakis
from django.core.management import setup_environ
37 8cdde414 Giorgos Verigakis
try:
38 8cdde414 Giorgos Verigakis
    from synnefo import settings
39 8cdde414 Giorgos Verigakis
except ImportError:
40 8cdde414 Giorgos Verigakis
    raise Exception("Cannot import settings, make sure PYTHONPATH contains "
41 8cdde414 Giorgos Verigakis
                    "the parent directory of the Synnefo Django project.")
42 8cdde414 Giorgos Verigakis
setup_environ(settings)
43 8cdde414 Giorgos Verigakis
44 8cdde414 Giorgos Verigakis
import inspect
45 8cdde414 Giorgos Verigakis
import logging
46 8cdde414 Giorgos Verigakis
import sys
47 8cdde414 Giorgos Verigakis
48 8cdde414 Giorgos Verigakis
from collections import defaultdict
49 8cdde414 Giorgos Verigakis
from optparse import OptionParser
50 8cdde414 Giorgos Verigakis
from os.path import basename
51 8cdde414 Giorgos Verigakis
52 8cdde414 Giorgos Verigakis
from synnefo.db import models
53 8cdde414 Giorgos Verigakis
54 8cdde414 Giorgos Verigakis
55 8cdde414 Giorgos Verigakis
def get_user(uid):
56 8cdde414 Giorgos Verigakis
    try:
57 8cdde414 Giorgos Verigakis
        uid = int(uid)
58 8cdde414 Giorgos Verigakis
        return models.SynnefoUser.objects.get(id=uid)
59 8cdde414 Giorgos Verigakis
    except ValueError:
60 8cdde414 Giorgos Verigakis
        return None
61 8cdde414 Giorgos Verigakis
    except models.SynnefoUser.DoesNotExist:
62 8cdde414 Giorgos Verigakis
        return None
63 8cdde414 Giorgos Verigakis
64 8cdde414 Giorgos Verigakis
def print_dict(d, exclude=()):
65 ca8f8081 Giorgos Verigakis
    if not d:
66 ca8f8081 Giorgos Verigakis
        return
67 8cdde414 Giorgos Verigakis
    margin = max(len(key) for key in d) + 1
68 8cdde414 Giorgos Verigakis
69 8cdde414 Giorgos Verigakis
    for key, val in sorted(d.items()):
70 9a60dacb Giorgos Verigakis
        if key in exclude or key.startswith('_'):
71 8cdde414 Giorgos Verigakis
            continue
72 8cdde414 Giorgos Verigakis
        print '%s: %s' % (key.rjust(margin), val)
73 8cdde414 Giorgos Verigakis
74 13d2b7f7 Giorgos Verigakis
def print_item(item):
75 13d2b7f7 Giorgos Verigakis
    print '%d %s' % (item.id, item.name)
76 13d2b7f7 Giorgos Verigakis
    print_dict(item.__dict__, exclude=('id', 'name'))
77 13d2b7f7 Giorgos Verigakis
78 8cdde414 Giorgos Verigakis
def print_items(items, detail=False):
79 8cdde414 Giorgos Verigakis
    for item in items:
80 8cdde414 Giorgos Verigakis
        print '%d %s' % (item.id, item.name)
81 8cdde414 Giorgos Verigakis
        if detail:
82 9a60dacb Giorgos Verigakis
            print_dict(item.__dict__, exclude=('id', 'name'))
83 8cdde414 Giorgos Verigakis
            print
84 8cdde414 Giorgos Verigakis
85 8cdde414 Giorgos Verigakis
86 8cdde414 Giorgos Verigakis
class Command(object):
87 9a60dacb Giorgos Verigakis
    group = '<group>'
88 9a60dacb Giorgos Verigakis
    name = '<command>'
89 8cdde414 Giorgos Verigakis
    syntax = ''
90 8cdde414 Giorgos Verigakis
    description = ''
91 8cdde414 Giorgos Verigakis
    
92 9a60dacb Giorgos Verigakis
    def __init__(self, exe, argv):
93 8cdde414 Giorgos Verigakis
        parser = OptionParser()
94 9a60dacb Giorgos Verigakis
        syntax = '%s [options]' % self.syntax if self.syntax else '[options]'
95 9a60dacb Giorgos Verigakis
        parser.usage = '%s %s %s' % (exe, self.name, syntax)
96 9a60dacb Giorgos Verigakis
        parser.description = self.description
97 8cdde414 Giorgos Verigakis
        self.add_options(parser)
98 8cdde414 Giorgos Verigakis
        options, self.args = parser.parse_args(argv)
99 8cdde414 Giorgos Verigakis
        
100 8cdde414 Giorgos Verigakis
        # Add options to self
101 8cdde414 Giorgos Verigakis
        for opt in parser.option_list:
102 8cdde414 Giorgos Verigakis
            key = opt.dest
103 8cdde414 Giorgos Verigakis
            if key:
104 8cdde414 Giorgos Verigakis
                val = getattr(options, key)
105 8cdde414 Giorgos Verigakis
                setattr(self, key, val)
106 8cdde414 Giorgos Verigakis
        
107 8cdde414 Giorgos Verigakis
        ch = logging.StreamHandler()
108 8cdde414 Giorgos Verigakis
        ch.setFormatter(logging.Formatter('%(message)s'))
109 8cdde414 Giorgos Verigakis
        logger = logging.getLogger()
110 8cdde414 Giorgos Verigakis
        logger.addHandler(ch)
111 8cdde414 Giorgos Verigakis
        level = logging.WARNING
112 8cdde414 Giorgos Verigakis
        logger.setLevel(level)
113 8cdde414 Giorgos Verigakis
        
114 8cdde414 Giorgos Verigakis
        self.parser = parser
115 8cdde414 Giorgos Verigakis
    
116 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
117 8cdde414 Giorgos Verigakis
        pass
118 8cdde414 Giorgos Verigakis
    
119 8cdde414 Giorgos Verigakis
    def execute(self):
120 8cdde414 Giorgos Verigakis
        try:
121 8cdde414 Giorgos Verigakis
            self.main(*self.args)
122 8cdde414 Giorgos Verigakis
        except TypeError:
123 8cdde414 Giorgos Verigakis
            self.parser.print_help()
124 8cdde414 Giorgos Verigakis
125 8cdde414 Giorgos Verigakis
126 13d2b7f7 Giorgos Verigakis
# Server commands
127 13d2b7f7 Giorgos Verigakis
128 8cdde414 Giorgos Verigakis
class ListServers(Command):
129 9a60dacb Giorgos Verigakis
    group = 'server'
130 ca8f8081 Giorgos Verigakis
    name = 'list'
131 8cdde414 Giorgos Verigakis
    syntax = '[server id]'
132 8cdde414 Giorgos Verigakis
    description = 'list servers'
133 8cdde414 Giorgos Verigakis
    
134 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
135 8cdde414 Giorgos Verigakis
        parser.add_option('-a', action='store_true', dest='show_deleted',
136 8cdde414 Giorgos Verigakis
                        default=False, help='also list deleted servers')
137 8cdde414 Giorgos Verigakis
        parser.add_option('-l', action='store_true', dest='detail',
138 8cdde414 Giorgos Verigakis
                        default=False, help='show detailed output')
139 8cdde414 Giorgos Verigakis
        parser.add_option('-u', dest='uid', metavar='UID',
140 8cdde414 Giorgos Verigakis
                            help='show servers of user with id UID')
141 8cdde414 Giorgos Verigakis
    
142 8cdde414 Giorgos Verigakis
    def main(self, server_id=None):
143 8cdde414 Giorgos Verigakis
        servers = models.VirtualMachine.objects.order_by('id')
144 8cdde414 Giorgos Verigakis
        if server_id:
145 8cdde414 Giorgos Verigakis
            servers = servers.filter(id=server_id)
146 8cdde414 Giorgos Verigakis
        if not self.show_deleted:
147 8cdde414 Giorgos Verigakis
            servers = servers.filter(deleted=False)
148 8cdde414 Giorgos Verigakis
        if self.uid:
149 8cdde414 Giorgos Verigakis
            user = get_user(self.uid)
150 8cdde414 Giorgos Verigakis
            if user:
151 8cdde414 Giorgos Verigakis
                servers = servers.filter(owner=user)
152 8cdde414 Giorgos Verigakis
            else:
153 8cdde414 Giorgos Verigakis
                print 'Unknown user id'
154 8cdde414 Giorgos Verigakis
                return
155 8cdde414 Giorgos Verigakis
        
156 8cdde414 Giorgos Verigakis
        print_items(servers, self.detail)
157 8cdde414 Giorgos Verigakis
158 8cdde414 Giorgos Verigakis
159 13d2b7f7 Giorgos Verigakis
# User commands
160 13d2b7f7 Giorgos Verigakis
161 8cdde414 Giorgos Verigakis
class ListUsers(Command):
162 9a60dacb Giorgos Verigakis
    group = 'user'
163 ca8f8081 Giorgos Verigakis
    name = 'list'
164 8cdde414 Giorgos Verigakis
    syntax = '[user id]'
165 8cdde414 Giorgos Verigakis
    description = 'list users'
166 8cdde414 Giorgos Verigakis
    
167 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
168 8cdde414 Giorgos Verigakis
        parser.add_option('-l', action='store_true', dest='detail',
169 8cdde414 Giorgos Verigakis
                        default=False, help='show detailed output')
170 8cdde414 Giorgos Verigakis
    
171 8cdde414 Giorgos Verigakis
    def main(self, user_id=None):
172 8cdde414 Giorgos Verigakis
        if user_id:
173 8cdde414 Giorgos Verigakis
            users = [models.SynnefoUser.objects.get(id=user_id)]
174 8cdde414 Giorgos Verigakis
        else:
175 8cdde414 Giorgos Verigakis
            users = models.SynnefoUser.objects.order_by('id')
176 8cdde414 Giorgos Verigakis
        print_items(users, self.detail)
177 8cdde414 Giorgos Verigakis
178 8cdde414 Giorgos Verigakis
179 13d2b7f7 Giorgos Verigakis
class ModifyUser(Command):
180 13d2b7f7 Giorgos Verigakis
    group = 'user'
181 13d2b7f7 Giorgos Verigakis
    name = 'modify'
182 13d2b7f7 Giorgos Verigakis
    syntax = '<user id>'
183 13d2b7f7 Giorgos Verigakis
    description = 'modify a user'
184 13d2b7f7 Giorgos Verigakis
    
185 13d2b7f7 Giorgos Verigakis
    def add_options(self, parser):
186 13d2b7f7 Giorgos Verigakis
        parser.add_option('--credit', dest='credit', metavar='VALUE',
187 13d2b7f7 Giorgos Verigakis
                            help='set user credits')
188 13d2b7f7 Giorgos Verigakis
        parser.add_option('--invitations', dest='invitations',
189 13d2b7f7 Giorgos Verigakis
                            metavar='VALUE', help='set max invitations')
190 13d2b7f7 Giorgos Verigakis
        parser.add_option('--realname', dest='realname', metavar='NAME',
191 13d2b7f7 Giorgos Verigakis
                            help='set real name of user')
192 13d2b7f7 Giorgos Verigakis
        parser.add_option('--type', dest='type', metavar='TYPE',
193 13d2b7f7 Giorgos Verigakis
                            help='set user type')
194 13d2b7f7 Giorgos Verigakis
        parser.add_option('--username', dest='username', metavar='NAME',
195 13d2b7f7 Giorgos Verigakis
                            help='set username')
196 13d2b7f7 Giorgos Verigakis
    
197 13d2b7f7 Giorgos Verigakis
    def main(self, user_id):
198 13d2b7f7 Giorgos Verigakis
        user = get_user(user_id)
199 13d2b7f7 Giorgos Verigakis
        
200 13d2b7f7 Giorgos Verigakis
        if self.credit:
201 13d2b7f7 Giorgos Verigakis
            user.credit = self.credit
202 13d2b7f7 Giorgos Verigakis
        if self.invitations:
203 13d2b7f7 Giorgos Verigakis
            user.max_invitations = self.invitations
204 13d2b7f7 Giorgos Verigakis
        if self.realname:
205 13d2b7f7 Giorgos Verigakis
            user.realname = self.realname
206 13d2b7f7 Giorgos Verigakis
        if self.type:
207 13d2b7f7 Giorgos Verigakis
            allowed = [x[0] for x in models.SynnefoUser.ACCOUNT_TYPE]
208 13d2b7f7 Giorgos Verigakis
            if self.type not in allowed:
209 13d2b7f7 Giorgos Verigakis
                print 'Invalid type'
210 13d2b7f7 Giorgos Verigakis
                return
211 13d2b7f7 Giorgos Verigakis
            user.type = self.type
212 13d2b7f7 Giorgos Verigakis
        if self.username:
213 13d2b7f7 Giorgos Verigakis
            user.name = self.username
214 13d2b7f7 Giorgos Verigakis
        
215 13d2b7f7 Giorgos Verigakis
        user.save()
216 13d2b7f7 Giorgos Verigakis
        print_item(user)
217 13d2b7f7 Giorgos Verigakis
218 13d2b7f7 Giorgos Verigakis
219 13d2b7f7 Giorgos Verigakis
# Image commands
220 13d2b7f7 Giorgos Verigakis
221 8cdde414 Giorgos Verigakis
class ListImages(Command):
222 9a60dacb Giorgos Verigakis
    group = 'image'
223 ca8f8081 Giorgos Verigakis
    name = 'list'
224 8cdde414 Giorgos Verigakis
    syntax = '[image id]'
225 8cdde414 Giorgos Verigakis
    description = 'list images'
226 8cdde414 Giorgos Verigakis
    
227 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
228 8cdde414 Giorgos Verigakis
        parser.add_option('-l', action='store_true', dest='detail',
229 8cdde414 Giorgos Verigakis
                        default=False, help='show detailed output')
230 8cdde414 Giorgos Verigakis
    
231 8cdde414 Giorgos Verigakis
    def main(self, image_id=None):
232 8cdde414 Giorgos Verigakis
        if image_id:
233 8cdde414 Giorgos Verigakis
            images = [models.Image.objects.get(id=image_id)]
234 8cdde414 Giorgos Verigakis
        else:
235 8cdde414 Giorgos Verigakis
            images = models.Image.objects.order_by('id')
236 8cdde414 Giorgos Verigakis
        print_items(images, self.detail)
237 8cdde414 Giorgos Verigakis
238 8cdde414 Giorgos Verigakis
239 8cdde414 Giorgos Verigakis
class RegisterImage(Command):
240 9a60dacb Giorgos Verigakis
    group = 'image'
241 8cdde414 Giorgos Verigakis
    name = 'register'
242 8cdde414 Giorgos Verigakis
    syntax = '<name> <backend id>'
243 8cdde414 Giorgos Verigakis
    description = 'register an image'
244 8cdde414 Giorgos Verigakis
    
245 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
246 ca8f8081 Giorgos Verigakis
        parser.add_option('--public', action='store_true', dest='public',
247 8cdde414 Giorgos Verigakis
                            default=False, help='make image public')
248 8cdde414 Giorgos Verigakis
        parser.add_option('-u', dest='uid', metavar='UID',
249 8cdde414 Giorgos Verigakis
                            help='assign image to user with id UID')
250 8cdde414 Giorgos Verigakis
    
251 8cdde414 Giorgos Verigakis
    def main(self, name, backend_id):
252 8cdde414 Giorgos Verigakis
        user = None
253 8cdde414 Giorgos Verigakis
        if self.uid:
254 8cdde414 Giorgos Verigakis
            user = get_user(self.uid)
255 8cdde414 Giorgos Verigakis
            if not user:
256 8cdde414 Giorgos Verigakis
                print 'Unknown user id'
257 8cdde414 Giorgos Verigakis
                return
258 8cdde414 Giorgos Verigakis
        
259 8cdde414 Giorgos Verigakis
        image = models.Image.objects.create(
260 8cdde414 Giorgos Verigakis
            name=name,
261 8cdde414 Giorgos Verigakis
            state='ACTIVE',
262 8cdde414 Giorgos Verigakis
            owner=user,
263 8cdde414 Giorgos Verigakis
            backend_id=backend_id,
264 8cdde414 Giorgos Verigakis
            public=self.public)
265 9a60dacb Giorgos Verigakis
        
266 13d2b7f7 Giorgos Verigakis
        print_item(image)
267 8cdde414 Giorgos Verigakis
268 8cdde414 Giorgos Verigakis
269 8cdde414 Giorgos Verigakis
class ModifyImage(Command):
270 9a60dacb Giorgos Verigakis
    group = 'image'
271 8cdde414 Giorgos Verigakis
    name = 'modify'
272 8cdde414 Giorgos Verigakis
    syntax = '<image id>'
273 8cdde414 Giorgos Verigakis
    description = 'modify an image'
274 8cdde414 Giorgos Verigakis
    
275 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
276 8cdde414 Giorgos Verigakis
        parser.add_option('-b', dest='backend_id', metavar='BACKEND_ID',
277 8cdde414 Giorgos Verigakis
                            help='set image backend id')
278 8cdde414 Giorgos Verigakis
        parser.add_option('-f', dest='format', metavar='FORMAT',
279 8cdde414 Giorgos Verigakis
                            help='set image format')
280 8cdde414 Giorgos Verigakis
        parser.add_option('-n', dest='name', metavar='NAME',
281 8cdde414 Giorgos Verigakis
                            help='set image name')
282 ca8f8081 Giorgos Verigakis
        parser.add_option('--public', action='store_true', dest='public',
283 8cdde414 Giorgos Verigakis
                            default=False, help='make image public')
284 ca8f8081 Giorgos Verigakis
        parser.add_option('--nopublic', action='store_true', dest='private',
285 8cdde414 Giorgos Verigakis
                            default=False, help='make image private')
286 8cdde414 Giorgos Verigakis
        parser.add_option('-s', dest='state', metavar='STATE',
287 8cdde414 Giorgos Verigakis
                            default=False, help='set image state')
288 8cdde414 Giorgos Verigakis
        parser.add_option('-u', dest='uid', metavar='UID',
289 8cdde414 Giorgos Verigakis
                            help='assign image to user with id UID')
290 8cdde414 Giorgos Verigakis
    
291 8cdde414 Giorgos Verigakis
    def main(self, image_id):
292 8cdde414 Giorgos Verigakis
        try:
293 8cdde414 Giorgos Verigakis
            image = models.Image.objects.get(id=image_id)
294 8cdde414 Giorgos Verigakis
        except:
295 8cdde414 Giorgos Verigakis
            print 'Image not found'
296 8cdde414 Giorgos Verigakis
            return
297 8cdde414 Giorgos Verigakis
        
298 8cdde414 Giorgos Verigakis
        if self.backend_id:
299 8cdde414 Giorgos Verigakis
            image.backend_id = self.backend_id
300 8cdde414 Giorgos Verigakis
        if self.format:
301 13d2b7f7 Giorgos Verigakis
            allowed = [x[0] for x in models.Image.FORMATS]
302 13d2b7f7 Giorgos Verigakis
            if self.format not in allowed:
303 13d2b7f7 Giorgos Verigakis
                print 'Invalid format'
304 13d2b7f7 Giorgos Verigakis
                return
305 13d2b7f7 Giorgos Verigakis
            image.format = self.format
306 8cdde414 Giorgos Verigakis
        if self.name:
307 8cdde414 Giorgos Verigakis
            image.name = self.name
308 8cdde414 Giorgos Verigakis
        if self.public:
309 8cdde414 Giorgos Verigakis
            image.public = True
310 8cdde414 Giorgos Verigakis
        if self.private:
311 8cdde414 Giorgos Verigakis
            image.public = False
312 8cdde414 Giorgos Verigakis
        if self.state:
313 13d2b7f7 Giorgos Verigakis
            allowed = [x[0] for x in models.Image.IMAGE_STATES]
314 13d2b7f7 Giorgos Verigakis
            if self.state not in allowed:
315 13d2b7f7 Giorgos Verigakis
                print 'Invalid state'
316 13d2b7f7 Giorgos Verigakis
                return
317 8cdde414 Giorgos Verigakis
            image.state = self.state
318 8cdde414 Giorgos Verigakis
        if self.uid:
319 8cdde414 Giorgos Verigakis
            image.owner = get_user(self.uid)
320 8cdde414 Giorgos Verigakis
        
321 8cdde414 Giorgos Verigakis
        image.save()
322 13d2b7f7 Giorgos Verigakis
        print_item(image)
323 8cdde414 Giorgos Verigakis
324 8cdde414 Giorgos Verigakis
325 ca8f8081 Giorgos Verigakis
class ModifyImageMeta(Command):
326 9a60dacb Giorgos Verigakis
    group = 'image'
327 ca8f8081 Giorgos Verigakis
    name = 'meta'
328 ca8f8081 Giorgos Verigakis
    syntax = '<image id> [key[=val]]'
329 ca8f8081 Giorgos Verigakis
    description = 'get and manipulate image metadata'
330 ca8f8081 Giorgos Verigakis
    
331 ca8f8081 Giorgos Verigakis
    def main(self, image_id, arg=''):
332 ca8f8081 Giorgos Verigakis
        try:
333 ca8f8081 Giorgos Verigakis
            image = models.Image.objects.get(id=image_id)
334 ca8f8081 Giorgos Verigakis
        except:
335 ca8f8081 Giorgos Verigakis
            print 'Image not found'
336 ca8f8081 Giorgos Verigakis
            return
337 ca8f8081 Giorgos Verigakis
        
338 ca8f8081 Giorgos Verigakis
        key, sep, val = arg.partition('=')
339 ca8f8081 Giorgos Verigakis
        if not sep:
340 ca8f8081 Giorgos Verigakis
            val = None
341 ca8f8081 Giorgos Verigakis
        
342 ca8f8081 Giorgos Verigakis
        if not key:
343 ca8f8081 Giorgos Verigakis
            metadata = {}
344 ca8f8081 Giorgos Verigakis
            for meta in image.imagemetadata_set.order_by('meta_key'):
345 ca8f8081 Giorgos Verigakis
                metadata[meta.meta_key] = meta.meta_value
346 ca8f8081 Giorgos Verigakis
            print_dict(metadata)
347 ca8f8081 Giorgos Verigakis
            return
348 ca8f8081 Giorgos Verigakis
        
349 ca8f8081 Giorgos Verigakis
        try:
350 ca8f8081 Giorgos Verigakis
            meta = image.imagemetadata_set.get(meta_key=key)
351 ca8f8081 Giorgos Verigakis
        except models.ImageMetadata.DoesNotExist:
352 ca8f8081 Giorgos Verigakis
            meta = None
353 ca8f8081 Giorgos Verigakis
        
354 ca8f8081 Giorgos Verigakis
        if val is None:
355 ca8f8081 Giorgos Verigakis
            if meta:
356 ca8f8081 Giorgos Verigakis
                print_dict({key: meta.meta_value})
357 ca8f8081 Giorgos Verigakis
            return
358 ca8f8081 Giorgos Verigakis
        
359 ca8f8081 Giorgos Verigakis
        if val:
360 ca8f8081 Giorgos Verigakis
            if not meta:
361 ca8f8081 Giorgos Verigakis
                meta = image.imagemetadata_set.create(meta_key=key)
362 ca8f8081 Giorgos Verigakis
            meta.meta_value = val
363 ca8f8081 Giorgos Verigakis
            meta.save()
364 ca8f8081 Giorgos Verigakis
        else:
365 ca8f8081 Giorgos Verigakis
            # Delete if val is empty
366 ca8f8081 Giorgos Verigakis
            if meta:
367 ca8f8081 Giorgos Verigakis
                meta.delete()
368 ca8f8081 Giorgos Verigakis
369 ca8f8081 Giorgos Verigakis
370 9a60dacb Giorgos Verigakis
def print_usage(exe, groups, group=None, shortcut=False):
371 9a60dacb Giorgos Verigakis
    nop = Command(exe, [])
372 9a60dacb Giorgos Verigakis
    nop.parser.print_help()
373 9a60dacb Giorgos Verigakis
    if group:
374 9a60dacb Giorgos Verigakis
        groups = {group: groups[group]}
375 8cdde414 Giorgos Verigakis
376 8cdde414 Giorgos Verigakis
    print
377 8cdde414 Giorgos Verigakis
    print 'Commands:'
378 9a60dacb Giorgos Verigakis
    
379 9a60dacb Giorgos Verigakis
    for group, commands in sorted(groups.items()):
380 9a60dacb Giorgos Verigakis
        for command, cls in sorted(commands.items()):
381 9a60dacb Giorgos Verigakis
            name = '  %s %s' % (group, command)
382 9a60dacb Giorgos Verigakis
            print '%s %s' % (name.ljust(22), cls.description)
383 9a60dacb Giorgos Verigakis
        print
384 8cdde414 Giorgos Verigakis
385 8cdde414 Giorgos Verigakis
386 8cdde414 Giorgos Verigakis
def main():
387 9a60dacb Giorgos Verigakis
    groups = defaultdict(dict)
388 8cdde414 Giorgos Verigakis
    module = sys.modules[__name__]
389 8cdde414 Giorgos Verigakis
    for name, cls in inspect.getmembers(module, inspect.isclass):
390 9a60dacb Giorgos Verigakis
        if not issubclass(cls, Command) or cls == Command:
391 9a60dacb Giorgos Verigakis
            continue
392 9a60dacb Giorgos Verigakis
        groups[cls.group][cls.name] = cls
393 8cdde414 Giorgos Verigakis
    
394 8cdde414 Giorgos Verigakis
    argv = list(sys.argv)
395 8cdde414 Giorgos Verigakis
    exe = basename(argv.pop(0))
396 9a60dacb Giorgos Verigakis
    prefix, sep, suffix = exe.partition('-')
397 9a60dacb Giorgos Verigakis
    if sep and prefix == 'snf' and suffix in groups:
398 9a60dacb Giorgos Verigakis
        # Allow shortcut aliases like snf-image, snf-server, etc
399 9a60dacb Giorgos Verigakis
        group = suffix
400 8cdde414 Giorgos Verigakis
    else:
401 9a60dacb Giorgos Verigakis
        group = argv.pop(0) if argv else None
402 9a60dacb Giorgos Verigakis
        if group in groups:
403 9a60dacb Giorgos Verigakis
            exe = '%s %s' % (exe, group)
404 9a60dacb Giorgos Verigakis
        else:
405 9a60dacb Giorgos Verigakis
            exe = '%s <group>' % exe
406 9a60dacb Giorgos Verigakis
            group = None
407 8cdde414 Giorgos Verigakis
    
408 8cdde414 Giorgos Verigakis
    command = argv.pop(0) if argv else None
409 8cdde414 Giorgos Verigakis
    
410 9a60dacb Giorgos Verigakis
    if group not in groups or command not in groups[group]:
411 9a60dacb Giorgos Verigakis
        print_usage(exe, groups, group)
412 8cdde414 Giorgos Verigakis
        sys.exit(1)
413 8cdde414 Giorgos Verigakis
    
414 9a60dacb Giorgos Verigakis
    cls = groups[group][command]
415 9a60dacb Giorgos Verigakis
    cmd = cls(exe, argv)
416 8cdde414 Giorgos Verigakis
    cmd.execute()
417 8cdde414 Giorgos Verigakis
418 8cdde414 Giorgos Verigakis
419 8cdde414 Giorgos Verigakis
if __name__ == '__main__':
420 8cdde414 Giorgos Verigakis
    main()