little changes
[nepi.git] / src / neco / resources / linux / node.py
1 from neco.execution.attribute import Attribute, Flags
2 from neco.execution.resource import ResourceManager, clsinit, ResourceState
3 from neco.resources.linux.ssh_api import SSHApiFactory
4
5 import logging
6
7 @clsinit
8 class LinuxNode(ResourceManager):
9     _rtype = "LinuxNode"
10
11     @classmethod
12     def _register_attributes(cls):
13         hostname = Attribute("hostname", "Hostname of the machine")
14         username = Attribute("username", "Local account username", 
15                 flags = Flags.Credential)
16         identity = Attribute("identity", "SSH identity file",
17                 flags = Flags.Credential)
18         clean_home = Attribute("cleanHome", "Remove all files and directories 
19                 from home folder before starting experiment", 
20                 flags = Flags.ReadOnly)
21         clean_processes = Attribute("cleanProcesses", 
22                 "Kill all running processes before starting experiment", 
23                 flags = Flags.ReadOnly)
24         tear_down = Attribute("tearDown", "Bash script to be executed before
25                 releasing the resource", flags = Flags.ReadOnly)
26
27         cls._register_attribute(hostname)
28         cls._register_attribute(username)
29         cls._register_attribute(identity)
30         cls._register_attribute(clean_home)
31         cls._register_attribute(clean_processes)
32         cls._register_attribute(tear_down)
33
34     def __init__(self, ec, guid):
35         super(LinuxNode, self).__init__(ec, guid)
36
37         self._logger = logging.getLogger("neco.linux.Node.%d" % guid)
38
39     def provision(self, filters = None):
40         if not self.api.is_alive():
41             self._state = ResourceState.FAILED
42             self.logger.error("Deploy failed. Unresponsive node")
43             return
44         
45         if self.get("cleanProcesses"):
46             self._clean_processes()
47
48         if self.get("cleanHome"):
49             # self._clean_home() -> this is dangerous
50             pass
51
52     def deploy(self):
53         self.provision()
54         super(LinuxNode, self).deploy()
55
56     def release(self):
57         tear_down = self.get("tearDown")
58         if tear_down:
59             self.api.execute(tear_down)
60
61         super(LinuxNode, self).release()
62
63     def _validate_connection(self, guid):
64         # TODO: Validate!
65         return True
66
67     @property
68     def api(self):
69         host = self.get("host")
70         user = self.get("user")
71         identity = self.get("identity")
72         return SSHApiFactory.get_api(host, user, identity)
73
74     def _clean_processes(self):
75         hostname = self.get("hostname")
76         self.logger.info("Cleaning up processes on %s", hostname)
77         
78         cmds = [
79             "sudo -S killall python tcpdump || /bin/true ; "
80             "sudo -S killall python tcpdump || /bin/true ; "
81             "sudo -S kill $(ps -N -T -o pid --no-heading | grep -v $PPID | sort) || /bin/true ",
82             "sudo -S killall -u root || /bin/true ",
83             "sudo -S killall -u root || /bin/true ",
84         ]
85
86         api = self.api
87         for cmd in cmds:
88             out, err = api.execute(cmd)
89             if err:
90                 self.logger.error(err)
91             
92     def _clean_home(self):
93         hostname = self.get("hostname")
94         self.logger.info("Cleaning up home on %s", hostname)
95
96          cmds = [
97             "find . -maxdepth 1 ! -name '.bash*' ! -name '.' -execdir rm -rf {} + "
98         ]
99
100         api = self.api
101         for cmd in cmds:
102             out, err = api.execute(cmd)
103             if err:
104                 self.logger.error(err)
105