Merge lp:~andreserl/maas/enlistment_ipmi_autodiscovery into lp:maas/trunk

Proposed by Andres Rodriguez on 2012-10-09
Status: Merged
Approved by: Andres Rodriguez on 2012-10-09
Approved revision: 1244
Merged at revision: 1243
Proposed branch: lp:~andreserl/maas/enlistment_ipmi_autodiscovery
Merge into: lp:maas/trunk
Diff against target: 198 lines (+173/-2)
1 file modified
contrib/preseeds_v2/enlist_userdata (+173/-2)
To merge this branch: bzr merge lp:~andreserl/maas/enlistment_ipmi_autodiscovery
Reviewer Review Type Date Requested Status
Francis J. Lacoste (community) 2012-10-09 Approve on 2012-10-09
Review via email: mp+128819@code.launchpad.net

Commit message

Enlistment IPMI autodiscovery

To post a comment you must log in.
1244. By Andres Rodriguez on 2012-10-09

comment line

Francis J. Lacoste (flacoste) wrote :

Looks ok to me.

review: Approve
Francis J. Lacoste (flacoste) wrote :

[16:56] <flacoste> roaksoax: line 17: it should be commented out :-)
[16:57] <roaksoax> flacoste: done
[17:00] <roaksoax> flacoste: crap something failed in another test I just run
[17:00] <flacoste> roaksoax: why the all-caps variable name at line 147?
[17:01] <roaksoax> flacoste: "globals"
[17:01] <flacoste> roaksoax: but they aren't globals?
[17:01] <roaksoax> flacoste: I know :) I didn't have the time to update that
[17:02] <roaksoax> flacoste: that's why the quotes :)
[17:03] <flacoste> roaksoax: looks ok to me, but i'm not a shell expert

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'contrib/preseeds_v2/enlist_userdata'
2--- contrib/preseeds_v2/enlist_userdata 2012-09-19 13:19:56 +0000
3+++ contrib/preseeds_v2/enlist_userdata 2012-10-09 20:59:20 +0000
4@@ -5,13 +5,184 @@
5
6 misc_bucket:
7 - &maas_enlist |
8+ #### IPMI setup ######
9+ # If IPMI network settings have been configured statically, you can
10+ # make them DHCP. If 'true', the IPMI network source will be changed
11+ # to DHCP.
12+ IPMI_CHANGE_STATIC_TO_DHCP="false"
13+
14+ # In certain hardware, the parameters for the ipmi_si kernel module
15+ # might need to be specified. If you wish to send parameters, uncomment
16+ # the following line.
17+ #IPMI_SI_PARAMS="type=kcs ports=0xca2"
18+
19+ TEMP_D=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX")
20+ IPMI_CONFIG_D="${TEMP_D}/ipmi.d"
21+ BIN_D="${TEMP_D}/bin"
22+ OUT_D="${TEMP_D}/out"
23+ PATH="$BIN_D:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
24+
25+ mkdir -p "$BIN_D" "$OUT_D" "$IPMI_CONFIG_D"
26+
27+ load_modules() {
28+ modprobe ipmi_msghandler
29+ modprobe ipmi_devintf
30+ modprobe ipmi_si ${IPMI_SI_PARAMS}
31+ }
32+
33+ add_bin() {
34+ cat > "${BIN_D}/$1"
35+ chmod "${2:-755}" "${BIN_D}/$1"
36+ }
37+ add_ipmi_config() {
38+ cat > "${IPMI_CONFIG_D}/$1"
39+ chmod "${2:-644}" "${IPMI_CONFIG_D}/$1"
40+ }
41+
42+ add_ipmi_config "01-user-privileges.ipmi" <<"END_IPMI_USER_PRIVILEGES"
43+ Section User3
44+ Enable_User Yes
45+ Lan_Enable_IPMI_Msgs Yes
46+ Lan_Privilege_Limit Administrator
47+ EndSection
48+ END_IPMI_USER_PRIVILEGES
49+
50+ add_ipmi_config "02-global-config.ipmi" <<"END_IPMI_CONFIG"
51+ Section Lan_Channel
52+ Volatile_Access_Mode Always_Available
53+ Volatile_Enable_User_Level_Auth Yes
54+ Volatile_Channel_Privilege_Limit Administrator
55+ Non_Volatile_Access_Mode Always_Available
56+ Non_Volatile_Enable_User_Level_Auth Yes
57+ Non_Volatile_Channel_Privilege_Limit Administrator
58+ EndSection
59+ END_IPMI_CONFIG
60+
61+ add_bin "maas-ipmi-autodetect" <<"END_MAAS_IPMI_AUTODETECT"
62+ #!/usr/bin/python
63+ import os
64+ import commands
65+ import re
66+ import string
67+ import random
68+ import time
69+ import json
70+
71+ def detect_ipmi():
72+ # TODO: Detection could be improved.
73+ (status, output) = commands.getstatusoutput('ipmi-locate')
74+ show_re = re.compile('(IPMI\ Version:) (\d\.\d)')
75+ res = show_re.search(output)
76+ if res == None:
77+ return (False, "")
78+ return (True, res.group(2))
79+
80+ def is_ipmi_dhcp():
81+ (status, output) = commands.getstatusoutput('bmc-config --checkout --key-pair="Lan_Conf:IP_Address_Source"')
82+ show_re = re.compile('IP_Address_Source\s+Use_DHCP')
83+ res = show_re.search(output)
84+ if res == None:
85+ return False
86+ return True
87+
88+ def set_ipmi_network_source(source):
89+ (status, output) = commands.getstatusoutput('bmc-config --commit --key-pair="Lan_Conf:IP_Address_Source=%s"' % source)
90+
91+ def get_ipmi_ip_address():
92+ (status, output) = commands.getstatusoutput('bmc-config --checkout --key-pair="Lan_Conf:IP_Address"')
93+ show_re = re.compile('([0-9]{1,3}[.]?){4}')
94+ res = show_re.search(output)
95+ return res.group()
96+
97+ def commit_ipmi_user_settings(user, password):
98+ (status, output) = commands.getstatusoutput('bmc-config --commit --key-pair="User3:Username=%s"' % user)
99+ (status, output) = commands.getstatusoutput('bmc-config --commit --key-pair="User3:Password=%s"' % password)
100+
101+ def commit_ipmi_settings(config):
102+ (status, output) = commands.getstatusoutput('bmc-config --commit --filename %s' % config)
103+
104+ def get_maas_power_settings(user, password, ipaddress):
105+ return "%s,%s,%s" % (user, password, ipaddress)
106+
107+ def get_maas_power_settings_json(user, password, ipaddress):
108+ power_params = {"power_address": ipaddress, "power_pass": password, "power_user": user}
109+ return json.dumps(power_params)
110+
111+ def generate_random_password(min=8,max=15):
112+ length=random.randint(min,max)
113+ letters=string.ascii_letters+string.digits
114+ return ''.join([random.choice(letters) for _ in range(length)])
115+
116+ def main():
117+
118+ import argparse
119+
120+ parser = argparse.ArgumentParser(
121+ description='send config file to modify IPMI settings with')
122+ parser.add_argument("--configdir", metavar="folder",
123+ help="specify config file directory", default=None)
124+ parser.add_argument("--dhcp-if-static", action="store_true",
125+ dest="dhcp", help="set network source to DHCP if Static", default=False)
126+ parser.add_argument("--commission-creds", action="store_true",
127+ dest="commission_creds", help="Create IPMI temporary credentials", default=False)
128+
129+ args = parser.parse_args()
130+
131+ # Check whether IPMI exists or not.
132+ (status, ipmi_version) = detect_ipmi()
133+ if status != True:
134+ # if False, then failed to detect ipmi
135+ exit(1)
136+
137+ # Check whether IPMI is being set to DHCP. If it is not, and
138+ # '--dhcp-if-static' has been passed, Set it to IPMI to DHCP.
139+ if not is_ipmi_dhcp() and args.dhcp:
140+ set_ipmi_network_source("Use_DHCP")
141+ # allow IPMI 60 seconds to obtain an IP address
142+ time.sleep(60)
143+
144+ # create user/pass
145+ if args.commission_creds:
146+ IPMI_MAAS_USER="maas-commissioning"
147+ else:
148+ IPMI_MAAS_USER="maas"
149+ IPMI_MAAS_PASSWORD=generate_random_password()
150+
151+ # Configure IPMI user/password
152+ commit_ipmi_user_settings(IPMI_MAAS_USER, IPMI_MAAS_PASSWORD)
153+
154+ # Commit other IPMI settings
155+ if args.configdir:
156+ for file in os.listdir(args.configdir):
157+ commit_ipmi_settings(os.path.join(args.configdir, file))
158+
159+ # get the IP address
160+ IPMI_IP_ADDRESS = get_ipmi_ip_address()
161+
162+ if args.commission_creds:
163+ print get_maas_power_settings_json(IPMI_MAAS_USER, IPMI_MAAS_PASSWORD, IPMI_IP_ADDRESS)
164+ else:
165+ print get_maas_power_settings(IPMI_MAAS_USER, IPMI_MAAS_PASSWORD, IPMI_IP_ADDRESS)
166+
167+ if __name__ == '__main__':
168+ main()
169+ END_MAAS_IPMI_AUTODETECT
170+
171 # we could obtain the interface that booted from the kernel cmdline
172 # thanks to 'IPAPPEND' (http://www.syslinux.org/wiki/index.php/SYSLINUX)
173 url="{{server_url}}"
174 host=""
175 ip=$(ifconfig eth0 | awk '$1 == "inet" { sub("addr:","",$2); print $2; }') &&
176 [ -n "${ip}" ] && host=$(dig +short -x $ip) && host=${host%.}
177- maas-enlist --serverurl "$url" ${host:+--hostname "${host}"} >/tmp/enlist.out
178+ # load ipmi modules
179+ load_modules
180+ pargs=""
181+ if $IPMI_CHANGE_STATIC_TO_DHCP; then
182+ pargs="--dhcp-if-static"
183+ fi
184+ power_params=$(maas-ipmi-autodetect --configdir "$IPMI_CONFIG_D" ${pargs} --commission-creds) &&
185+ [ -n "${power_params}" ] && power_params=${power_params%.} && power_type=ipmi
186+ maas-enlist --serverurl "$url" ${host:+--hostname "${host}"} ${power_params:+--power-params "${power_params}" --power-type "${power_type}"}>/tmp/enlist.out
187 if [ $? -eq 0 ]; then
188 msg="successfully enlisted to '$url'"
189 [ -n "$host" ] && msg="$msg with hostname '$host'" ||
190@@ -43,7 +214,7 @@
191 fi
192 poweroff
193
194-packages: [ maas-enlist ]
195+packages: [ maas-enlist, freeipmi-tools ]
196 output: {all: '| tee -a /var/log/cloud-init-output.log'}
197 runcmd:
198 - [ sh, -c, *maas_enlist ]