cc1  v2.1
CC1 source code docs
 All Classes Namespaces Files Functions Variables Pages
actions.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 # @COPYRIGHT_begin
3 #
4 # Copyright [2010-2014] Institute of Nuclear Physics PAN, Krakow, Poland
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 # @COPYRIGHT_end
19 
20 import os
21 import subprocess
22 import random
23 import string
24 import pwd
25 import grp
26 
27 VERSION = 3
28 
29 """
30 @defgroup CTX VM Exceptions
31 @{
32 """
33 
34 
35 ##
36 #
37 # Method to raise Exception for missing parameter.
38 # @param_post{param} missing parameter
39 #
40 def missing_parameter(param):
41  raise Exception("The request must contain the parameter %s" % param)
42 
43 
44 ##
45 #
46 # Method to raise Exception for execution error.
47 # @param_post{error} execution's error
48 #
49 def execution_error(error):
50  raise Exception("There was problem during function execution: %s" % error)
51 
52 
53 ##
54 #
55 # Method to raise Exception for build in command's failure.
56 # @param_post{cmd}
57 # @param_post{code}
58 #
59 def build_in_command_failed(cmd, code):
60  raise Exception("Build in command %s failed with exit code: %s" % (cmd, code))
61 
62 
63 ##
64 #
65 # @param_post{hosts_list}
66 # @param_post{user} (optional, default: @val{root})
67 #
68 def update_hosts(hosts_list=None, user='root'):
69  if user is None:
70  missing_parameter('user')
71  if hosts_list is None:
72  missing_parameter('host_list')
73  try:
74  f = open("/etc/hosts", "r")
75  lines = f.readlines()
76  f.close()
77  except IOError, e:
78  execution_error(e.strerror)
79  lines[:] = [line for line in lines if not line.find("farm") != -1]
80 
81  known_hosts = open(os.path.expanduser('~%s/.ssh/known_hosts' % user), "a")
82 
83  for host in hosts_list:
84  lines.append("%s\t%s\n" % (host["ip"], host["host_name"]))
85 
86  try:
87  f = open("/etc/hosts", 'w')
88  f.writelines(lines)
89  f.close()
90  except IOError, e:
91  execution_error(e.strerror)
92  return (True, 'ok')
93 
94  for host in hosts_list:
95  r = subprocess.call(['ssh-keyscan', host["ip"]], stdout=known_hosts)
96  if r != 0:
97  build_in_command_failed("ssh-keyscan", r)
98  r = subprocess.call(['ssh-keyscan', host["host_name"]], stdout=known_hosts)
99  if r != 0:
100  build_in_command_failed("ssh-keyscan", r)
101 
102 
103 ##
104 #
105 # @param_post{hostname}
106 #
107 def set_hostname(hostname=None):
108  if hostname == None:
109  missing_parameter('hostname')
110  r = subprocess.call(['hostname', hostname])
111  if r != 0:
112  build_in_command_failed('hostname', r)
113 
114 
115 ##
116 #
117 # @param_post{cmd}
118 #
119 def cmd_exists(cmd):
120  return subprocess.call(["which", cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0
121 
122 
123 ##
124 #
125 # Tries to shutdown VM. If fails, raises exception.
126 #
127 def shutdown():
128  r = 'not working cmd'
129  if cmd_exists('poweroff'):
130  r = subprocess.call('sleep 5 && poweroff &', shell=True)
131  elif cmd_exists('shutdown'):
132  r = subprocess.call('sleep 5 && shutdown -h now', shell=True)
133  if r != 0:
134  build_in_command_failed('shutdown', r)
135 
136 
137 ##
138 #
139 # Tries to restart VM. If fails, raises exception.
140 #
141 def reboot():
142  r = 'not working cmd'
143  if cmd_exists('reboot'):
144  r = subprocess.call(['reboot'])
145  elif cmd_exists('shutdown'):
146  r = subprocess.call(['shutdown', '-r', 'now'])
147  if r != 0:
148  build_in_command_failed('shutdown', r)
149 
150 
151 ##
152 #
153 # Tries to reset password of ther user
154 # @param_post{user}
155 #
156 def reset_password(user=None):
157  if user == None:
159  chars = string.ascii_letters + string.digits
160 
161  random.seed = (os.urandom(1024))
162  password = ''.join(random.choice(chars) for unused in range(12))
163  p = subprocess.Popen(('openssl', 'passwd', '-1', password), stdout=subprocess.PIPE)
164  shadow_password = p.communicate()[0].strip()
165 
166  if p.returncode != 0:
167  build_in_command_failed('openssl', p.returncode)
168 
169  # r = subprocess.call(['usermod', '-p', shadow_password, user])
170  # kompatybilniejsza metoda:
171  p = subprocess.Popen(['chpasswd', '-e'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
172  r = p.communicate('%s:%s\n' % (user, shadow_password))
173  if r[1]:
174  build_in_command_failed('chpasswd', r[1])
175  if p.returncode != 0:
176  build_in_command_failed('chpasswd', p.returncode)
177  return password
178 
179 
180 ##
181 #
182 # @param_post{user}
183 # @param_post{ssh_key}
184 #
185 def add_ssh_key(user=None, ssh_key=None):
186  if user is None:
187  missing_parameter('user')
188  if ssh_key is None:
189  missing_parameter('ssh_key')
190 
191  try:
192  uid = pwd.getpwnam(user).pw_uid
193  gid = grp.getgrnam(user).gr_gid
194  keys_path = os.path.expanduser('~%s/.ssh/authorized_keys' % user)
195  if not os.path.exists(keys_path):
196  d = os.path.dirname(os.path.expanduser('~%s/.ssh/' % user))
197  if not os.path.exists(d):
198  os.makedirs(d)
199  os.chown(d, uid, gid)
200  fp = file(keys_path, 'w')
201  fp.close()
202 
203  fp = file(keys_path, 'a')
204  fp.write('\n%s\n' % ssh_key)
205  fp.close()
206  os.chown(keys_path, uid, gid)
207 
208  ssh_conf = open("/etc/ssh/ssh_config", 'r')
209  lines = ssh_conf.readlines()
210  ssh_conf.close()
211 
212  lines[:] = [line for line in lines if line.find("StrictHostKeyChecking") == -1]
213  lines.append("StrictHostKeyChecking no")
214  ssh_conf = open("/etc/ssh/ssh_config", 'w')
215  ssh_conf.writelines(lines)
216  ssh_conf.close()
217  except IOError, e:
218  execution_error(e.strerror)
219 
220 
221 ##
222 #
223 # Creates pair of ssh keys on the machine (public - private)
224 # and then returns public.
225 # @param_post{key_name} @optional{"id_rsa"}
226 #
227 def generate_key(key_name="id_rsa"):
228  user = 'root'
229 
230  key_name = os.path.expanduser('~%s/.ssh/' % user) + key_name
231  if not os.path.exists(key_name):
232  subprocess.call(["ssh-keygen", "-q", "-N", "", "-f", key_name])
233 
234  try:
235  f = open("%s.pub" % key_name, "r")
236  key = f.read().strip()
237  f.close()
238  except IOError, e:
239  execution_error(e.strerror)
240  return key
241