143 lines
4.9 KiB
Python
143 lines
4.9 KiB
Python
#!/usr/bin/env python2
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright 2015 Mirantis, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
"""
|
|
tools module
|
|
"""
|
|
|
|
import os
|
|
import logging
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def get_dir_structure(rootdir):
|
|
"""
|
|
Creates a nested dictionary that represents the folder structure of rootdir
|
|
"""
|
|
dir = {}
|
|
try:
|
|
rootdir = rootdir.rstrip(os.sep)
|
|
start = rootdir.rfind(os.sep) + 1
|
|
for path, dirs, files in os.walk(rootdir):
|
|
folders = path[start:].split(os.sep)
|
|
subdir = dict.fromkeys(files)
|
|
parent = reduce(dict.get, folders[:-1], dir)
|
|
parent[folders[-1]] = subdir
|
|
except:
|
|
logging.error('failed to create list of the directory: %s' % rootdir)
|
|
sys.exit(1)
|
|
return dir
|
|
|
|
|
|
def mdir(directory):
|
|
if not os.path.exists(directory):
|
|
logging.debug('creating directory %s' % directory)
|
|
try:
|
|
os.makedirs(directory)
|
|
except:
|
|
logging.error("Can't create a directory: %s" % directory)
|
|
sys.exit(3)
|
|
|
|
|
|
def launch_cmd(command, timeout):
|
|
logging.info('launch_cmd: command %s' % command)
|
|
p = subprocess.Popen(command,
|
|
shell=True,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE)
|
|
try:
|
|
outs, errs = p.communicate(timeout=timeout+1)
|
|
except subprocess.TimeoutExpired:
|
|
p.kill()
|
|
outs, errs = p.communicate()
|
|
logging.error("command: %s err: %s, returned: %s" %
|
|
(command, errs, p.returncode))
|
|
logging.debug("ssh return: err:%s\nouts:%s\ncode:%s" %
|
|
(errs, outs, p.returncode))
|
|
logging.info("ssh return: err:%s\ncode:%s" %
|
|
(errs, p.returncode))
|
|
return outs, errs, p.returncode
|
|
|
|
|
|
def ssh_node(ip, command, sshopts='', sshvars='', timeout=15, filename=None,
|
|
inputfile=None, outputfile=None, prefix='nice -n 19 ionice -c 3'):
|
|
if (ip in ['localhost', '127.0.0.1']) or ip.startswith('127.'):
|
|
logging.info("skip ssh")
|
|
bstr = "%s timeout '%s' bash -c " % (
|
|
sshvars, timeout)
|
|
else:
|
|
logging.info("exec ssh")
|
|
# base cmd str
|
|
bstr = "timeout '%s' ssh -t -T %s '%s' '%s' " % (
|
|
timeout, sshopts, ip, sshvars)
|
|
if filename is None:
|
|
cmd = bstr + '"' + prefix + ' ' + command + '"'
|
|
else:
|
|
cmd = bstr + " '%s bash -s' < '%s'" % (prefix, filename)
|
|
if inputfile is not None:
|
|
cmd = bstr + '"' + prefix + " " + command + '" < ' + inputfile
|
|
logging.info("ssh_node: inputfile selected, cmd: %s" %cmd)
|
|
if outputfile is not None:
|
|
cmd += ' > "' + outputfile + '"'
|
|
outs, errs, code = launch_cmd(cmd, timeout)
|
|
return outs, errs, code
|
|
|
|
|
|
def get_files_rsync(ip, data, sshopts, dpath, timeout=15):
|
|
if (ip in ['localhost', '127.0.0.1']) or ip.startswith('127.'):
|
|
logging.info("skip ssh rsync")
|
|
cmd = ("timeout '%s' rsync -avzr --files-from=- / '%s'"
|
|
" --progress --partial --delete-before" %
|
|
(timeout, dpath))
|
|
else:
|
|
cmd = ("timeout '%s' rsync -avzr -e 'ssh %s"
|
|
" -oCompression=no' --files-from=- '%s':/ '%s'"
|
|
" --progress --partial --delete-before"
|
|
) % (timeout, sshopts, ip, dpath)
|
|
logging.debug("command:%s\ndata:\n%s" % (cmd, data))
|
|
if data == '':
|
|
return cmd, '', 127
|
|
p = subprocess.Popen(cmd,
|
|
shell=True,
|
|
stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE)
|
|
try:
|
|
outs, errs = p.communicate(input=data, timeout=timeout+1)
|
|
except subprocess.TimeoutExpired:
|
|
p.kill()
|
|
outs, errs = p.communicate()
|
|
logging.error("ip: %s, command: %s err: %s, returned: %s" %
|
|
(ip, cmd, errs, p.returncode))
|
|
logging.debug("ip: %s, ssh return: err:%s\nouts:%s\ncode:%s" %
|
|
(ip, errs, outs, p.returncode))
|
|
logging.info("ip: %s, ssh return: err:%s\ncode:%s" %
|
|
(ip, errs, p.returncode))
|
|
return outs, errs, p.returncode
|
|
|
|
|
|
def free_space(destdir, timeout):
|
|
cmd = ("df %s --block-size K 2> /dev/null"
|
|
" | tail -n 1 | awk '{print $2}' | sed 's/K//g'") % (destdir)
|
|
outs, errs, code = launch_cmd(cmd, timeout)
|
|
return outs, errs, code
|
|
|
|
|
|
if __name__ == '__main__':
|
|
exit(0)
|