Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / management / commands / server-inspect.py @ c346aed0

History | View | Annotate | Download (5.6 kB)

1 00051a6a Christos Stavrakakis
# Copyright 2012 GRNET S.A. All rights reserved.
2 00051a6a Christos Stavrakakis
#
3 00051a6a Christos Stavrakakis
# Redistribution and use in source and binary forms, with or
4 00051a6a Christos Stavrakakis
# without modification, are permitted provided that the following
5 00051a6a Christos Stavrakakis
# conditions are met:
6 00051a6a Christos Stavrakakis
#
7 00051a6a Christos Stavrakakis
#   1. Redistributions of source code must retain the above
8 00051a6a Christos Stavrakakis
#      copyright notice, this list of conditions and the following
9 00051a6a Christos Stavrakakis
#      disclaimer.
10 00051a6a Christos Stavrakakis
#
11 00051a6a Christos Stavrakakis
#   2. Redistributions in binary form must reproduce the above
12 00051a6a Christos Stavrakakis
#      copyright notice, this list of conditions and the following
13 00051a6a Christos Stavrakakis
#      disclaimer in the documentation and/or other materials
14 00051a6a Christos Stavrakakis
#      provided with the distribution.
15 00051a6a Christos Stavrakakis
#
16 00051a6a Christos Stavrakakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 00051a6a Christos Stavrakakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 00051a6a Christos Stavrakakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 00051a6a Christos Stavrakakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 00051a6a Christos Stavrakakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 00051a6a Christos Stavrakakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 00051a6a Christos Stavrakakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 00051a6a Christos Stavrakakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 00051a6a Christos Stavrakakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 00051a6a Christos Stavrakakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 00051a6a Christos Stavrakakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 00051a6a Christos Stavrakakis
# POSSIBILITY OF SUCH DAMAGE.
28 00051a6a Christos Stavrakakis
#
29 00051a6a Christos Stavrakakis
# The views and conclusions contained in the software and
30 00051a6a Christos Stavrakakis
# documentation are those of the authors and should not be
31 00051a6a Christos Stavrakakis
# interpreted as representing official policies, either expressed
32 00051a6a Christos Stavrakakis
# or implied, of GRNET S.A.
33 00051a6a Christos Stavrakakis
34 00051a6a Christos Stavrakakis
from datetime import datetime
35 00051a6a Christos Stavrakakis
from optparse import make_option
36 00051a6a Christos Stavrakakis
from django.core.management.base import BaseCommand, CommandError
37 00051a6a Christos Stavrakakis
38 00051a6a Christos Stavrakakis
from synnefo.lib.utils import merge_time
39 3524241a Christos Stavrakakis
from synnefo.logic.rapi import GanetiApiError
40 b84ed662 Christos Stavrakakis
from synnefo.management import common
41 00051a6a Christos Stavrakakis
42 00051a6a Christos Stavrakakis
43 00051a6a Christos Stavrakakis
# Fields to print from a gnt-instance info
44 00051a6a Christos Stavrakakis
GANETI_INSTANCE_FIELDS = ('name', 'oper_state', 'admin_state', 'status',
45 00051a6a Christos Stavrakakis
                          'pnode', 'snode', 'network_port', 'disk_template',
46 00051a6a Christos Stavrakakis
                          'disk_usage', 'oper_ram', 'oper_vcpus', 'mtime',
47 00051a6a Christos Stavrakakis
                          'nic.ips', 'nic.macs', 'nic.networks', 'nic.modes')
48 00051a6a Christos Stavrakakis
49 00051a6a Christos Stavrakakis
# Fields to print from a gnt-job info
50 00051a6a Christos Stavrakakis
GANETI_JOB_FIELDS = ('id', 'status', 'summary', 'opresult', 'opstatus',
51 00051a6a Christos Stavrakakis
                     'oplog', 'start_ts', 'end_ts')
52 00051a6a Christos Stavrakakis
53 00051a6a Christos Stavrakakis
54 00051a6a Christos Stavrakakis
class Command(BaseCommand):
55 00051a6a Christos Stavrakakis
    help = "Inspect a server on DB and Ganeti"
56 b84ed662 Christos Stavrakakis
    args = "<server ID>"
57 00051a6a Christos Stavrakakis
58 00051a6a Christos Stavrakakis
    option_list = BaseCommand.option_list + (
59 00051a6a Christos Stavrakakis
        make_option('--jobs', action='store_true',
60 4a37a0be Christos Stavrakakis
                    dest='jobs', default=False,
61 00051a6a Christos Stavrakakis
                    help="Show non-archived jobs concerning server."
62 00051a6a Christos Stavrakakis
            ),
63 00051a6a Christos Stavrakakis
    )
64 00051a6a Christos Stavrakakis
65 00051a6a Christos Stavrakakis
    def handle(self, *args, **options):
66 00051a6a Christos Stavrakakis
        if len(args) != 1:
67 00051a6a Christos Stavrakakis
            raise CommandError("Please provide a server ID")
68 00051a6a Christos Stavrakakis
69 b84ed662 Christos Stavrakakis
        vm = common.get_vm(args[0])
70 00051a6a Christos Stavrakakis
71 00051a6a Christos Stavrakakis
        try:
72 b84ed662 Christos Stavrakakis
            image = common.get_image(vm.imageid, vm.userid)['name']
73 00051a6a Christos Stavrakakis
        except:
74 00051a6a Christos Stavrakakis
            image = vm.imageid
75 00051a6a Christos Stavrakakis
76 00051a6a Christos Stavrakakis
        sep = '-' * 80 + '\n'
