HC Test: re-enable NSH tests, minor fixes
[csit.git] / resources / tools / scripts / topo_installation.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2016 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:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15
16 """This script provides copy and installation of VPP build deb packages.
17    As destinations are used all DUT nodes from the topology file."""
18
19 import sys
20 import argparse
21 from yaml import load
22
23 from resources.libraries.python.ssh import SSH
24
25
26 def ssh_no_error(ssh, cmd, sudo=False):
27     """Execute a command over ssh channel, and log and exit if the command
28     fails.
29
30     :param ssh: SSH() object connected to a node.
31     :param cmd: Command line to execute on remote node.
32     :type ssh: SSH() object
33     :type cmd: str
34     :return: stdout from the SSH command.
35     :rtype: str
36     """
37
38     if sudo:
39         ret, stdo, stde = ssh.exec_command_sudo(cmd, timeout=60)
40     else:
41         ret, stdo, stde = ssh.exec_command(cmd, timeout=60)
42
43     if ret != 0:
44         print 'Command execution failed: "{}"'.format(cmd)
45         print 'stdout: {0}'.format(stdo)
46         print 'stderr: {0}'.format(stde)
47         raise RuntimeError('Unexpected ssh command failure')
48
49     return stdo
50
51
52 def ssh_ignore_error(ssh, cmd, sudo=False):
53     """Execute a command over ssh channel, ignore errors.
54
55     :param ssh: SSH() object connected to a node.
56     :param cmd: Command line to execute on remote node.
57     :type ssh: SSH() object
58     :type cmd: str
59     :return: stdout from the SSH command.
60     :rtype: str
61     """
62
63     if sudo:
64         ret, stdo, stde = ssh.exec_command_sudo(cmd)
65     else:
66         ret, stdo, stde = ssh.exec_command(cmd)
67
68     if ret != 0:
69         print 'Command execution failed: "{}"'.format(cmd)
70         print 'stdout: {0}'.format(stdo)
71         print 'stderr: {0}'.format(stde)
72
73     return stdo
74
75
76 def main():
77     """Copy and installation of VPP packages."""
78
79     parser = argparse.ArgumentParser()
80     parser.add_argument("-t", "--topo", required=True,
81                         help="Topology file")
82     parser.add_argument("-d", "--directory", required=True,
83                         help="Installation directory")
84     parser.add_argument("-p", "--packages", required=False, nargs='+',
85                         help="Packages paths to copy")
86     parser.add_argument("-c", "--cancel", help="Cancel installation",
87                         action="store_true")
88     parser.add_argument("-hc", "--honeycomb", help="Include Honeycomb package.",
89                         required=False, default=False)
90
91     args = parser.parse_args()
92     topology_file = args.topo
93     packages = args.packages
94     install_dir = args.directory
95     cancel_installation = args.cancel
96     honeycomb = args.honeycomb
97
98     work_file = open(topology_file)
99     topology = load(work_file.read())['nodes']
100
101     def fix_interrupted(package):
102         """If there are interrupted installations, clean them up."""
103
104         cmd = "dpkg -l | grep {0}".format(package)
105         ret, _, _ = ssh.exec_command(cmd)
106         if ret == 0:
107             # Try to fix interrupted installations
108             cmd = 'dpkg --configure -a'
109             stdout = ssh_no_error(ssh, cmd, sudo=True)
110             print "###TI {}".format(stdout)
111             # Try to remove installed packages
112             cmd = 'apt-get purge -y "{0}.*"'.format(package)
113             stdout = ssh_no_error(ssh, cmd, sudo=True)
114             print "###TI {}".format(stdout)
115
116     ssh = SSH()
117     for node in topology:
118         if topology[node]['type'] == "DUT":
119             print "###TI host: {}".format(topology[node]['host'])
120             ssh.connect(topology[node])
121
122             if cancel_installation:
123                 # Remove installation directory on DUT
124                 cmd = "rm -r {}".format(install_dir)
125                 stdout = ssh_ignore_error(ssh, cmd)
126                 print "###TI {}".format(stdout)
127
128                 if honeycomb:
129                     fix_interrupted("honeycomb")
130                     # remove HC logs
131                     cmd = "rm -rf /var/log/honeycomb"
132                     stdout = ssh_ignore_error(ssh, cmd, sudo=True)
133                     print "###TI {}".format(stdout)
134                 fix_interrupted("vpp")
135
136             else:
137                 # Create installation directory on DUT
138                 cmd = "rm -r {0}; mkdir {0}".format(install_dir)
139                 stdout = ssh_no_error(ssh, cmd)
140                 print "###TI {}".format(stdout)
141
142                 if honeycomb:
143                     smd = "ls ~/honeycomb | grep .deb"
144                     stdout = ssh_ignore_error(ssh, smd)
145                     if "honeycomb" in stdout:
146                         # If custom honeycomb packages exist, use them
147                         cmd = "cp ~/honeycomb/*.deb {0}".format(install_dir)
148                         stdout = ssh_no_error(ssh, cmd)
149                         print "###TI {}".format(stdout)
150                     else:
151                         # Copy packages from local path to installation dir
152                         for deb in packages:
153                             print "###TI scp: {}".format(deb)
154                             ssh.scp(local_path=deb, remote_path=install_dir)
155                 else:
156                     # Copy packages from local path to installation dir
157                     for deb in packages:
158                         print "###TI scp: {}".format(deb)
159                         ssh.scp(local_path=deb, remote_path=install_dir)
160
161                 if honeycomb:
162                     fix_interrupted("honeycomb")
163                 fix_interrupted("vpp")
164
165                 # Installation of deb packages
166                 cmd = "dpkg -i --force-all {}/*.deb".format(install_dir)
167                 stdout = ssh_no_error(ssh, cmd, sudo=True)
168                 print "###TI {}".format(stdout)
169
170 if __name__ == "__main__":
171     sys.exit(main())