def wraps_invoke_run(self): # NOTE: most of the interesting tests about this are in # invoke.runners / invoke.integration. cxn = Connection("localhost") result = cxn.local("echo foo", hide=True) assert result.stdout == "foo\n" assert not cxn.is_connected # meh way of proving it didn't use SSH
class sudo: def setup(self): # NOTE: assumes a user configured for passworded (NOT # passwordless)_sudo, whose password is 'mypass', is executing the # test suite. I.e. our travis-ci setup. config = Config( {"sudo": {"password": "******"}, "run": {"hide": True}} ) self.cxn = Connection("localhost", config=config) def sudo_command(self): """ Run command via sudo on host localhost """ skip_outside_travis() assert self.cxn.sudo("whoami").stdout.strip() == "root" def mixed_sudo_and_normal_commands(self): """ Run command via sudo, and not via sudo, on localhost """ skip_outside_travis() logname = os.environ["LOGNAME"] assert self.cxn.run("whoami").stdout.strip() == logname assert self.cxn.sudo("whoami").stdout.strip() == "root"
def mixed_use_of_local_and_run(self): """ Run command truly locally, and over SSH via localhost """ cxn = Connection("localhost") result = cxn.local("echo foo", hide=True) assert result.stdout == "foo\n" assert not cxn.is_connected # meh way of proving it didn't use SSH yet result = cxn.run("echo foo", hide=True) assert cxn.is_connected # NOW it's using SSH assert result.stdout == "foo\n"
def large_remote_commands_finish_cleanly(self): # Guards against e.g. cleanup finishing before actually reading all # data from the remote end. Which is largely an issue in Invoke-level # code but one that only really manifests when doing stuff over the # network. Yay computers! path = "/usr/share/dict/words" cxn = Connection("localhost") with open(path) as fd: words = [x.strip() for x in fd.readlines()] stdout = cxn.run("cat {}".format(path), hide=True).stdout lines = [x.strip() for x in stdout.splitlines()] # When bug present, # lines received is significantly fewer than the # true count in the file (by thousands). assert len(lines) == len(words)
def __init__(self, cluster): self.__connection = Connection( host=cluster.master_ip, user=self.USERNAMES[cluster.os], forward_agent=True, connect_kwargs={"key_filename": cluster.ssh_key}, ) self.__user_at_hostname = "{0}@{1}".format(self.USERNAMES[cluster.os], cluster.master_ip)
def setup(self): # NOTE: assumes a user configured for passworded (NOT # passwordless)_sudo, whose password is 'mypass', is executing the # test suite. I.e. our travis-ci setup. config = Config( {"sudo": {"password": "******"}, "run": {"hide": True}} ) self.cxn = Connection("localhost", config=config)
class get: def setup(self): self.c = Connection('localhost') self.remote = self._support('file.txt') def base_case(self): # Copy file from support to tempdir # TODO: consider path.py for contextmanager cwd = os.getcwd() os.chdir(self.tmpdir) try: result = self.c.get(self.remote) finally: os.chdir(cwd) # Make sure it arrived local = self._tmp('file.txt') ok_(os.path.exists(local)) eq_(open(local).read(), "yup\n") # Sanity check result object eq_(result.remote, self.remote) eq_(result.orig_remote, self.remote) eq_(result.local, local) eq_(result.orig_local, None) def file_like_objects(self): fd = BytesIO() result = self.c.get(remote=self.remote, local=fd) eq_(fd.getvalue(), b"yup\n") eq_(result.remote, self.remote) ok_(result.local is fd) def mode_preservation(self): # Use a dummy file which is given an unusual, highly unlikely to be # default umask, set of permissions (oct 641, aka -rw-r----x) local = self._tmp('funky-local.txt') remote = self._tmp('funky-remote.txt') with open(remote, 'w') as fd: fd.write('whatever') os.chmod(remote, 0o641) self.c.get(remote=remote, local=local) eq_(stat.S_IMODE(os.stat(local).st_mode), 0o641)
def main(args): with open(os.path.expanduser(args.config_file), 'r') as fh: config = yaml.load(fh) # Create an archive dirname = get_dirname(args.repo) logger.info("Using repo {}".format(dirname)) repo = Repo(args.repo) assert not repo.is_dirty() archive_name = dirname git_tag = next((tag for tag in repo.tags if tag.commit == repo.head.commit), None) if git_tag: archive_name += '_' + git_tag else: archive_name += '_' + repo.head.object.hexsha if args.extra_tag: archive_name += '_' + args.extra_tag logger.info("Creating repo archive {}".format(archive_name)) archive = "{0}.tar.gz".format(archive_name) archive_path = ospj(args.repo, archive) run_dir = os.getcwd() os.chdir(args.repo) os.system("git-archive-all {}".format(archive)) os.chdir(run_dir) logger.info("Archive created.") # Transfer archive to remote remote_dir = config['hosts']['irma']['archive_dir'] Connection('irma').put(archive_path, remote=remote_dir) logger.info("Archive successfully transferred to irma") # Extract remote archive c = Connection('irma') remote_archive_path = ospj(remote_dir, archive) remote_extracted_path = remote_archive_path.replace('.tar.gz', '') c.run('rm -r {} || true'.format(remote_extracted_path)) c.run('cd {}; tar -xvzf {}'.format(remote_dir, remote_archive_path)) # Create a link from dev or latest to the new archive if args.mode == 'dev': link_name = "{}_dev".format(dirname) else: link_name = "{}_latest".format(dirname) c.run('cd {}; ln -sfn {} {}'.format(remote_dir, remote_extracted_path, link_name)) logger.info("Linking: {} {}".format(remote_extracted_path, link_name)) logger.info("{} successfully linked as the new {}".format(dirname, link_name))
class get: def setup(self): self.c = Connection("localhost") self.remote = _support("file.txt") def base_case(self, tmpdir): # Copy file from support to tempdir with tmpdir.as_cwd(): result = self.c.get(self.remote) # Make sure it arrived local = tmpdir.join("file.txt") assert local.check() assert local.read() == "yup\n" # Sanity check result object assert result.remote == self.remote assert result.orig_remote == self.remote assert result.local == str(local) assert result.orig_local is None def file_like_objects(self): fd = BytesIO() result = self.c.get(remote=self.remote, local=fd) assert fd.getvalue() == b"yup\n" assert result.remote == self.remote assert result.local is fd def mode_preservation(self, tmpdir): # Use a dummy file which is given an unusual, highly unlikely to be # default umask, set of permissions (oct 641, aka -rw-r----x) local = tmpdir.join("funky-local.txt") remote = tmpdir.join("funky-remote.txt") remote.write("whatever") remote.chmod(0o641) self.c.get(remote=str(remote), local=str(local)) assert stat.S_IMODE(local.stat().mode) == 0o641
class put: def setup(self): self.c = Connection("localhost") self.remote = path.local.mkdtemp().join("file.txt").realpath() def base_case(self): # Copy file from 'local' (support dir) to 'remote' (tempdir) local_dir = _support() with path.local(local_dir).as_cwd(): tmpdir = self.remote.dirpath() # TODO: wrap chdir at the Connection level self.c.sftp().chdir(str(tmpdir)) result = self.c.put("file.txt") # Make sure it arrived assert self.remote.check() assert self.remote.read() == "yup\n" # Sanity check result object assert result.remote == self.remote assert result.orig_remote is None assert result.local == _support("file.txt") assert result.orig_local == "file.txt" def file_like_objects(self): fd = BytesIO() fd.write(b"yup\n") remote_str = str(self.remote) result = self.c.put(local=fd, remote=remote_str) assert self.remote.read() == "yup\n" assert result.remote == remote_str assert result.local is fd def mode_preservation(self, tmpdir): # Use a dummy file which is given an unusual, highly unlikely to be # default umask, set of permissions (oct 641, aka -rw-r----x) local = tmpdir.join("funky-local.txt") local.write("whatever") local.chmod(0o641) remote = tmpdir.join("funky-remote.txt") self.c.put(remote=str(remote), local=str(local)) assert stat.S_IMODE(remote.stat().mode) == 0o641
from fabric import Connection, Config config = Config(overrides={'sudo': {'password': '******'}, 'Password': '******'}) connect = Connection("192.168.1.51", config=config) try: connect.run("git clone https://github.com/MazayKun/DockerProject.git") except BaseException: print("already cloned") connect.sudo("docker-compose -f DockerProject/docker-compose.yml up") connect.close()
def setup_cluster(): cluster_ip_list = iplist seeds = ips.replace("\r\n", "") print("seeds", seeds) for ip in cluster_ip_list: currentip = ip.replace("\r\n", "") c = Connection(host="ubuntu@%s" % currentip, connect_kwargs={"key_filename": key_key}) print("connected to", currentip) c.run('pwd') # sudo("sed -i 's/127.0.0.1/%s/' /etc/dse/cassandra/cassandra.yaml"%(seeds)) c.sudo("service ssh status", user="******", password="******") print("sed") c.sudo("sed -i \'s/127.0.0.1/%s/\' /etc/dse/cassandra/cassandra.yaml" % (seeds), user="******") #privateip=c.run("ip addr | grep \'state UP\' -A2 | tail -n1 | awk \'{print $2}\' | cut -f1 -d\'/\'") #prip=str(privateip.stdout) #print(prip) #c.sudo("sed -i \'s/listen_address: localhost/listen_address: %s/\' /etc/dse/cassandra/cassandra.yaml"%(prip),user="******") c.sudo( "sed -i \'s/rpc_address: localhost/rpc_address: 0.0.0.0/\' /etc/dse/cassandra/cassandra.yaml", user="******") c.sudo( "sed -i \'s/# broadcast_address: 1.2.3.4/broadcast_address: %s/\' /etc/dse/cassandra/cassandra.yaml" % (currentip), user="******") c.sudo("rm -rf /var/run/cassandra/*", user="******") c.sudo("rm -rf /var/lock/subsys/cassandra", user="******") c.sudo("service ssh status", user="******")
def deploy(c): remote_user = "******" remote_password = "******" remote_host = "159.65.6.97" config = Config(overrides={'sudo': {'password': remote_password}}) connect_kwarg = {'password': remote_password, 'allow_agent': False} conn = Connection(host=remote_host, user=remote_user, config=config, connect_kwargs=connect_kwarg) print("Success") conn.put("app.py") conn.put("config.json") conn.put("meal.json") conn.put("orders.json") conn.put("promo.json") conn.put("users.json") conn.put("promotions.json") print("Success!") print("Install requirements:") conn.sudo("pip3 install Flask Flask-CORS") conn.sudo("pip3 install twilio") print("Killdown") conn.sudo("pkill -F server.pid", warn=True) print("Start server") conn.sudo("nohup python3 app.py &> logs.txt & echo $! > server.pid") conn.close()
def setup(self): self.c = Connection("localhost") self.remote = _support("file.txt")
def main(settings: Settings) -> None: common_tags = frozenset(settings.common_tags) blacklist_tags = frozenset(settings.blacklist_tags) whitelist_tags = frozenset(settings.whitelist_tags) # gateway = Connection("pi10-inet") gateway = None register_all() for host in settings.whitelist_hosts: record = settings.by_name[host] port = 22 initial_password = record.initial_password ip = record.initial_ip or record.host + ".local" print(" {} ({}:{}) ".format(record.host, ip, port).center(80, "=")) kw = dict(password=initial_password) if initial_password else dict() c = Connection(ip, user=record.sudo, port=port, connect_kwargs=kw, gateway=gateway, forward_agent=True) root_conn = Info(c) tags = set(record.tags) | common_tags all_actions = set(actions.actions.keys()) # print(sorted(list(all_actions))) if whitelist_tags: white = set(whitelist_tags) # print(sorted(list(whitelist_tags))) missing = set(white) - all_actions if missing: raise Exception("Unknown whitelist tags: " + ", ".join(missing)) tags &= white else: white = set() # print("tags", sorted(list(tags))) if blacklist_tags: black = set(blacklist_tags) missing = set(black) - all_actions if missing: raise Exception("Unknown whitelist tags: " + ", ".join(missing)) tags -= (black - white) print("tags:", ", ".join(sorted(list(tags)))) tag_ids = list(tags) ctx = Context( root_conn=root_conn, record=record, tags=tags, host=host, settings=settings, ) order = list(topological_sort(actions.G)) print("\n".join(order)) print("=" * 80) with open("deps.dot", "w") as fp: print("digraph {", file=fp) for a, b in actions.G.edges: print(f'"{a}" -> "{b}"', file=fp) print("}", file=fp) missing_actions = ", ".join(sorted(set(tag_ids) - set(order))) if missing_actions: raise Exception(f"Unknown action for tags: {missing_actions}") start_at = settings.start_at if start_at: first = order.index(start_at) order = order[first:] print("-") print("\n".join(order)) todo = [a for a in order if a in tag_ids] print("actions:", ", ".join(todo)) times = {} for name in order: if name in tag_ids: t0 = time.time() print("=" * 80) print(f"Running: {name} ({host})") print("=" * 80) actions.actions[name](ctx) dt = time.time() - t0 print(f"{name} completed in {dt:.2f}s") print("") times[name] = dt for v, k in sorted(((v, k) for k, v in times.items()), reverse=True): print(f"{k:20} {v:.2f}s") print("-" * 27) total: float = sum(times.values()) print("{:20} {:.2f}s".format("total", total))
class Bridge(): def __init__(self, host, port, username, password): self.device = SSHArchDevice(host, port, username, password) # Unbridged self.connection = None self.responder = None self.result = None self.stdout = "" self.stderr = "" # Connection def _connect_fabric(self): target = "{}@{}".format(self.device.username, self.device.host) self.connection = Connection( target, connect_kwargs={'password': self.device.password}) def _connect_fabric_sudo(self): target = "{}@{}".format(self.device.username, self.device.host) config = Config(overrides={'sudo': {'password': self.device.password}}) self.connection = Connection( target, connect_kwargs={'password': self.device.password}, config=config) def _create_responder(self, su=False): if su: # Responder with SU credentials self.responder = Responder( pattern=r'Password:'******'{}\n'.format(self.device.root_password), ) return self.responder else: # responder requires sudo password self.responder = Responder( pattern=r'\[sudo\] password for *', response='{}\n'.format(self.device.password), ) return self.responder def _result_parser(self): if not self.result: CLASS_LOG.warning("Result buffer empty. Run a command.") else: if self.result.stderr: self.stderr = self.result.stderr CLASS_LOG.warning("Cmd returned error or warning:\n{}".format( self.result.stderr)) print("Current command yielded stderr:\n{}".format( self.stderr)) #Remove if self.result.stdout: self.stdout = self.result.stdout CLASS_LOG.info("Cmd success returned:\n{}".format( self.result.stdout)) print("Current command yielded stdout:\n{}".format( self.stdout)) #Remove def _command_helper(self, cmd, sudo, responder): try: if sudo: # CLASS_LOG.debug("sudo command") if responder: resp = Responder( pattern=r'\[sudo\] password for *', response='{}\n'.format(self.device.password), ) self.result = self.connection.sudo( self.device.cmd_format(cmd), pty=True, watchers=[resp]) else: self.result = self.connection.sudo( self.device.cmd_format(cmd)) else: if responder: resp = self._create_responder() self.result = self.connection.run( self.device.cmd_format(cmd), pty=True, watchers=[resp]) else: self.result = self.connection.run( self.device.cmd_format(cmd)) CLASS_LOG.debug( "Finished command helper. Obtained result: {}".format( self.result)) except UnexpectedExit: self.stderr = "Unexpected exit probably expecting a responder" CLASS_LOG.critical( "Unexpected exit probably expecting a responder") return self.result # command def _command(self, cmd, sudo=False, respond=False): if not self.connection: CLASS_LOG.critical("Must have an active fabric connection.") return if isinstance(cmd, list): for c in cmd: self._command_helper(self.device.cmd_format(c), sudo, respond) self._result_parser() else: self._command_helper(self.device.cmd_format(cmd), sudo, respond) self._result_parser() # Fabric execute def execute(self, cmd, sudo=False, respond=False): """Creates a fabric connection and sends a command.""" # Setup connection and set responder if sudo: self._connect_fabric_sudo() else: self._connect_fabric() CLASS_LOG.info("Created fabric connection") # Send command and parse result CLASS_LOG.info( "Executing command as sudo: {} and responding: {}".format( sudo, respond)) self._command(cmd, sudo, respond) CLASS_LOG.info("Command executed.") if not self.result: CLASS_LOG.error("Run command first.") exit(-1) if self.stdout and self.stderr: CLASS_LOG.warning("The following warnings were found:\n{}".format( self.stderr)) CLASS_LOG.info("The following responses were found:\n{}".format( self.stdout)) return self.stdout if self.stdout: CLASS_LOG.info("The following responses were found:\n{}".format( self.stdout)) return self.stdout if self.stderr: CLASS_LOG.warning("The following warnings were found:\n{}".format( self.stderr)) return self.stderr # SSH (Paramiko) execute def execute_ssh_command(self, cmd, time_override=1, su=False): """Sends a command(s) using an attached device without fabric.""" return self.device.send_command(cmd, time_override, su)
TASKS = { 'test': test, 'ensure_src_dir': ensure_src_dir, 'push_sources': push_sources, 'webserver_start': webserver_start, 'webserver_stop': webserver_stop, 'webserver_restart': webserver_stop, 'rebuild_index': rebuild_index, 'install_dependencies': install_dependencies, 'clear_sessions': clear_sessions, 'backup_database': backup_database, 'update_database': update_database, 'build_static': build_static, 'deploy': deploy, } if __name__ == "__main__": from functools import partial import argparse parser = argparse.ArgumentParser(description='Redpanal deploys') parser.add_argument('cmd', choices=TASKS.keys()) parser.add_argument('--revision', help="Use a specific git revision") args = parser.parse_args() task = TASKS[args.cmd] c = Connection(f'{USER}@{HOST}', port=PORT) c.run = partial(c.run, echo=True) c.sudo = partial(c.sudo, echo=True) task(c)
class ReComEx(object): """ Remote Command Executor. Wrapper class for fabric connection which remembers the working directory and other states """ def __init__(self, remote, user, strict=True): """ :param remote: url :param user: user :param strict: raise an exception if something goes wrong """ self._c = Connection(remote, user) self.dir = None self.venv = None self.strict = strict self.hide = True # hide mode for commands which are called implicitly def chdir(self, path): """ The following works on uberspace: c.chdir("etc") c.chdir("~") c.chdir("$HOME") :param path: :return: """ if path is None: self.dir = None return cmd = "cd {} && pwd".format(path) res = self.run(cmd, hide=self.hide, warn=True) if res.exited != 0: msg = "Could not change directory. Error message: {}".format( res.stderr) if self.strict: raise RemoteExecutionError(msg) else: print(msg) else: # store the result of pwd in the variable self.dir = res.stdout.strip() def activate_venv(self, path): """ Activate a virtual environment :param path: path to activate script (relative or absolute) :return: """ dir_path, script_name = os.path.split(path) res0 = self.run("cd {} && pwd".format(dir_path), hide=self.hide) if not res0.exited == 0: msg = "There was some problem with the path of the virtual env. Error message:\n {}".format( res0.stderr) if self.strict: raise RemoteExecutionError(msg) else: print(msg) return abspath = os.path.join(res0.stdout.strip(), script_name) cmd = "source {}".format(abspath) res = self.run(cmd, hide=self.hide, warn=True) if res.exited != 0: msg = "Could not activate virtual environment. Error message:\n {}".format( res.stderr) if self.strict: raise RemoteExecutionError(msg) else: print(msg) else: # store the result of pwd in the variable self.venv = abspath return res.exited def deactivate_venv(self): self.venv = None def run(self, cmd, use_dir=True, hide=True, warn=False, printonly=False, use_venv=True, strict=None): """ :param cmd: :param use_dir: change dir to self.dir before the command :param use_venv: source self.venv before the command :param hide: see docs of invoke :param warn: see docs of invoke :param printonly: only print the command but do not execute :param strict: strict mode (None -> use self.strict) :return: """ if strict is None: strict = self.strict if use_dir and self.dir is not None: cmd = "cd {}; {}".format(self.dir, cmd) if use_venv and self.venv is not None: cmd = "source {}; {}".format(self.venv, cmd) if not printonly: try: res = self._c.run(cmd, hide=hide, warn=warn) except UnexpectedExit as e: # this exception type has the (failed result included) res = e.args[0] if res.exited != 0: msg = "The return code was not 0. Error message:\n {}".format( res.stderr) if strict: raise RemoteExecutionError(msg) else: print(msg) else: print("->:", cmd) res = None return res def get_stdout(self, cmd, **kwargs): res = self.run(cmd, **kwargs) if hasattr(res, "stdout"): return res.stdout.strip() else: return res
def inits_from_iterable_of_Connections(self): g = Group.from_connections((Connection("foo"), Connection("bar"))) assert len(g) == 2 assert g[1].host == "bar"
class FtpServerHelperStep1: def __init__(self, zipfile_path): """ :param str zipfile_path: """ self.zipfile_path = zipfile_path self.zipfile_root_foldername = self.get_zipfile_rootpath(zipfile_path) # 解压后的根目录名 if not self.zipfile_root_foldername: cli.error("无法获取压缩包的根目录") exit() # ftp 信息 self.ftp_info = FtpInfo(path.dirname(self.zipfile_path)) self.zip_uploads_path = path.dirname(self.zipfile_path) # ftp 上传目录 self.zip_process_path = path.join(ftp_data_tmp_path(), self.ftp_info.project_code, self.ftp_info.company_code + "_fid_" + self.ftp_info.ftp_id ) # ftp 上传的数据临时处理目录 self.zipfile_newname = "{}_{}_{}.zip".format(self.ftp_info.project_code, self.ftp_info.company_code + "_fid" + self.ftp_info.ftp_id, time.strftime('%Y%m%d%H%M%S', time.localtime(time.time())) ) # 执行本地linux 命令实例 self.local_connection = Connection("localhost") # 获取zip 根目录 def get_zipfile_rootpath(self, zip_file_path): """ :param str zip_file_path: :return: None if not a zip file,else rootname of zip """ # 检测是否是zip 文件 if not zipfile.is_zipfile(zip_file_path): return None # 分析根目录 zip_file = zipfile.ZipFile(zip_file_path, "r") zip_root_dir_name = zip_file.infolist()[0] return zip_root_dir_name.filename.rstrip("/") def show_tree(self): """ 显示出给定目录的tree 结构,默认两层,将调用系统自带的tree命令 :return: """ self.local_connection.local("tree -L {level} {path}".format(path=self.zip_process_path, level=2)) def ls_lah(self, file_path): cli.info("ls -lah {}".format(file_path)) self.local_connection.local("ls -lah {}".format(file_path)) def show_zipfile_info(self): """ 分析给定的ftp上传目录,获取相关的项目代号,外包代号,ftp id 等信息 :return: """ cli.info(str(self.ftp_info)) def mv(self): """ 移动文件到数据处理目录下 :return: """ if not path.exists(self.zip_process_path): os.makedirs(self.zip_process_path, exist_ok=True) # 不存在则新建,存在则不管 self.local_connection.local("mv {} {}".format(self.zipfile_path, path.join(self.zip_process_path, self.zipfile_newname) )) def unzip(self): """ 解压 :return: """ responder = Responder( pattern=r".*", response="A\n", ) cli.info("unzip {} -d {}".format(path.join(self.zip_process_path, self.zipfile_newname), self.zip_process_path)) result = self.local_connection.local("unzip {} -d {}".format(path.join(self.zip_process_path, self.zipfile_newname), self.zip_process_path), pty=True) # type:Result # if result.ok: # cli.info("解压完成") # elif result.failed: # cli.error("解压出错了") # cli.error(result.stderr + "\n") # exit(result.return_code) # 压缩包解压后的名字按命名规范重命名 cli.info("mv {} {}".format(path.join(self.zip_process_path, self.zipfile_root_foldername), path.join(self.zip_process_path, self.zipfile_newname[:-4]) )) self.local_connection.local("mv {} {}".format(path.join(self.zip_process_path, self.zipfile_root_foldername), path.join(self.zip_process_path, self.zipfile_newname)[:-4] )) # 包分析 def package_analysis(self): # 最后一个 ''字符拼接必须得有,后期调整逻辑 packages_folder = path.join(self.zip_process_path, self.zipfile_newname[:-4]) cli.info("分析目录:{}".format(packages_folder)) assistant_controller = PackageAssistantController(packages_folder) assistant_controller.do_analysis() # wav 目录下的文件移到wav同级目录下 assistant_controller.replace_folder_wav_files() # 删除 包中出现的 m4a mp3 temp 目录 assistant_controller.delete_unknown_folders() # 删除后缀 skip、sk、pk等文件 assistant_controller.delete_unknown_suffix_file() # .u后缀文件rename assistant_controller.rename_endswith_u_file() # 删除重复录制产生的 xxx_1.wav xxx_2.wav 这种文件 assistant_controller.delete_duplicated_underline_number_file() # 解密被加密的文件 assistant_controller.decrypt_endswith_enc_file() # 删除没有对应音频的txt assistant_controller.delete_single_txt() # 输出结果,生成excel 和 运行结果文件 assistant_controller.result_echo_no_via_pager() assistant_controller.result_write_2_file() assistant_controller.package_info_write_to_excel() # 发送邮件通知 assistant_controller.send_mail(True, True)
def setup(self): self.cxns = [Connection(x) for x in ("host1", "host2", "host3")] self.args = ("command", ) self.kwargs = {"hide": True, "warn": True}
def connect(host=config['host'], **args): return Connection(host, **kwargs, **args)
user = "******" virtualenv_root = '~/.virtualenvs/your_project_name' virtualenv_root_local = '~/virtualenvs/your_project_name' project_name = "your_project_name" webapps_password = "" psql_user = "******" psql_database_name = "postgres_database_name" psql_password = "******" supervisor_process_name = "your_project_name" bitbucket_user = "" bitbucket_url = "https://{}@bitbucket.org/your_user/your_project_name.git".format( bitbucket_user) remote_config = Config(overrides={'sudo': {'password': '******'}}) remote_connection = Connection(hosts[0], user=user, connect_kwargs={'password': '******'}, config=remote_config) local_config = invoke.config.Config(project_location=BASE_DIR) local_context = invoke.context.Context(config=local_config) # TODO Creamos un usuario y lo agregamos al grupo sudo # $ adduser serveruser # Le asignamos un password. # Adding user webapps to group sudo # $ gpasswd -a serveruser sudo # su serveruser @task
ssh_id = civo.ssh.search(filter='name:alejandrojnm')[0]['id'] if not search_hostname: instance = civo.instances.create(hostname=hostname_default, size=size_id, region='lon1', template_id=template, public_ip='true', ssh_key_id=ssh_id) status = instance['status'] while status != 'ACTIVE': status = civo.instances.search( filter='hostname:{}'.format(hostname_default))[0]['status'] time.sleep(10) # add this because the instance is not ready to handle ssh connection so fast time.sleep(20) ip_server = civo.instances.search( filter='hostname:{}'.format(hostname_default))[0]['public_ip'] username = '******' c = Connection('{}@{}'.format(username, ip_server)) # c.run('cat /etc/os-release') result = c.put('webroot.gz', remote='/tmp') print("Uploaded {0.local} to {0.remote}".format(result)) c.sudo('apt update') c.sudo('apt install -qy nginx') c.sudo('rm -rf /var/www/html/*') c.sudo('tar -C /var/www/html/ -xzvf /tmp/webroot.gz')
def _build_and_reinstall_memkind(self, c: fabric.Connection) -> None: """ Rebuild and reinstall memkind library """ result = c.run('nproc', **self._verbosity_option) nproc = int(result.stdout.strip()) c.run('make distclean', **self._verbosity_option, warn=True) c.run('./autogen.sh', **self._verbosity_option) c.run(f'./configure {self._memkind_configure_params}', **self._verbosity_option) c.run(f'make -j {nproc}', **self._verbosity_option) c.run(f'make checkprogs -j {nproc}', **self._verbosity_option) c.run('sudo make uninstall', **self._verbosity_option) c.run('sudo make install', **self._verbosity_option) c.run('sudo ldconfig', **self._verbosity_option)
def setup(self): self.c = Connection('localhost') self.remote = self._tmp('file.txt')
#!/usr/bin/env python # -*- coding: utf-8 -*- from fabric import Connection from invoke.exceptions import UnexpectedExit print('Code For Curitiba - Sistema de deploy do projeto onibus-io-frontend\n') connect_kwargs = {"key_filename": ["id_rsa"]} with Connection(host='jarvis.preludian.com.br', user='******', port=40022, connect_kwargs=connect_kwargs) as c: try: print('Stopping containers and destroying images...') c.run('docker stop code4cwb-onibus-io-frontend-container && \ docker rm code4cwb-onibus-io-frontend-container && \ docker rmi code4cwb/onibus-io-frontend') except UnexpectedExit: print('Delete deleting container not possible... Keep going') print('Running container...') c.run( 'docker run --restart=always -d --network=code4cwb-onibusio --name code4cwb-onibus-io-frontend-container -m 128m -p 9001:80 code4cwb/onibus-io-frontend' ) print('\nTerminado com sucesso')
class RemoteExecuter: host = None hostUrl = None connectArgs = None conn = None sshConf = None def __init__(self, host, user, password): self.host = host self.user = user self.password = password self.sshConf = sshConfig(host, user, password) self.hostUrl = "{0}@{1}".format(self.sshConf.getUser(), self.sshConf.getHost()) self.connectArgs = {"password": self.sshConf.getPass()} self.conn = Connection(host=self.hostUrl, port=self.sshConf.getPort(), connect_kwargs=self.connectArgs) def __init__(self, host, sshConf): self.host = host self.sshConf = sshConf app.logger.info( "connection info: {0}@{1} identified by {2}. passwordless {3}". format(self.sshConf.getUser(), self.sshConf.getHost(), self.sshConf.getPass(), self.sshConf.isPasswordless())) self.hostUrl = "{0}@{1}".format(self.sshConf.getUser(), self.sshConf.getHost()) if self.sshConf.isPasswordless() == True: self.connectArgs = { "key_filename": self.sshConf.getPassFile(), "look_for_keys": False, "allow_agent": False } else: self.connectArgs = {"password": self.sshConf.getPass()} self.conn = Connection(host=self.hostUrl, port=self.sshConf.getPort(), connect_kwargs=self.connectArgs) def refreshConn(self): self.conn.close() self.conn.open() def executeRemoteCommand(self, cmd): try: # cmd="sudo bash -c \"" + cmd + "\"" app.logger.info("executing remote command: {0}".format(cmd)) self.refreshConn() result = self.conn.run(cmd, hide=True) # result=self.conn.sudo(cmd,user="******",hide=True) #result = self.conn.sudo(cmd, hide=True, shell=False) return ReturnValue(result.exited, result.stderr, result.stdout) except (UnexpectedExit, Exit, ParseError) as e: if isinstance(e, ParseError): app.logger.error( "Remote Executor:: Parser failed with error:" + str(e)) return ReturnValue(1, e.stderr, "") if isinstance(e, Exit) and e.message: app.logger.error("Remote Executor:: Exited with error: " + str(e)) return ReturnValue(e.code, e.stderr, "") if isinstance(e, UnexpectedExit) and e.result.hide: app.logger.error( "Remote Executor:: Unexpected exit with error: " + str(e)) return ReturnValue(1, "", "") else: app.logger.error("Remote Executor:: Exception : " + str(Exception) + " Err: " + str(e)) return ReturnValue(e.result.exited, e.result.stderr.strip(), e.result.stdout.strip()) def copyFileToRemote(self, sourcePath, destinationPath): try: #conn = Connection(host=self.hostUrl, connect_kwargs=self.connectArgs) app.logger.info("copying file to remote: {0}->{1}@{2}".format( sourcePath, self.host, destinationPath)) self.refreshConn() result = self.conn.put(sourcePath, destinationPath, preserve_mode=True) #put() method doesnt return a fabric.runners.Result object like run() method. #it returns a fabric.transfer.Result which has no return info. #on failure it raises exception (oserror), no exception means it succeeded. return ReturnValue(0, "", "") except (UnexpectedExit, Exit, ParseError) as e: if isinstance(e, ParseError): app.logger.error( "Remote Executor:: Parser failed with error:" + e) return ReturnValue(1, e.stderr, "") if isinstance(e, Exit) and e.message: app.logger.error("Remote Executor:: Exited with error: " + e) return ReturnValue(e.code, e.stderr, "") if isinstance(e, UnexpectedExit) and e.result.hide: return ReturnValue(1, "", "") else: app.logger.error("Remote Executor:: Exception : " + str(Exception) + " Err: " + str(e)) return ReturnValue(e.result.exited, e.result.stderr.strip(), e.result.stdout.strip()) def opsHandler(self, opList): # execute operations remotely one by one for cmd in opList: try: if cmd["operId"] == RemoteOperations.CMD: self.executeRemoteCommand(cmd["args"][0]) elif cmd["operId"] == RemoteOperations.COPY: self.copyFileToRemote(cmd["args"][0], cmd["args"][1]) else: app.logger.error( "remote operation {0} is not supported".format( cmd["operId"])) raise Exception( "remote operation {0} is not supported".format( cmd["operId"])) except Exception as ex: app.logger.error( "operation {0} failed with exception {1}".format( str(cmd), str(ex))) return True
def setup(self): self.c = Connection("localhost") self.remote = path.local.mkdtemp().join("file.txt").realpath()
class RemoteRunner: """ Starts Jupyter lab on a remote resource and port forwards session to local machine. Returns ------- RemoteRunner An object that is responsible for connecting to remote host and launching jupyter lab. Raises ------ SystemExit When the specified local port is not available. """ host: str port: int = 8888 conda_env: str = None notebook_dir: str = None port_forwarding: bool = True launch_command: str = None identity: str = None shell: str = '/usr/bin/env bash' def __post_init__(self): if self.port_forwarding and not is_port_available(self.port): raise SystemExit(( f'''Specified port={self.port} is already in use on your local machine. Try a different port''' )) connect_kwargs = {} if self.identity: connect_kwargs['key_filename'] = [self.identity] self.session = Connection(self.host, connect_kwargs=connect_kwargs, forward_agent=True) try: self.session.open() except paramiko.ssh_exception.BadAuthenticationType: loc_transport = self.session.client.get_transport() loc_transport.auth_interactive_dumb(self.session.user, _authentication_handler) self.session.transport = loc_transport def dir_exists(self, directory): """ Checks if a given directory exists on remote host. """ message = "couldn't find the directory" cmd = f'''if [[ ! -d "{directory}" ]] ; then echo "{message}"; fi''' out = self.session.run(cmd, hide='out').stdout.strip() return message not in out def setup_port_forwarding(self): """ Sets up SSH port forwarding """ print('**********************************') print('*** Setting up port forwarding ***') print('**********************************\n\n') local_port = int(self.port) remote_port = int(self.parsed_result['port']) with self.session.forward_local( local_port, remote_port=remote_port, remote_host=self.parsed_result['hostname'], ): time.sleep( 3 ) # don't want open_browser to run before the forwarding is actually working open_browser(port=local_port, token=self.parsed_result['token']) self.session.run(f'tail -f {self.log_file}', pty=True) def close(self): self.session.close() def start(self): """ Launches Jupyter Lab on remote host, sets up ssh tunnel and opens browser on local machine. """ # jupyter lab will pipe output to logfile, which should not exist prior to running # Logfile will be in $TMPDIR if defined on the remote machine, otherwise in $HOME try: if self.dir_exists('$TMPDIR'): self.log_dir = '$TMPDIR' else: self.log_dir = '$HOME' self.log_dir = f'{self.log_dir}/.jupyter_forward' kwargs = dict(pty=True, shell=self.shell) self.session.run(f'mkdir -p {self.log_dir}', **kwargs) timestamp = datetime.datetime.now().strftime('%Y-%m-%dT%H-%M-%S') self.log_file = f'{self.log_dir}/log.{timestamp}' self.session.run(f'touch {self.log_file}', **kwargs) command = 'jupyter lab --no-browser' if self.launch_command: command = f'{command} --ip=\$(hostname)' else: command = f'{command} --ip=`hostname`' if self.notebook_dir: command = f'{command} --notebook-dir={self.notebook_dir}' command = f'{command} > {self.log_file} 2>&1' if self.conda_env: command = f'conda activate {self.conda_env} && {command}' if self.launch_command: script_file = f'{self.log_dir}/batch-script.{timestamp}' cmd = f"""echo "#!{self.shell}\n\n{command}" > {script_file}""" self.session.run(cmd, **kwargs, echo=True) self.session.run(f'chmod +x {script_file}', **kwargs) command = f'{self.launch_command} {script_file}' self.session.run(command, asynchronous=True, **kwargs, echo=True) # wait for logfile to contain access info, then write it to screen condition = True stdout = None pattern = 'is running at:' while condition: try: result = self.session.run(f'cat {self.log_file}', **kwargs) if pattern in result.stdout: condition = False stdout = result.stdout except invoke.exceptions.UnexpectedExit: print( f'Trying to access {self.log_file} on {self.session.host} again...' ) pass self.parsed_result = parse_stdout(stdout) if self.port_forwarding: self.setup_port_forwarding() else: open_browser(url=self.parsed_result['url']) self.session.run(f'tail -f {self.log_file}', **kwargs) finally: self.close() print( '\n***********************************************************' ) print( '*** Terminated the network connection to the remote end ***') print( '***********************************************************\n' )
def test_host(c): con = Connection('192.168.88.75',user='******',connect_kwargs={'password':'******'}) con.run("uname -a")
class RemoteCommandExecutor: """Execute remote commands on the cluster master node.""" USERNAMES = { "alinux": "ec2-user", "centos6": "centos", "centos7": "centos", "ubuntu1404": "ubuntu", "ubuntu1604": "ubuntu", } def __init__(self, cluster): self.__connection = Connection( host=cluster.master_ip, user=self.USERNAMES[cluster.os], forward_agent=True, connect_kwargs={"key_filename": cluster.ssh_key}, ) self.__user_at_hostname = "{0}@{1}".format(self.USERNAMES[cluster.os], cluster.master_ip) def __del__(self): try: self.__connection.close() except Exception as e: # Catch all exceptions if we fail to close the clients logging.warning("Exception raised when closing remote ssh client: {0}".format(e)) def run_remote_command(self, command, log_error=True, additional_files=None, raise_on_error=True, login_shell=True): """ Execute remote command on the cluster master node. :param command: command to execute. :param log_error: log errors. :param additional_files: additional files to copy before executing script. :param raise_on_error: if True raises a RemoteCommandExecutionError on failures :param login_shell: if True prepends /bin/bash --login -c to the given command :return: result of the execution. """ if isinstance(command, list): command = " ".join(command) self._copy_additional_files(additional_files) logging.info("Executing remote command command on {0}: {1}".format(self.__user_at_hostname, command)) if login_shell: command = "/bin/bash --login -c {0}".format(shlex.quote(command)) result = self.__connection.run(command, warn=True, pty=True, hide=False) result.stdout = "\n".join(result.stdout.splitlines()) result.stderr = "\n".join(result.stderr.splitlines()) if result.failed and raise_on_error: if log_error: logging.error( "Command {0} failed with error:\n{1}\nand output:\n{2}".format( command, result.stderr, result.stdout ) ) raise RemoteCommandExecutionError(result) return result def run_remote_script(self, script_file, args=None, log_error=True, additional_files=None): """ Execute a script remotely on the cluster master node. Script is copied to the master home dir before being executed. :param script_file: local path to the script to execute remotely. :param args: args to pass to the script when invoked. :param log_error: log errors. :param additional_files: additional files to copy before executing script. :return: result of the execution. """ script_name = os.path.basename(script_file) self.__connection.put(script_file, script_name) if not args: args = [] return self.run_remote_command( ["/bin/bash", "--login", script_name] + args, log_error=log_error, additional_files=additional_files ) def _copy_additional_files(self, files): for file in files or []: self.__connection.put(file, os.path.basename(file))
class CosmicHost(CosmicObject): def __init__(self, ops, data): super().__init__(ops, data) global FABRIC_PATCHED if not FABRIC_PATCHED: Connection.open_orig = Connection.open Connection.open = unsafe_open FABRIC_PATCHED = True # Load configuration config = get_config() ssh_user = config.get('ssh', 'user', fallback=None) ssh_key_file = config.get('ssh', 'ssh_key_file', fallback=None) connect_kwargs = { 'key_filename': ssh_key_file } if ssh_key_file else None ilo_user = config.get('ilo', 'user', fallback=None) ilo_password = config.get('ilo', 'password', fallback=None) # Setup SSH connection self._connection = Connection(self['name'], user=ssh_user, connect_kwargs=connect_kwargs) # Setup ILO connection ilo_address = self['name'].split('.') ilo_address.insert(1, 'ilom') ilo_address = '.'.join(ilo_address) self._ilo = hpilo.Ilo(ilo_address, login=ilo_user, password=ilo_password) self.vms_with_shutdown_policy = [] def refresh(self): self._data = self._ops.get_host(id=self['id'], json=True) def disable(self): if self.dry_run: logging.info(f"Would disable host '{self['name']}'") return True else: logging.info(f"Disabling host '{self['name']}'", self.log_to_slack) if not self._ops.cs.updateHost(id=self['id'], allocationstate='Disable').get('host'): logging.error(f"Failed to disable host '{self['name']}'", self.log_to_slack) return False with click_spinner.spinner(): while True: self.refresh() if self['resourcestate'] == 'Disabled': break time.sleep(5) return True def enable(self): if self.dry_run: logging.info(f"Would enable host '{self['name']}'") return True else: logging.info(f"Enabling host '{self['name']}'", self.log_to_slack) if not self._ops.cs.updateHost(id=self['id'], allocationstate='Enable').get('host'): logging.error(f"Failed to enable host '{self['name']}'", self.log_to_slack) return False with click_spinner.spinner(): while True: self.refresh() if self['resourcestate'] == 'Enabled': break time.sleep(5) return True def empty(self, target=None): total = success = failed = 0 all_vms = self.get_all_vms() + self.get_all_project_vms( ) + self.get_all_routers() + self.get_all_project_routers( ) + self.get_all_system_vms() if not all_vms: logging.warning(f"No VMs found on host '{self['name']}'") return total, success, failed total = len(all_vms) target_message = f" to target '{target['name']}'" if target else '' if self.dry_run: logging.info( f"Dry run of VM migration away from host '{self['name']}'" + target_message) else: logging.info(f"Migrating VMs away from host '{self['name']}'" + target_message) for vm in all_vms: if vm.get('maintenancepolicy') == 'ShutdownAndStart': if not vm.stop(): failed += 1 continue success += 1 # If the host is disabled, try to restart the VM. Will fail if the host is on NVMe. if self['resourcestate'] == 'Disabled': if vm.start(): continue self.vms_with_shutdown_policy.append(vm) continue vm_on_dedicated_hv = False dedicated_affinity_id = None for affinity_group in vm.get_affinity_groups(): if affinity_group['type'] == 'ExplicitDedication': vm_on_dedicated_hv = True dedicated_affinity_id = affinity_group['id'] if target: available_hosts = [target] else: try: available_hosts = self._ops.cs.findHostsForMigration( virtualmachineid=vm['id']).get('host', []) except CloudStackApiException as e: logging.error( f"Encountered API exception while finding suitable host for migration: {e}" ) failed += 1 continue available_hosts.sort(key=itemgetter('memoryallocated')) migration_host = None for available_host in available_hosts: if not target: # Skip hosts that require storage migration if available_host['requiresStorageMotion']: logging.debug( f"Skipping '{available_host['name']}' because migrating VM '{vm['name']}' requires a storage migration" ) continue # Ensure host is suitable for migration if not available_host['suitableformigration']: logging.debug( f"Skipping '{available_host['name']}' because it's not suitable for migration" ) continue # Only hosts in the same cluster if available_host['clusterid'] != self['clusterid']: logging.debug( f"Skipping '{available_host['name']}' because it's part of a different cluster" ) continue if vm_on_dedicated_hv: # Ensure the dedication group matches if available_host.get( 'affinitygroupid') != dedicated_affinity_id: logging.info( f"Skipping '{available_host['name']}' because host does not match the dedication group of VM '{vm['name']}'" ) continue else: # If the user VM isn't dedicated, skip dedicated hosts if vm.is_user_vm() and 'affinitygroupid' in available_host: logging.info( f"Skipping '{available_host['name']}' because host is dedicated and VM '{vm['name']}' is not" ) continue logging.debug( f"Selected '{available_host['name']}' for VM '{vm['name']}'" ) migration_host = available_host break if not migration_host: logging.error( f"Failed to find host with capacity to migrate VM '{vm['name']}'. Please migrate manually to another cluster." ) failed += 1 continue if not vm.migrate(migration_host): failed += 1 else: success += 1 return total, success, failed def get_all_vms(self, domain=None, keyword_filter=None): domain_id = domain['id'] if domain else None vms = self._ops.cs.listVirtualMachines(fetch_list=True, hostid=self['id'], domainid=domain_id, keyword=keyword_filter, listall='true') return [CosmicVM(self._ops, vm) for vm in vms] def get_all_project_vms(self, project=None): if project: project_id = project['id'] else: project_id = '-1' project_vms = self._ops.cs.listVirtualMachines(fetch_list=True, hostid=self['id'], listall='true', projectid=project_id) return [CosmicVM(self._ops, vm) for vm in project_vms] def get_all_routers(self, domain=None): domain_id = domain['id'] if domain else None routers = self._ops.cs.listRouters(fetch_list=True, hostid=self['id'], domainid=domain_id, listall='true') return [CosmicRouter(self._ops, router) for router in routers] def get_all_project_routers(self, project=None): if project: project_id = project['id'] else: project_id = '-1' project_routers = self._ops.cs.listRouters(fetch_list=True, hostid=self['id'], listall='true', projectid=project_id) return [CosmicRouter(self._ops, router) for router in project_routers] def get_all_system_vms(self): system_vms = self._ops.cs.listSystemVms(fetch_list=True, hostid=self['id']) return [CosmicVM(self._ops, vm) for vm in system_vms] def copy_file(self, source, destination, mode=None): if self.dry_run: logging.info( f"Would copy '{source}' to '{destination}' on '{self['name']}") return self._connection.put(source, destination) if mode: self._connection.sudo(f'chmod {mode:o} {destination}') def execute(self, command, sudo=False, hide_stdout=True, pty=False, always=False): if self.dry_run and not always: logging.info(f"Would execute '{command}' on '{self['name']}") return if sudo: runner = self._connection.sudo else: runner = self._connection.run return runner(command, hide=hide_stdout, pty=pty) def reboot(self, action=RebootAction.REBOOT): reboot_or_halt = 'halt' if action == RebootAction.HALT else 'reboot' if self.dry_run: logging.info( f"Would {reboot_or_halt} host '{self['name']}' with action '{action}'" ) return True if self.execute( 'virsh list | grep running | wc -l').stdout.strip() != '0': logging.error( f"Host '{self['name']}' has running VMs, will not {reboot_or_halt}", self.log_to_slack) return False try: if action == RebootAction.REBOOT: logging.info(f"Rebooting '{self['name']}' in 60s", self.log_to_slack) self.execute('shutdown -r 1', sudo=True) elif action == RebootAction.HALT: logging.info( f"Halting '{self['name']}' in 60s, be sure to start it manually to continue the rolling reboot", self.log_to_slack) self.execute('shutdown -h 1', sudo=True) elif action == RebootAction.FORCE_RESET: logging.info(f"Force resetting '{self['name']}'", self.log_to_slack) self.execute('sync', sudo=True) self.execute('echo b > /proc/sysrq-trigger', sudo=True) elif action == RebootAction.UPGRADE_FIRMWARE: logging.info( f"Rebooting '{self['name']}' after firmware upgrade", self.log_to_slack) self.execute( "tmux new -d 'yes | sudo /usr/sbin/smartupdate upgrade && sudo reboot'", pty=True) elif action == RebootAction.PXE_REBOOT: logging.info(f"PXE Rebooting '{self['name']}' in 10s", self.log_to_slack) self.execute( "tmux new -d 'sleep 10 && sudo /usr/sbin/hp-reboot pxe'", pty=True) elif action == RebootAction.SKIP: logging.info(f"Skipping reboot for '{self['name']}'", self.log_to_slack) except Exception as e: logging.warning( f"Ignoring exception as it's likely related to the {reboot_or_halt}: {e}", self.log_to_slack) return True def set_uid_led(self, state): new_state = 'on' if state else 'off' if self.dry_run: logging.info(f"Would set UID led {new_state}") else: self.execute(f'hpasmcli -s "set uid {new_state}"', sudo=True) def wait_until_offline(self): if self.dry_run: logging.info( f"Would wait for '{self['name']}' to complete it's reboot") else: logging.info( f"Waiting for '{self['name']}' to complete it's reboot", self.log_to_slack) with click_spinner.spinner(): while True: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.settimeout(5) result = s.connect_ex((self['name'], 22)) if result != 0: break time.sleep(5) def wait_until_online(self): if self.dry_run: logging.info( f"Would wait for '{self['name']}' to come back online") else: logging.info(f"Waiting for '{self['name']}' to come back online", self.log_to_slack) with click_spinner.spinner(): while True: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.settimeout(5) result = s.connect_ex((self['name'], 22)) if result == 0: break if self.dry_run: logging.info(f"Would wait for libvirt on '{self['name']}'") else: logging.info(f"Waiting for libvirt on '{self['name']}'", self.log_to_slack) with click_spinner.spinner(): while True: try: if self.execute('virsh list').return_code == 0: break except (ConnectionResetError, UnexpectedExit, CommandTimedOut): pass time.sleep(5) def restart_vms_with_shutdown_policy(self): if self.dry_run: logging.info( f"Would restart VMs with 'ShutdownAndStart' policy on host '{self['name']}'" ) else: logging.info( f"Starting VMs with 'ShutdownAndStart' policy on host '{self['name']}'", self.log_to_slack) for vm in self.vms_with_shutdown_policy: vm.start() def wait_for_agent(self): if self.dry_run: logging.info( f"Would wait for agent to became up on host '{self['name']}'") return else: logging.info(f"Waiting for agent on host '{self['name']}'", self.log_to_slack) with click_spinner.spinner(): while True: self.refresh() if self['state'] == 'Up': break time.sleep(5) def get_disks(self, vm): lv = libvirt.openReadOnly(f"qemu+tcp://{self['name']}/system") domain = lv.lookupByName(vm['instancename']) tree = ElementTree.fromstring(domain.XMLDesc()) block_devs = tree.findall('devices/disk') disk_data = {} for disk in block_devs: if disk.get('device') != 'disk': continue dev = disk.find('target').get('dev') full_path = disk.find('source').get('file') _, _, pool, path = full_path.split('/') size, _, _ = domain.blockInfo(dev) disk_data[path] = { 'dev': dev, 'pool': pool, 'path': path, 'size': size } lv.close() return disk_data def get_domjobinfo(self, vm): try: lv = libvirt.openReadOnly(f"qemu+tcp://{self['name']}/system") all_domains = lv.listAllDomains() if any([x for x in all_domains if x.name() == vm]): domain = lv.lookupByName(vm) domjobinfo = domain.jobInfo() return DomJobInfo.from_list(domjobinfo) except libvirt.libvirtError as _: pass # Ignore exception return DomJobInfo() def get_domjobstats(self, vm, correction=True): try: lv = libvirt.openReadOnly(f"qemu+tcp://{self['name']}/system") all_domains = lv.listAllDomains() if any([x for x in all_domains if x.name() == vm]): domain = lv.lookupByName(vm) domjobstats = domain.jobStats() memory_total = domjobstats.get('memory_total', 0) if correction: if memory_total == 0: c_add = domain.info()[0] memory_total = memory_total + c_add return DomJobInfo( jobType=domjobstats.get('type', libvirt.VIR_DOMAIN_JOB_NONE), operation=domjobstats.get('operation', 0), timeElapsed=domjobstats.get('time_elapsed', 0), timeRemaining=domjobstats.get('time_remaining', 0), dataTotal=domjobstats.get('data_total', 0), dataProcessed=domjobstats.get('data_processed', 0), dataRemaining=domjobstats.get('data_remaining', 0), memTotal=memory_total, memProcessed=domjobstats.get('memory_processed', 0), memRemaining=domjobstats.get('memory_remaining', 0), fileTotal=domjobstats.get('disk_total', 0), fileProcessed=domjobstats.get('disk_processed', 0), fileRemaing=domjobstats.get('disk_remaining', 0)) except libvirt.libvirtError as _: pass # Ignore exception return DomJobInfo() def get_blkjobinfo(self, vm, volume): try: disks = self.get_disks(vm) disk = dict(filter(lambda x: x[0] == volume, disks.items())) lv = libvirt.openReadOnly(f"qemu+tcp://{self['name']}/system") all_domains = lv.listAllDomains() if any([x for x in all_domains if x.name() == vm['instancename']]): domain = lv.lookupByName(vm['instancename']) blkjobinfo = domain.blockJobInfo(disk[volume]['dev'], 0) return BlkJobInfo(jobType=blkjobinfo.get('type', 0), bandWidth=blkjobinfo.get('bandwidth', 0), current=blkjobinfo.get('cur', 0), end=blkjobinfo.get('end', 0)) except libvirt.libvirtError as _: pass # Ignore exception return BlkJobInfo() def set_iops_limit(self, vm, max_iops): command = f""" for i in $(/usr/bin/virsh domblklist --details '{vm['name']}' | grep disk | grep file | /usr/bin/awk '{{print $3}}'); do /usr/bin/virsh blkdeviotune '{vm['name']}' $i --total-iops-sec {max_iops} --live done """ if not self.execute(command, sudo=True).return_code == 0: logging.error(f"Failed to set IOPS limit for '{vm['name']}'") return False else: return True def merge_backing_files(self, vm): command = f""" for i in $(/usr/bin/virsh domblklist --details '{vm['name']}' | grep disk | grep file | /usr/bin/awk '{{print $3}}'); do echo /usr/bin/virsh blockpull '{vm['name']}' $i --wait --verbose done """ if not self.execute(command, sudo=True).return_code == 0: logging.error( f"Failed to merge backing volumes for '{vm['name']}'") return False else: return True def power_on(self): try: self._ilo.set_host_power(True) return True except Exception as err: logging.error(f"Failed to power on '{self['name']}': {err}") return False def file_exists(self, path): try: result = self.execute(f"/bin/ls -la \"{path}\"", always=True).stdout return result.split() except UnexpectedExit: return [] def rename_file(self, source, destination): try: if not self.execute(f"/bin/mv \"{source}\" \"{destination}\"", True).return_code == 0: return False return True except UnexpectedExit: return False def rename_existing_destination_file(self, path): timestamp = datetime.now().strftime("%d-%m-%Y-%H-%M-%S") magweg = f"magweg-migration-{timestamp}" logging.info( f"Renaming {path} to {path}.{magweg} on host {self['name']}") if not self.rename_file(path, f"{path}.{magweg}"): return False return True def __del__(self): if self._connection: self._connection.close()
# Getting the host IPs hosts = [(k, v) for k, v in config['hosts'].items()] master = hosts[0] # Connecting to hosts for i in range(len(hosts)): current = hosts[i] public_ip = current[0] # Replacing dots with dashes public_ip = public_ip.replace(".", "-") # Establishing connection c = Connection(host=f'ubuntu@ec2-{public_ip}.compute-1.amazonaws.com', connect_kwargs={'key_filename': config['ssh_path']}) time.sleep(20) print("Successfully connected...") # ec2.instances.terminate() if current == master: print(f'master ip {public_ip}') c.run("sudo kubeadm init") c.run("mkdir -p $HOME/.kube") c.run("sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config") c.run("sudo chown $(id -u):$(id -g) $HOME/.kube/config") c.run( "sudo kubectl --kubeconfig=/etc/kubernetes/admin.conf create -f https://docs.projectcalico.org/v3.14/manifests/calico.yaml" ) c.run(
def backol(c): c = Connection('aw') """ backup data from aw mongo """ t = time.time() with c.cd('/var/www/anwen/db'): c.run('. ~/.zshrc && python3 db_in_out.py -o') c.run('tar czf aw_yaml_{}.tar.gz data'.format(t)) with c.cd('/var/www/anwen/docs/shares'): c.run('tar czf aw_md_{}.tar.gz *.md'.format(t)) with c.cd('/var/www/anwen/static/upload/'): c.run('tar czf upload_{}.tar.gz img'.format(t))
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'MFC' __time__ = '18/8/23 15:06' """ pip install fabric python3的api和python2的api不同了,注意 http://docs.fabfile.org/en/2.3/ https://blog.csdn.net/tohearts/article/details/81060608 """ from fabric import Connection conn = Connection('192.33.33.33', port=22, user='******', connect_kwargs={'password': ''}) result = conn.run('uname -s', hide=True) result2 = conn.run('cat /etc/issue', hide=True) msg = "Ran {0.command!r} on {0.connection.host}, got stdout:\n{0.stdout}" print(msg.format(result)) print('-' * 60) print(msg.format(result2))
def _Connection(*args, **kwargs): kwargs['config'] = Config({'run': {'in_stream': False}}) return Connection(*args, **kwargs)
fabric_config = Config() fabric_config['load_ssh_config'] = False fabric_config['port'] = 22 fabric_config['user'] = '******' fabric_config['connect_kwargs'] = { "key_filename": "c:\Users\Guodong\.ssh\exportedkey201310171355", } # Superuser privileges via auto-response sudo_pass_auto_respond = Responder( pattern=r'\[sudo\] password:'******'mypassword\n', ) # create connection cxn = Connection('192.168.88.19', config=fabric_config) # do tasks on host print cxn.run("uname -a", hide=True).stdout print cxn.sudo("whoami", hide=True).stdout cxn.run('sudo whoami', pty=True, watchers=[sudo_pass_auto_respond]) cxn.put(__file__, "/tmp/this.py") cxn.run("sudo rm -f /tmp/this.py") # cxn.get("/tmp/this.py", "this.py") print disk_free(cxn) # config multiple servers with methods 1 for host in ('192.168.88.19', '192.168.88.20', '192.168.88.21'): result = Connection(host, config=fabric_config).run('uname -s', hide=True) print("{}: {}".format(host, result.stdout.strip()))
def open_method_generates_real_connection(self): c = Connection("localhost") c.open() assert c.client.get_transport().active is True assert c.is_connected is True return c
def main(): c = Connection("[email protected]") with c.cd('/home/ubuntu/projects/CybexDotDexUAT'): c.run('git stash') c.run('git pull') c.run('git stash pop') c.run('/usr/bin/yarn') c.run('/usr/bin/yarn build') c.run( '/home/ubuntu/.nvm/versions/node/v12.16.1/bin/pm2 restart cybex-dot-dex-uat' )
def unsafe_open(self): # pragma: no cover self.client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy()) Connection.open_orig(self)
def logs_source(ctx): with Connection(host=host, connect_kwargs={'password': '******'}) as c: c.run('sudo journalctl -fu source')
def setup_server(config): c = Connection(host=config['host'], user=config['user'], port=config['port'], connect_kwargs={'password': config['pass']}) setup_script_path, setup_script_name = make_server_setup_script( config, os.getcwd()) if config["user"] == 'root': remote_user_home = '/root' else: remote_user_home = f'/home/{config["user"]}' c.run(f'mkdir {remote_user_home}/.ssh') remote_script_path = os.path.join(remote_user_home, setup_script_name) c.put(config['ssh_key'], f'{remote_user_home}/.ssh/authorized_keys') c.put(setup_script_path, remote_script_path) c.run(f'chmod +x {remote_script_path}') c.sudo(remote_script_path, password=config['pass']) c.close() if 'new_ssh_port' in config: config['port'] = config['new_ssh_port'] return config
def send_elk(ctx, include_config_files=False, include_plugin_files=True, include_systemd_files=False): # Copy compiled file and sushi configuration to board # NOTE: note that the architecture folder name of the generated VST3 build (arm64-linux) is in fact wrong, # and it should really be "aarch64-linux". The fabric script copies it to the reight directory on the ELK board, # but the paths here might need to be updated if the cross compilation toolchain is updated to generate the # compiled plugin in the right directory. print('\nSending SourceSamler to board...') print('********************************\n') with Connection(host=host, connect_kwargs={'password': '******'}) as c: # Copy config and/or plugin files c.run('mkdir -p {}'.format(remote_dir)) c.run('mkdir -p {}'.format(remote_vst3_so_dir)) os.system( 'git log -1 --pretty=format:"%h %ci" > elk_platform/last_commit_info' ) config_files = [ ("elk_platform/source_sushi_config.json", remote_dir), ("elk_platform/source_sensei_config.json", remote_dir), ("elk_platform/html/index.html", remote_dir), ("elk_platform/html/sound_usage_log.html", remote_dir), ("elk_platform/html/simulator.html", remote_dir), ("elk_platform/requirements.txt", remote_dir), ("elk_platform/main", remote_dir), ("elk_platform/elk_ui_custom.py", remote_dir), ("elk_platform/source_states.py", remote_dir), ("elk_platform/helpers.py", remote_dir), ("elk_platform/freesound_interface.py", remote_dir), ("elk_platform/freesound_api_key.py", remote_dir), ("elk_platform/LiberationMono-Regular.ttf", remote_dir), ("elk_platform/FuturaHeavyfont.ttf", remote_dir), ("elk_platform/logo_oled_upf.png", remote_dir), ("elk_platform/logo_oled_ra.png", remote_dir), ("elk_platform/logo_oled_ra_b.png", remote_dir), ("elk_platform/logo_oled_fs.png", remote_dir), ("elk_platform/last_commit_info", remote_dir), ] plugin_files = [ ("elk_platform/metronome_plugin/Builds/ELKAudioOS/build/RitaAndAuroraMetronome.so", remote_dir + 'RitaAndAuroraMetronome.so'), ("SourceSampler/Builds/ELKAudioOS/build/SourceSampler.so", remote_dir + 'SourceSampler.so'), #("SourceSampler/Builds/ELKAudioOS/build/SourceSampler.vst3/Contents/arm64-linux/SourceSampler.so", remote_vst3_so_dir) ] files_to_send = [] if include_config_files: files_to_send += config_files if include_plugin_files: files_to_send += plugin_files for local_file, destination_dir in files_to_send: print('- Copying {0} to {1}'.format(local_file, destination_dir)) c.put(local_file, destination_dir) # Copy systemd files if include_systemd_files: print( '- Sending systemd config files and reloading systemd daemon') sudo_install(c, "elk_platform/systemd_config_files/sensei.service", "/lib/systemd/system/sensei.service", mode='0644') sudo_install(c, "elk_platform/systemd_config_files/sushi.service", "/lib/systemd/system/sushi.service", mode='0644') sudo_install(c, "elk_platform/systemd_config_files/source.service", "/lib/systemd/system/source.service", mode='0644') c.run('sudo systemctl daemon-reload') print( 'Now restarting "sensei", "sushi" and "source" services in board...' ) c.run('sudo systemctl restart sensei') time.sleep(1) c.run('sudo systemctl restart source') time.sleep(1) c.run('sudo systemctl restart sushi') print('DONE!') print('\n')
def ssh_con_fabric(test_vars): """Create an SSH connection to the controller.""" log = logging.getLogger("ssh_con_fabric") # SSH connection/client to the public IP. pub_client = Connection(test_vars["public_ip"], user=test_vars["controller_user"], connect_kwargs={ "key_filename": test_vars["ssh_priv_key"], }) # If the controller's IP is not the same as the public IP, then we are # using a jumpbox to get into the VNET containing the controller. In that # case, create an SSH tunnel before connecting to the controller. msg_con = "SSH connection to controller ({})".format( test_vars["controller_ip"]) if test_vars["public_ip"] != test_vars["controller_ip"]: tunnel_local_port = get_unused_local_port() tunnel_remote_port = 22 msg_con += " via jumpbox ({0}), local port {1}".format( test_vars["public_ip"], tunnel_local_port) log.debug("Opening {}".format(msg_con)) with pub_client.forward_local(local_port=tunnel_local_port, remote_port=tunnel_remote_port, remote_host=test_vars["controller_ip"]): client = Connection("127.0.0.1", user=test_vars["controller_user"], port=tunnel_local_port, connect_kwargs={ "key_filename": test_vars["ssh_priv_key"], }) client.open() yield client log.debug("{} closed".format(msg_con)) else: log.debug("Opening {}".format(msg_con)) pub_client.open() yield pub_client log.debug("Closing {}".format(msg_con)) pub_client.close()
def test(c): c = Connection('aw') result = c.run('uname -s', hide=True) msg = "Ran {0.command!r} on {0.connection.host}, got stdout:\n{0.stdout}" print(msg.format(result)) print(c.run('hostname'))
# * Create time : 2020-05-23 09:25 # * Filename : install.py # * Description : # ********************************************************** import sys from fabric import Connection import logging import hashlib import os logging.basicConfig(level=logging.INFO,filename='update.log',format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',datefmt='%a, %d %b %Y %H:%M:%S') c = Connection("[email protected]",connect_kwargs={"password":"******"}) cn = Connection("[email protected]",connect_kwargs={"password":"******"}) def view(): print("\t1.更新") print("\tq.退出") def linux_md5(filename): jarhash = hashlib.md5() f = open(filename,'rb') b = f.read() jarhash.update(b) f.close()
def backup(c): c = Connection('aw') """ backup data from aw mongo """ with c.cd('/var/www/anwen/db'): c.run('. ~/.zshrc && python3 db_in_out.py -o') c.run('tar czf aw_yaml.tar.gz data') with c.cd('/var/www/anwen/docs/shares'): c.run('tar czf aw_md.tar.gz *.md') with c.cd('/var/www/anwen/static/upload/'): c.run('tar czf upload.tar.gz img') print('download yaml:') with CD(os.path.join(os.getcwd(), 'db/')): c.get('/var/www/anwen/db/aw_yaml.tar.gz', 'aw_yaml.tar.gz') c.local('tar zxf aw_yaml.tar.gz') c.local('rm aw_yaml.tar.gz') print('download md:') with CD(os.path.join(os.getcwd(), 'docs/shares/')): c.get('/var/www/anwen/docs/shares/aw_md.tar.gz', 'aw_md.tar.gz') c.local('tar zxf aw_md.tar.gz') c.local('rm aw_md.tar.gz') print('download img:') return with CD(os.path.join(os.getcwd(), 'static/upload/')): c.get('/var/www/anwen/static/upload/upload.tar.gz', 'upload.tar.gz') c.local('tar zxf upload.tar.gz img') c.local('rm upload.tar.gz')
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import getpass from fabric import Connection, Config sudo_pass = getpass.getpass("input your password: ") c = Connection(host='arch-od-tracker04.beta1.fn', user='******', connect_kwargs={'password': sudo_pass}, config=Config(overrides={'sudo': { 'password': sudo_pass }})) c.sudo('whoami', hide='stderr') c.run('hostname')