Merge bootstack-ops:jjo-add-ipmiconsole_py into bootstack-ops:master

Proposed by JuanJo Ciarlante
Status: Merged
Approved by: James Hebden
Approved revision: 1089ee08e07739a75185e753b7ae7ef346a63e2c
Merged at revision: d5585dbfb7a290fcfc8ae65d8a8e2212f9f517f5
Proposed branch: bootstack-ops:jjo-add-ipmiconsole_py
Merge into: bootstack-ops:master
Diff against target: 113 lines (+99/-1)
2 files modified
bootstack-ops/ipmiconsole.py (+98/-0)
bootstack-ops/juju_bundle_export.py (+1/-1)
Reviewer Review Type Date Requested Status
Jill Rouleau (community) lgtm Approve
Review via email: mp+322149@code.launchpad.net

Commit message

[jjo] add ipmiconsole.py, fix juju_bundle_export.py symlink

Description of the change

[jjo] add ipmiconsole.py, fix juju_bundle_export.py symlink

To post a comment you must log in.
Revision history for this message
Jill Rouleau (jillrouleau) :
review: Approve (lgtm)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/bootstack-ops/ipmiconsole.py b/bootstack-ops/ipmiconsole.py
0new file mode 1006440new file mode 100644
index 0000000..0c895f6
--- /dev/null
+++ b/bootstack-ops/ipmiconsole.py
@@ -0,0 +1,98 @@
1#!/usr/bin/env python3
2# ipmiconsole.py: run ipmitool sol activate from maas data via maas CLI
3#
4# Author: JuanJo Ciarlante <jjo@canonical.com>
5# License: GPLv3+
6#
7# E.g. usage:
8# ./ipmiconsole.py foo-c-001
9# ./ipmiconsole.py --nodes_list
10#
11# To all nodes with passed prefix for "login:" via ipmi SOL:
12# ./ipmiconsole.py --login_test foo-c-
13#
14import argparse
15import os
16import subprocess
17import sys
18import json
19import pexpect
20import logging
21
22
23def parse_args():
24 parser = argparse.ArgumentParser(
25 description='Connect to node via IPMI console')
26 parser.add_argument('hostname', nargs='?',
27 help='maas hostname or prefix')
28 parser.add_argument('-u', dest='maas_user', nargs='?', default='maas',
29 help='maas user (if not "maas")')
30 parser.add_argument('--nodes_list', action='store_true', default=False,
31 help='list nodes prefixed by hostname and exit')
32 parser.add_argument('--login_test', action='store_true', default=False,
33 help='test "login:" prompt nodes prefixed by hostname')
34 return parser.parse_args(sys.argv[1:])
35
36
37def get_power_params(args, system_id):
38 return json.loads(subprocess.check_output(
39 ['maas', args.maas_user, 'node',
40 'power-parameters', system_id]).decode())
41
42
43def get_ipmitool_sol(args, system_id):
44 cmd = ('ipmitool -H {power_address} -U {power_user} -P {power_pass} '
45 '-I lanplus sol activate').format(**get_power_params(args,
46 system_id))
47 return cmd
48
49
50def get_node_ids(args, exact=False):
51 maas_cmd = ['maas', args.maas_user, 'nodes', 'read']
52 if exact and args.hostname:
53 maas_cmd.append('hostname={}'.format(args.hostname))
54 logger.debug('maas_cmd: {}'.format(maas_cmd))
55 maas_nodes = json.loads(subprocess.check_output(maas_cmd).decode())
56 prefix = args.hostname if args.hostname else ""
57 node_ids = [(node['hostname'], node['system_id']) for node in maas_nodes
58 if node['hostname'].startswith(prefix)]
59 return [node_id for node_id in sorted(node_ids, key=lambda x: x[0])]
60
61
62def main():
63 args = parse_args()
64 if args.nodes_list:
65 for (node, id) in get_node_ids(args):
66 print("{:32} {}".format(node, id))
67 sys.exit(0)
68 if args.login_test:
69 for (node, id) in get_node_ids(args):
70 cmd = get_ipmitool_sol(args, id)
71 expect_conn = pexpect.spawn(cmd)
72 try:
73 expect_conn.expect('SOL Session operational', timeout=5)
74 expect_conn.sendline("")
75 expect_conn.expect('login:', timeout=5)
76 print('PASS: {}'.format(node))
77 except (pexpect.exceptions.TIMEOUT, pexpect.exceptions.EOF) as e:
78 print('FAIL: {} - Error: {}'.format(node,
79 str(e).split('\n')[0]))
80 finally:
81 expect_conn.close(force=True)
82 sys.exit(0)
83
84 if not args.hostname:
85 raise ValueError("missing hostname")
86
87 node, system_id = get_node_ids(args, exact=True)[0]
88 cmd = get_ipmitool_sol(args, system_id)
89 logger.debug("node: {}, system_id: {}, cmd: {}".format(
90 node, system_id, cmd))
91 os.system(cmd)
92
93logging.basicConfig(level=logging.DEBUG)
94logger = logging.getLogger()
95
96
97if __name__ == '__main__':
98 main()
diff --git a/bootstack-ops/juju_bundle_export.py b/bootstack-ops/juju_bundle_export.py
index 25ff6d3..c90db6c 120000
--- a/bootstack-ops/juju_bundle_export.py
+++ b/bootstack-ops/juju_bundle_export.py
@@ -1 +1 @@
1../ops-bundle/common/juju_bundle_export.py
2\ No newline at end of file1\ No newline at end of file
2../ops-bundle/scripts/juju_bundle_export.py
3\ No newline at end of file3\ No newline at end of file

Subscribers

People subscribed via source and target branches

to all changes: