3 # Copyright (c) 2017 Cisco and/or its affiliates.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 """This script provides copy and load of Docker container images.
17 As destinations are used all DUT nodes from the topology file."""
23 from resources.libraries.python.ssh import SSH
26 def ssh_no_error(ssh, cmd, sudo=False):
27 """Execute a command over ssh channel, and log and exit if the command
30 :param ssh: SSH() object connected to a node.
31 :param cmd: Command line to execute on remote node.
32 :param sudo: Run command with sudo privileges.
33 :type ssh: SSH() object
36 :returns: stdout from the SSH command.
38 :raises RuntimeError: In case of unexpected ssh command failure
41 ret, stdo, stde = ssh.exec_command_sudo(cmd, timeout=60)
43 ret, stdo, stde = ssh.exec_command(cmd, timeout=60)
46 print('Command execution failed: "{}"'.format(cmd))
47 print('stdout: {0}'.format(stdo))
48 print('stderr: {0}'.format(stde))
49 raise RuntimeError('Unexpected ssh command failure')
54 def ssh_ignore_error(ssh, cmd, sudo=False):
55 """Execute a command over ssh channel, ignore errors.
57 :param ssh: SSH() object connected to a node.
58 :param cmd: Command line to execute on remote node.
59 :param sudo: Run command with sudo privileges.
60 :type ssh: SSH() object
63 :returns: stdout from the SSH command.
67 ret, stdo, stde = ssh.exec_command_sudo(cmd)
69 ret, stdo, stde = ssh.exec_command(cmd)
72 print('Command execution failed: "{}"'.format(cmd))
73 print('stdout: {0}'.format(stdo))
74 print('stderr: {0}'.format(stde))
80 """Copy and load of Docker image."""
81 parser = argparse.ArgumentParser()
82 parser.add_argument("-t", "--topo", required=True,
84 parser.add_argument("-d", "--directory", required=True,
85 help="Destination directory")
86 parser.add_argument("-i", "--images", required=False, nargs='+',
87 help="Images paths to copy")
88 parser.add_argument("-c", "--cancel", help="Cancel all",
91 args = parser.parse_args()
92 topology_file = args.topo
94 directory = args.directory
95 cancel_all = args.cancel
97 work_file = open(topology_file)
98 topology = load(work_file.read())['nodes']
101 for node in topology:
102 if topology[node]['type'] == "DUT":
103 print("###TI host: {host}".format(host=topology[node]['host']))
104 ssh.connect(topology[node])
107 # Remove destination directory on DUT
108 cmd = "rm -r {directory}".format(directory=directory)
109 stdout = ssh_ignore_error(ssh, cmd)
110 print("###TI {stdout}".format(stdout=stdout))
113 # Create installation directory on DUT
114 cmd = "rm -r {directory}; mkdir {directory}"\
115 .format(directory=directory)
116 stdout = ssh_no_error(ssh, cmd)
117 print("###TI {stdout}".format(stdout=stdout))
119 # Copy images from local path to destination dir
121 print("###TI scp: {}".format(image))
122 ssh.scp(local_path=image, remote_path=directory)
124 # Load image to Docker.
125 cmd = "for f in {directory}/*.tar.gz; do "\
126 "sudo docker load -i $f; done".format(directory=directory)
127 stdout = ssh_no_error(ssh, cmd)
128 print("###TI {}".format(stdout))
130 # Remove <none> images from Docker.
131 cmd = "docker rmi $(sudo docker images -f 'dangling=true' -q)"
132 stdout = ssh_ignore_error(ssh, cmd, sudo=True)
133 print("###TI {}".format(stdout))
136 if __name__ == "__main__":