def test_get_exit_code(docker_env): gateway_ip, gateway_port = docker_env.get_host_ip_port('gateway') gateway_session = SSHSession(host=gateway_ip, port=gateway_port, username='******', password='******').open() assert gateway_session.get_exit_code('ls') == 0 assert gateway_session.get_exit_code('dummy commmand') == 127
def change_link(*args, **kwargs): target_link = kwargs.get('link', 'T33L') version = kwargs.get('version') if kwargs.get('server').startswith('192'): gateway_session = SSHSession('173.36.203.62', 'wbxbuilds', password='******').open() print("Connected to sshlogin server.") remote_session = gateway_session.get_remote_session( kwargs.get('server'), kwargs.get('user', 'shuqli'), password=kwargs.get('pass', 'wbx@Aa$hfcm')) print(f"Connected to target server {kwargs.get('server')}.") else: remote_session = SSHSession(kwargs.get('server'), kwargs.get('user', 'wbxroot'), password=kwargs.get('pass', 'wbx@AaR00t')).open() print("Starting to change link ...") remote_session.get_cmd_output( "cd /www/htdocs/client; sudo rm -f {target_link}; sudo ln -sf " "`ls -lrt|grep WBXclient-{version}|grep ^d|tail -n1|awk '{{" "print $NF}}'` {target_link}; sudo chown -h nobody.nobody " "{target_link};".format(version=version, target_link=target_link)) ret = remote_session.get_exit_code( f"test -e /www/htdocs/client/{target_link}") print(ret) if ret == 0: return True else: return False
def test_run_cmd_interrupt_remote_command(docker_env, monkeypatch, caplog): caplog.set_level(logging.DEBUG) """Test behavior of run_cmd when user hit Contrl-C while a command is being executed remotely""" gateway_ip, gateway_port = docker_env.get_host_ip_port('gateway') gateway_session = SSHSession(host=gateway_ip, port=gateway_port, username='******', password='******').open() mock_input = '__builtin__.raw_input' if util.PY2 else 'builtins.input' # 1. if user request to interrupt remote command with pytest.raises(KeyboardInterrupt): # raise KeyboardInterrupt while command is running with mock.patch('select.select', side_effect=KeyboardInterrupt('Fake Ctrl-C')): # request to terminate remote command simulating the user entering "Y" in the terminal monkeypatch.setattr(mock_input, lambda x: "Y") gateway_session.run_cmd('sleep 30') # check command is no longer running on remote host assert gateway_session.get_exit_code( 'ps aux | grep -v grep | grep "sleep 30"') == 1 # 2. user request to NOT interrupt remote command with pytest.raises(KeyboardInterrupt): # raise KeyboardInterrupt while command is running with mock.patch('select.select', side_effect=KeyboardInterrupt('Fake Ctrl-C')): # request to terminate remote command simulating the user entering "N" in the terminal monkeypatch.setattr(mock_input, lambda x: "N") gateway_session.run_cmd('sleep 40') # check command is still running on remote host assert gateway_session.get_exit_code( 'ps aux | grep -v grep | grep "sleep 40"') == 0 # 3. user press enter (default value of util.yes_no_query used), we expect remote command to be stopped with pytest.raises(KeyboardInterrupt): # raise KeyboardInterrupt while command is running with mock.patch('select.select', side_effect=KeyboardInterrupt('Fake Ctrl-C')): # send empty string simulating the user pressing enter in the terminal monkeypatch.setattr(mock_input, lambda x: '') gateway_session.run_cmd('sleep 50') # check command is no longer running on remote host assert gateway_session.get_exit_code( 'ps aux | grep -v grep | grep "sleep 50"') == 1 # 4. user press Contrl-C twice, check remote command is still running with pytest.raises(KeyboardInterrupt): # raise KeyboardInterrupt while command is running with mock.patch('select.select', side_effect=KeyboardInterrupt('Fake Ctrl-C')): # user press a second time Contrl-C with mock.patch(mock_input, side_effect=KeyboardInterrupt('2nd Fake Ctrl-C')): gateway_session.run_cmd('sleep 60') # check command is still running on remote host assert gateway_session.get_exit_code( 'ps aux | grep -v grep | grep "sleep 60"') == 0 # 5. user press Contrl-C once but take time to answer if remote must be closed or not, and channel is closed # so we cannot terminate remote command but remote command finished its execution with pytest.raises(KeyboardInterrupt): # raise KeyboardInterrupt while command is running with mock.patch('select.select', side_effect=KeyboardInterrupt('Fake Ctrl-C')): # request to terminate remote command simulating the user entering "Y" in the terminal # but user answered after 4s while command finished after 3s so underline channel is already closed # and command still successfully run monkeypatch.setattr(mock_input, lambda x: time.sleep(4) or "Y") gateway_session.run_cmd('sleep 3') assert 'Remote command execution already finished with exit code' in caplog.text # 6. user press Contrl-C once but take time to answer if remote must be closed or not, and channel is closed # so we cannot terminate remote command and channel does't not have more information about remote command execution with pytest.raises(KeyboardInterrupt): # raise KeyboardInterrupt while command is running with mock.patch('select.select', side_effect=KeyboardInterrupt('Fake Ctrl-C')): # request to terminate remote command simulating the user entering "Y" in the terminal # but user answered after 4s while command finished after 3s so underline channel is already closed monkeypatch.setattr('paramiko.channel.Channel.recv_exit_status', lambda x: -1) gateway_session.run_cmd('sleep 3') assert 'Unable to terminate remote command because channel is closed.' in caplog.text
def action_job_with_shell(action, item, env, *args, **kwargs): build = kwargs.get('build') server = kwargs.get('server') action = 'install' if action == 'upgrade' else action downloadonly = kwargs.get('downloadonly', False) try: version = re.search('.*-(\d+.\d+.\d+)', build.split()[0]).group(1) except: version = '39' if kwargs.get('server').startswith('192'): gateway_session = SSHSession('173.36.203.62', 'wbxbuilds', password='******').open() print("Connected to sshlogin server.") remote_session = gateway_session.get_remote_session( server, kwargs.get('user', 'shuqli'), password=kwargs.get('pass', 'wbx@Aa$hfcm')) else: remote_session = SSHSession(server, kwargs.get('user', 'wbxroot'), password=kwargs.get('pass', 'wbx@AaR00t')).open() print(f"Connected to target server {kwargs.get('server')}.") if item == 'client': print(f"Starting {action} {item} ...") exit_code = remote_session.get_exit_code( f"sudo yum clean all;sudo yum erase -y `rpm -qa|grep -E" f" 'WBXclient|WBXmsi'`;sudo yum install -y {build}") if exit_code == 0: if downloadonly: print("Downloaded success.") return True else: print("Starting to change link ...") if change_link(env, server=server, version=version, link='T33L'): return True else: print("Changed Link Failed.") return False else: print("Downgraded failed.") return False else: print(f"Starting {action} {item} ...") if downloadonly: remote_session.get_exit_code( r"sudo find /home -name 'WBX*.rpm' -exec rm -f {} \;") exit_code = remote_session.get_exit_code( f"sudo yum clean all;sudo yum {action} -y {build} --downloadonly --downloaddir=." ) if exit_code == 0: return True else: return False else: exit_code = remote_session.get_exit_code( f"sudo yum clean all;sudo yum {action} -y {build}") remote_session.get_exit_code( r"sudo find /home -name 'WBX*.rpm' -exec rm -f {} \;") if exit_code == 0: print(f"Starting to restart service ...") ret = remote_session.get_exit_code( f"sudo service wbxd stop;sudo service wbxd start") if ret == 0: return True else: return False else: print(f"{action} failed.") return False