77 00051a6a Christos Stavrakakis
        labels = ('name', 'owner', 'flavor', 'image', 'state', 'backend',
78 f66d8b04 Christos Stavrakakis
                  'deleted', 'action', 'backendjobid', 'backendopcode',
79 00051a6a Christos Stavrakakis
                  'backendjobstatus', 'backend_time')
80 f66d8b04 Christos Stavrakakis
        fields = (vm.name, vm.userid, vm.flavor.name, image,
81 b84ed662 Christos Stavrakakis
                  common.format_vm_state(vm), str(vm.backend),
82 b84ed662 Christos Stavrakakis
                  str(vm.deleted), str(vm.action), str(vm.backendjobid),
83 b84ed662 Christos Stavrakakis
                  str(vm.backendopcode), str(vm.backendjobstatus),
84 b84ed662 Christos Stavrakakis
                  str(vm.backendtime))
85 00051a6a Christos Stavrakakis
86 00051a6a Christos Stavrakakis
        self.stdout.write(sep)
87 00051a6a Christos Stavrakakis
        self.stdout.write('State of Server in DB\n')
88 00051a6a Christos Stavrakakis
        self.stdout.write(sep)
89 00051a6a Christos Stavrakakis
        for l, f in zip(labels, fields):
90 00051a6a Christos Stavrakakis
            self.stdout.write(l.ljust(18) + ': ' + f.ljust(20) + '\n')
91 00051a6a Christos Stavrakakis
        self.stdout.write('\n')
92 00051a6a Christos Stavrakakis
        for nic in vm.nics.all():
93 00051a6a Christos Stavrakakis
            self.stdout.write("nic/%d: IPv4: %s, MAC: %s, IPv6:%s,  Network: %s\n"\
94 00051a6a Christos Stavrakakis
                              % (nic.index, nic.ipv4, nic.mac, nic.ipv6,  nic.network))
95 00051a6a Christos Stavrakakis
96 3524241a Christos Stavrakakis
        client = vm.get_client()
97 00051a6a Christos Stavrakakis
        try:
98 00051a6a Christos Stavrakakis
            g_vm = client.GetInstance(vm.backend_vm_id)
99 b49e7db8 Christos Stavrakakis
            self.stdout.write('\n')
100 b49e7db8 Christos Stavrakakis
            self.stdout.write(sep)
101 b49e7db8 Christos Stavrakakis
            self.stdout.write('State of Server in Ganeti\n')
102 b49e7db8 Christos Stavrakakis
            self.stdout.write(sep)
103 b49e7db8 Christos Stavrakakis
            for i in GANETI_INSTANCE_FIELDS:
104 b49e7db8 Christos Stavrakakis
                try:
105 b49e7db8 Christos Stavrakakis
                    value = g_vm[i]
106 b49e7db8 Christos Stavrakakis
                    if i.find('time') != -1:
107 b49e7db8 Christos Stavrakakis
                        value = datetime.fromtimestamp(value)
108 b49e7db8 Christos Stavrakakis
                    self.stdout.write(i.ljust(14) + ': ' + str(value) + '\n')
109 b49e7db8 Christos Stavrakakis
                except KeyError:
110 b49e7db8 Christos Stavrakakis
                    pass
111 00051a6a Christos Stavrakakis
        except GanetiApiError as e:
112 00051a6a Christos Stavrakakis
            if e.code == 404:
113 00051a6a Christos Stavrakakis
                self.stdout.write('Server does not exist in backend %s\n' %
114 00051a6a Christos Stavrakakis
                                  vm.backend.clustername)
115 00051a6a Christos Stavrakakis
            else:
116 00051a6a Christos Stavrakakis
                raise e
117 00051a6a Christos Stavrakakis
118 00051a6a Christos Stavrakakis
        if not options['jobs']:
119 00051a6a Christos Stavrakakis
            return
120 00051a6a Christos Stavrakakis
121 00051a6a Christos Stavrakakis
        self.stdout.write('\n')
122 00051a6a Christos Stavrakakis
        self.stdout.write(sep)
123 dab038a2 Christos Stavrakakis
        self.stdout.write('Non-archived jobs concerning Server in Ganeti\n')
124 00051a6a Christos Stavrakakis
        self.stdout.write(sep)
125 00051a6a Christos Stavrakakis
        jobs = client.GetJobs()
126 00051a6a Christos Stavrakakis
        for j in jobs:
127 00051a6a Christos Stavrakakis
            info = client.GetJobStatus(j)
128 00051a6a Christos Stavrakakis
            summary = ' '.join(info['summary'])
129 00051a6a Christos Stavrakakis
            if summary.startswith("INSTANCE") and \
130 00051a6a Christos Stavrakakis
               summary.find(vm.backend_vm_id) != -1:
131 00051a6a Christos Stavrakakis
                for i in GANETI_JOB_FIELDS:
132 00051a6a Christos Stavrakakis
                    value = info[i]
133 00051a6a Christos Stavrakakis
                    if i.find('_ts') != -1:
134 00051a6a Christos Stavrakakis
                        value = merge_time(value)
135 00051a6a Christos Stavrakakis
                    try:
136 00051a6a Christos Stavrakakis
                        self.stdout.write(i.ljust(14) + ': ' + str(value) +\
137 00051a6a Christos Stavrakakis
                                          '\n')
138 00051a6a Christos Stavrakakis
                    except KeyError:
139 00051a6a Christos Stavrakakis
                        pass
140 00051a6a Christos Stavrakakis
                self.stdout.write('\n' + sep)
141 3524241a Christos Stavrakakis
        # Return the RAPI client to pool
142 3524241a Christos Stavrakakis
        vm.put_client(client)