Merge "Compile DPDK to use basic cpu features" into stable/colorado
[fuel.git] / deploy / common.py
1 ###############################################################################
2 # Copyright (c) 2015 Ericsson AB and others.
3 # szilard.cserey@ericsson.com
4 # peter.barabas@ericsson.com
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ###############################################################################
10
11
12 import subprocess
13 import sys
14 import os
15 import logging
16 import argparse
17 import shutil
18 import stat
19 import errno
20 import time
21 import shlex
22
23 N = {'id': 0, 'status': 1, 'name': 2, 'cluster': 3, 'ip': 4, 'mac': 5,
24      'roles': 6, 'pending_roles': 7, 'online': 8, 'group_id': 9}
25 E = {'id': 0, 'status': 1, 'name': 2, 'release_id': 3, 'pending_release_id': 4}
26 R = {'id': 0, 'name': 1, 'state': 2, 'operating_system': 3, 'version': 4}
27 RO = {'name': 0, 'conflicts': 1}
28 CWD = os.getcwd()
29 LOG = logging.getLogger(__name__)
30 LOG.setLevel(logging.DEBUG)
31 formatter = logging.Formatter('%(message)s')
32 out_handler = logging.StreamHandler(sys.stdout)
33 out_handler.setFormatter(formatter)
34 LOG.addHandler(out_handler)
35 LOGFILE = 'autodeploy.log'
36 if os.path.isfile(LOGFILE):
37     os.remove(LOGFILE)
38 out_handler = logging.FileHandler(LOGFILE, mode='w')
39 out_handler.setFormatter(formatter)
40 LOG.addHandler(out_handler)
41 os.chmod(LOGFILE, 0664)
42
43
44 def mask_arguments(cmd, mask_args, mask_str):
45     cmd_line = shlex.split(cmd)
46     for pos in mask_args:
47         # Don't mask the actual command; also check if we don't reference
48         # beyond bounds
49         if pos == 0 or pos >= len(cmd_line):
50             continue
51         cmd_line[pos] = mask_str
52     return ' '.join(cmd_line)
53
54
55 def exec_cmd(cmd, check=True, attempts=1, delay=5, verbose=False, mask_args=[], mask_str='*****'):
56     masked_cmd = mask_arguments(cmd, mask_args, mask_str)
57
58     # a negative value means forever
59     while attempts != 0:
60         attempts = attempts - 1
61         process = subprocess.Popen(cmd,
62                                    stdout=subprocess.PIPE,
63                                    stderr=subprocess.PIPE,
64                                    shell=True)
65         (response, stderr) = process.communicate()
66         return_code = process.returncode
67         if return_code == 0 or attempts == 0:
68             break
69         time.sleep(delay)
70         if verbose:
71             log('%d attempts left: %s' % (attempts, masked_cmd))
72
73     response = response.strip()
74     if check:
75         if return_code > 0:
76             stderr = stderr.strip()
77             print "Failed command: " + str(masked_cmd)
78             print "Command returned response: " + str(stderr)
79             print "Command return code: " + str(return_code)
80             raise Exception(stderr)
81         else:
82             print "Command: " + str(masked_cmd)
83             print str(response)
84             return response
85     return response, return_code
86
87
88 def run_proc(cmd):
89     process = subprocess.Popen(cmd,
90                                stdout=subprocess.PIPE,
91                                stderr=subprocess.STDOUT,
92                                shell=True)
93     return process
94
95
96 def run_proc_wait_terminated(process):
97     response = process.communicate()[0].strip()
98     return_code = process.returncode
99     return response, return_code
100
101
102 def run_proc_kill(process):
103     response = process.kill()
104     return response
105
106
107 def parse(printout):
108     parsed_list = []
109     lines = printout.splitlines()
110     for l in lines[2:]:
111         parsed = [e.strip() for e in l.split('|')]
112         parsed_list.append(parsed)
113     return parsed_list
114
115
116 def clean(lines):
117     parsed_list = []
118     parsed = []
119     for l in lines.strip().splitlines():
120         parsed = []
121         cluttered = [e.strip() for e in l.split(' ')]
122         for p in cluttered:
123             if p:
124                 parsed.append(p)
125         parsed_list.append(parsed)
126     return parsed if len(parsed_list) == 1 else parsed_list
127
128
129 def err(message, fun = None, *args):
130     LOG.error('%s\n' % message)
131     if fun:
132         fun(*args)
133     sys.exit(1)
134
135
136 def warn(message):
137     LOG.warning('%s\n' % message)
138
139
140 def check_file_exists(file_path):
141     if not os.path.dirname(file_path):
142         file_path = '%s/%s' % (CWD, file_path)
143     if not os.path.isfile(file_path):
144         err('ERROR: File %s not found\n' % file_path)
145
146
147 def check_dir_exists(dir_path):
148     if not os.path.dirname(dir_path):
149         dir_path = '%s/%s' % (CWD, dir_path)
150     if not os.path.isdir(dir_path):
151         err('ERROR: Directory %s not found\n' % dir_path)
152
153
154 def create_dir_if_not_exists(dir_path):
155     if not os.path.isdir(dir_path):
156         log('Creating directory %s' % dir_path)
157         os.makedirs(dir_path)
158
159
160 def delete(f):
161     if os.path.isfile(f):
162         log('Deleting file %s' % f)
163         os.remove(f)
164     elif os.path.isdir(f):
165         log('Deleting directory %s' % f)
166         shutil.rmtree(f)
167
168
169 def commafy(comma_separated_list):
170     l = [c.strip() for c in comma_separated_list.split(',')]
171     return ','.join(l)
172
173
174 def check_if_root():
175     uid = os.getuid()
176     if uid != 0:
177         err('You need be root to run this application')
178
179
180 def log(message):
181     LOG.debug('%s\n' % message)
182
183
184 class ArgParser(argparse.ArgumentParser):
185
186     def error(self, message):
187         sys.stderr.write('ERROR: %s\n' % message)
188         self.print_help()
189         sys.exit(2)
190
191
192 def backup(path):
193     src = path
194     dst = path + '_orig'
195     delete(dst)
196     try:
197         shutil.copytree(src, dst)
198     except OSError as e:
199         if e.errno == errno.ENOTDIR:
200             shutil.copy(src, dst)
201         else:
202             raise