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

Subscribers

People subscribed via source and target branches

to all changes: