Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (6.7 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 04a1b675 Christos Stavrakakis
from snf_django.lib.astakos import UserCache
40 3524241a Christos Stavrakakis
from synnefo.logic.rapi import GanetiApiError
41 4500650c Stratos Psomadakis
from synnefo.management.common import Omit
42 b84ed662 Christos Stavrakakis
from synnefo.management import common
43 18c4414d Giorgos Korfiatis
from synnefo.settings import (CYCLADES_SERVICE_TOKEN as ASTAKOS_TOKEN,
44 e3ff6830 Georgios D. Tsoukalas
                              ASTAKOS_BASE_URL)
45 00051a6a Christos Stavrakakis
46 00051a6a Christos Stavrakakis
47 00051a6a Christos Stavrakakis
# Fields to print from a gnt-instance info
48 00051a6a Christos Stavrakakis
GANETI_INSTANCE_FIELDS = ('name', 'oper_state', 'admin_state', 'status',
49 00051a6a Christos Stavrakakis
                          'pnode', 'snode', 'network_port', 'disk_template',
50 00051a6a Christos Stavrakakis
                          'disk_usage', 'oper_ram', 'oper_vcpus', 'mtime',
51 00051a6a Christos Stavrakakis
                          'nic.ips', 'nic.macs', 'nic.networks', 'nic.modes')
52 00051a6a Christos Stavrakakis
53 00051a6a Christos Stavrakakis
# Fields to print from a gnt-job info
54 00051a6a Christos Stavrakakis
GANETI_JOB_FIELDS = ('id', 'status', 'summary', 'opresult', 'opstatus',
55 00051a6a Christos Stavrakakis
                     'oplog', 'start_ts', 'end_ts')
56 00051a6a Christos Stavrakakis
57 00051a6a Christos Stavrakakis
58 00051a6a Christos Stavrakakis
class Command(BaseCommand):
59 00051a6a Christos Stavrakakis
    help = "Inspect a server on DB and Ganeti"
60 b84ed662 Christos Stavrakakis
    args = "<server ID>"
61 00051a6a Christos Stavrakakis
62 00051a6a Christos Stavrakakis
    option_list = BaseCommand.option_list + (
63 9621c777 Christos Stavrakakis
        make_option(
64 9621c777 Christos Stavrakakis
            '--jobs',
65 c51f3a08 Stratos Psomadakis
            action='store_true',
66 c51f3a08 Stratos Psomadakis
            dest='jobs',
67 c51f3a08 Stratos Psomadakis
            default=False,
68 c51f3a08 Stratos Psomadakis
            help="Show non-archived jobs concerning server."),
69 9621c777 Christos Stavrakakis
        make_option(
70 e6c4bd78 Christos Stavrakakis
            '--displayname',
71 c51f3a08 Stratos Psomadakis
            action='store_true',
72 4500650c Stratos Psomadakis
            dest='displayname',
73 c51f3a08 Stratos Psomadakis
            default=False,
74 4500650c Stratos Psomadakis
            help="Display both uuid and display name"),
75 00051a6a Christos Stavrakakis
    )
76 00051a6a Christos Stavrakakis
77 00051a6a Christos Stavrakakis
    def handle(self, *args, **options):
78 00051a6a Christos Stavrakakis
        if len(args) != 1:
79 00051a6a Christos Stavrakakis
            raise CommandError("Please provide a server ID")
80 00051a6a Christos Stavrakakis
81 b84ed662 Christos Stavrakakis
        vm = common.get_vm(args[0])
82 00051a6a Christos Stavrakakis
83 4500650c Stratos Psomadakis
        displayname = options['displayname']
84 4500650c Stratos Psomadakis
85 e3ff6830 Georgios D. Tsoukalas
        ucache = UserCache(ASTAKOS_BASE_URL, ASTAKOS_TOKEN)
86 4500650c Stratos Psomadakis
87 00051a6a Christos Stavrakakis
        try:
88 b84ed662 Christos Stavrakakis
            image = common.get_image(vm.imageid, vm.userid)['name']
89 00051a6a Christos Stavrakakis
        except:
90 00051a6a Christos Stavrakakis
            image = vm.imageid
91 00051a6a Christos Stavrakakis
92 00051a6a Christos Stavrakakis
        sep = '-' * 80 + '\n'
93 4500650c Stratos Psomadakis
        labels = filter(lambda x: x is not Omit,
94 4500650c Stratos Psomadakis
                        ['name', 'owner_uuid',
95 4500650c Stratos Psomadakis
                         'owner_name' if displayname else Omit,
96 4500650c Stratos Psomadakis
                         'flavor', 'image', 'state', 'backend', 'deleted',
97 1fb0fdda Christos Stavrakakis
                         'action', 'task', 'task_job', 'backendjobid',
98 1fb0fdda Christos Stavrakakis
                         'backendopcode', 'backendjobstatus', 'backend_time'])
99 4500650c Stratos Psomadakis
100 4500650c Stratos Psomadakis
        uuid = vm.userid
101 4500650c Stratos Psomadakis
        if displayname:
102 8283d6c1 Stratos Psomadakis
            dname = ucache.get_name(uuid)
103 4500650c Stratos Psomadakis
104 4500650c Stratos Psomadakis
        fields = filter(lambda x: x is not Omit,
105 4500650c Stratos Psomadakis
                        [vm.name, uuid, dname if displayname else Omit,
106 4500650c Stratos Psomadakis
                         vm.flavor.name, image, common.format_vm_state(vm),
107 4500650c Stratos Psomadakis
                         str(vm.backend), str(vm.deleted), str(vm.action),
108 1fb0fdda Christos Stavrakakis
                         str(vm.task), str(vm.task_job_id),
109 4500650c Stratos Psomadakis
                         str(vm.backendjobid), str(vm.backendopcode),
110 4500650c Stratos Psomadakis
                         str(vm.backendjobstatus), str(vm.backendtime)])
111 00051a6a Christos Stavrakakis
112 00051a6a Christos Stavrakakis
        self.stdout.write(sep)
113 00051a6a Christos Stavrakakis
        self.stdout.write('State of Server in DB\n')
114 00051a6a Christos Stavrakakis
        self.stdout.write(sep)
115 00051a6a Christos Stavrakakis
        for l, f in zip(labels, fields):
116 00051a6a Christos Stavrakakis
            self.stdout.write(l.ljust(18) + ': ' + f.ljust(20) + '\n')
117 00051a6a Christos Stavrakakis
        self.stdout.write('\n')
118 00051a6a Christos Stavrakakis
        for nic in vm.nics.all():
119 7856a37a Stratos Psomadakis
            params = (nic.index, nic.ipv4, nic.mac, nic.ipv6,  nic.network)
120 7856a37a Stratos Psomadakis
            self.stdout.write("nic/%d: IPv4: %s, MAC: %s, IPv6:%s,"
121 7856a37a Stratos Psomadakis
                              " Network: %s\n" % params)
122 00051a6a Christos Stavrakakis
123 3524241a Christos Stavrakakis
        client = vm.get_client()
124 00051a6a Christos Stavrakakis
        try:
125 00051a6a Christos Stavrakakis
            g_vm = client.GetInstance(vm.backend_vm_id)
126 b49e7db8 Christos Stavrakakis
            self.stdout.write('\n')
127 b49e7db8 Christos Stavrakakis
            self.stdout.write(sep)
128 b49e7db8 Christos Stavrakakis
            self.stdout.write('State of Server in Ganeti\n')
129 b49e7db8 Christos Stavrakakis
            self.stdout.write(sep)
130 b49e7db8 Christos Stavrakakis
            for i in GANETI_INSTANCE_FIELDS:
131 b49e7db8 Christos Stavrakakis
                try:
132 b49e7db8 Christos Stavrakakis
                    value = g_vm[i]
133 b49e7db8 Christos Stavrakakis
                    if i.find('time') != -1:
134 b49e7db8 Christos Stavrakakis
                        value = datetime.fromtimestamp(value)
135 b49e7db8 Christos Stavrakakis
                    self.stdout.write(i.ljust(14) + ': ' + str(value) + '\n')
136 b49e7db8 Christos Stavrakakis
                except KeyError:
137 b49e7db8 Christos Stavrakakis
                    pass
138 00051a6a Christos Stavrakakis
        except GanetiApiError as e:
139 00051a6a Christos Stavrakakis
            if e.code == 404:
140 00051a6a Christos Stavrakakis
                self.stdout.write('Server does not exist in backend %s\n' %
141 00051a6a Christos Stavrakakis
                                  vm.backend.clustername)
142 00051a6a Christos Stavrakakis
            else:
143 00051a6a Christos Stavrakakis
                raise e
144 00051a6a Christos Stavrakakis
145 00051a6a Christos Stavrakakis
        if not options['jobs']:
146 00051a6a Christos Stavrakakis
            return
147 00051a6a Christos Stavrakakis
148 00051a6a Christos Stavrakakis
        self.stdout.write('\n')
149 00051a6a Christos Stavrakakis
        self.stdout.write(sep)
150 dab038a2 Christos Stavrakakis
        self.stdout.write('Non-archived jobs concerning Server in Ganeti\n')
151 00051a6a Christos Stavrakakis
        self.stdout.write(sep)
152 00051a6a Christos Stavrakakis
        jobs = client.GetJobs()
153 00051a6a Christos Stavrakakis
        for j in jobs:
154 00051a6a Christos Stavrakakis
            info = client.GetJobStatus(j)
155 00051a6a Christos Stavrakakis
            summary = ' '.join(info['summary'])
156 9621c777 Christos Stavrakakis
            job_is_relevant = summary.startswith("INSTANCE") and\
157 9621c777 Christos Stavrakakis
                (summary.find(vm.backend_vm_id) != -1)
158 9621c777 Christos Stavrakakis
            if job_is_relevant:
159 00051a6a Christos Stavrakakis
                for i in GANETI_JOB_FIELDS:
160 00051a6a Christos Stavrakakis
                    value = info[i]
161 00051a6a Christos Stavrakakis
                    if i.find('_ts') != -1:
162 00051a6a Christos Stavrakakis
                        value = merge_time(value)
163 00051a6a Christos Stavrakakis
                    try:
164 9621c777 Christos Stavrakakis
                        self.stdout.write(i.ljust(14) + ': ' + str(value) +
165 00051a6a Christos Stavrakakis
                                          '\n')
166 00051a6a Christos Stavrakakis
                    except KeyError:
167 00051a6a Christos Stavrakakis
                        pass
168 00051a6a Christos Stavrakakis
                self.stdout.write('\n' + sep)
169 3524241a Christos Stavrakakis
        # Return the RAPI client to pool
170 3524241a Christos Stavrakakis
        vm.put_client(client)