Merge branch 'master' of ssh://git.onelab.eu/git/plcapi
[plcapi.git] / PLC / Methods / RebootNodeWithPCU.py
1 # $Id$
2 # $URL$
3 import socket
4
5 from PLC.Faults import *
6 from PLC.Method import Method
7 from PLC.Parameter import Parameter, Mixed
8 from PLC.Auth import Auth
9
10 from PLC.Nodes import Node, Nodes
11 from PLC.PCUs import PCU, PCUs
12
13 try:
14     from pcucontrol import reboot
15     external_dependency = True
16 except:
17     external_dependency = False
18
19 class RebootNodeWithPCU(Method):
20     """
21         Uses the associated PCU to attempt to reboot the given Node.
22
23     Admins can reboot any node. Techs and PIs can only reboot nodes at
24     their site.
25
26     Returns 1 if the reboot proceeded without error (Note: this does not guarantee
27         that the reboot is successful).
28         Returns -1 if external dependencies for this call are not available.
29         Returns "error string" if the reboot failed with a specific message.
30     """
31
32     roles = ['admin', 'pi', 'tech']
33
34     accepts = [
35         Auth(),
36         Mixed(Node.fields['node_id'],
37               Node.fields['hostname']),
38         Parameter(bool, "Run as a test, or as a real reboot", nullok = True)
39         ]
40
41     returns = Parameter(int, '1 if successful')
42
43     def call(self, auth, node_id_or_hostname, testrun=None):
44     # Get account information
45         nodes = Nodes(self.api, [node_id_or_hostname])
46         if not nodes:
47             raise PLCInvalidArgument, "No such node"
48
49         if testrun is None:
50             testrun = False
51
52         node = nodes[0]
53
54         # Authenticated function
55         assert self.caller is not None
56
57         # If we are not an admin, make sure that the caller is a
58         # member of the site at which the node is located.
59         if 'admin' not in self.caller['roles']:
60             if node['site_id'] not in self.caller['site_ids']:
61                 raise PLCPermissionDenied, "Not allowed to reboot nodes from specified site"
62
63         # Verify that the node has pcus associated with it.
64         pcus = PCUs(self.api, {'pcu_id' : node['pcu_ids']} )
65         if not pcus:
66             raise PLCInvalidArgument, "No PCUs associated with Node"
67
68         pcu = pcus[0]
69
70         if not external_dependency:
71             raise PLCNotImplemented, "Could not load external module to attempt reboot"
72
73         # model, hostname, port,
74         # i = pcu['node_ids'].index(node['node_id'])
75         # p = pcu['ports'][i]
76         ret = reboot.reboot_api(node, pcu, testrun)
77
78         node.update_last_pcu_reboot(commit=True) # commits new timestamp to node 
79
80         self.event_objects = {'Node': [node['node_id']]}
81         self.message = "RebootNodeWithPCU %s with %s returned %s" % (node['node_id'], pcu['pcu_id'], ret)
82
83         return ret