refactoring metal3 code
[icn.git] / deploy / metal3 / scripts / 01_metal3.sh
1 #!/bin/bash
2 set +ex
3
4 LIBDIR="$(dirname "$(dirname "$(dirname "$PWD")")")"
5
6 eval "$(go env)"
7
8 source $LIBDIR/env/lib/common.sh
9
10 if [[ $EUID -ne 0 ]]; then
11     echo "This script must be run as root"
12     exit 1
13 fi
14
15 IMAGE_URL=http://172.22.0.1/images/${BM_IMAGE}
16 IMAGE_CHECKSUM=http://172.22.0.1/images/${BM_IMAGE}.md5sum
17
18 function get_default_inteface_ipaddress {
19     local _ip=$1
20     local _default_interface=$(awk '$2 == 00000000 { print $1 }' /proc/net/route)
21     local _ipv4address=$(ip addr show dev $_default_interface | awk '$1 == "inet" { sub("/.*", "", $2); print $2 }')
22     eval $_ip="'$_ipv4address'"
23 }
24
25 function create_ssh_key {
26     #ssh key for compute node to communicate back to bootstrap server
27     mkdir -p $BUILD_DIR/ssh_key
28     ssh-keygen -C "compute.icn.akraino.lfedge.org" -f $BUILD_DIR/ssh_key/id_rsa
29     cat $BUILD_DIR/ssh_key/id_rsa.pub >> $HOME/.ssh/authorized_keys
30 }
31
32 function set_compute_key {
33     _SSH_LOCAL_KEY=$(cat $BUILD_DIR/ssh_key/id_rsa)
34     cat << EOF
35 write_files:
36 - path: /opt/ssh_id_rsa
37     owner: root:root
38     permissions: '0600'
39     content: |
40     $_SSH_LOCAL_KEY
41 EOF
42 }
43
44 function deprovision_compute_node {
45     name="$1"
46     kubectl patch baremetalhost $name -n metal3 --type merge \
47     -p '{"spec":{"image":{"url":"","checksum":""}}}'
48 }
49
50 function set_compute_ssh_config {
51     get_default_inteface_ipaddress default_addr
52     cat << EOF
53 - path: /root/.ssh/config
54     owner: root:root
55     permissions: '0600'
56     content: |
57     Host bootstrapmachine $default_addr
58     HostName $default_addr
59     IdentityFile /opt/ssh_id_rsa
60     User $USER
61 - path: /etc/apt/sources.list
62     owner: root:root
63     permissions: '0665'
64     content: |
65     deb [trusted=yes] ssh://$USER@$default_addr:$LOCAL_APT_REPO ./
66 EOF
67 }
68
69 function create_userdata {
70     name="$1"
71     COMPUTE_NODE_FQDN="$name.akraino.icn.org"
72     printf "#cloud-config\n" >  $name-userdata.yaml
73     if [ -n "$COMPUTE_NODE_PASSWORD" ]; then
74     printf "password: ""%s" "$COMPUTE_NODE_PASSWORD" >>  $name-userdata.yaml
75     printf "\nchpasswd: {expire: False}\n" >>  $name-userdata.yaml
76     printf "ssh_pwauth: True\n" >>  $name-userdata.yaml
77     fi
78
79     if [ -n "$COMPUTE_NODE_FQDN" ]; then
80     printf "fqdn: ""%s" "$COMPUTE_NODE_FQDN" >>  $name-userdata.yaml
81     printf "\n" >>  $name-userdata.yaml
82     fi
83     printf "disable_root: false\n" >>  $name-userdata.yaml
84     printf "ssh_authorized_keys:\n  - " >>  $name-userdata.yaml
85
86     if [ ! -f $HOME/.ssh/id_rsa.pub ]; then
87     yes y | ssh-keygen -t rsa -N "" -f $HOME/.ssh/id_rsa
88     fi
89
90     cat $HOME/.ssh/id_rsa.pub >>  $name-userdata.yaml
91     network_config_files >> $name-userdata.yaml
92     printf "\n" >>  $name-userdata.yaml
93 }
94
95 function launch_baremetal_operator {
96     if [ ! -d $GOPATH/src/github.com/metal3-io/baremetal-operator ]; then
97         go get github.com/metal3-io/baremetal-operator
98         git checkout 3d40caa29dce82878d83aeb7f8dab4dc4a856160
99     fi
100
101     pushd $GOPATH/src/github.com/metal3-io/baremetal-operator
102     make deploy
103     popd
104 }
105
106 function network_config_files {
107     cat << 'EOF'
108 write_files:
109 - path: /opt/ironic_net.sh
110   owner: root:root
111   permissions: '0777'
112   content: |
113     #!/usr/bin/env bash
114     set -xe
115     for intf in /sys/class/net/*; do
116         sudo ifconfig `basename $intf` up
117         sudo dhclient -nw `basename $intf`
118     done
119 EOF
120 cat << EOF
121 - path: /opt/user_net.sh
122   owner: root:root
123   permissions: '0777'
124   content: |
125     #!/usr/bin/env bash
126     set -xe
127     route add default gw $PROVIDER_NETWORK_GATEWAY
128     sed -i -e 's/^#DNS=.*/DNS=$PROVIDER_NETWORK_DNS/g' /etc/systemd/resolved.conf
129     systemctl daemon-reload
130     systemctl restart systemd-resolved
131 runcmd:
132  - [ /opt/ironic_net.sh ]
133  - [ /opt/user_net.sh ]
134 EOF
135 }
136
137 function apply_userdata_credential {
138     name="$1"
139     cat <<EOF > ./$name-user-data-credential.yaml
140 apiVersion: v1
141 data:
142   userData: $(base64 -w 0 $name-userdata.yaml)
143 kind: Secret
144 metadata:
145   name: $name-user-data
146   namespace: metal3
147 type: Opaque
148 EOF
149     kubectl apply -n metal3 -f $name-user-data-credential.yaml
150 }
151
152 function make_bm_hosts {
153     while read -r name username password address; do
154         create_userdata $name
155         apply_userdata_credential $name
156
157         go run $GOPATH/src/github.com/metal3-io/baremetal-operator/cmd/make-bm-worker/main.go \
158            -address "ipmi://$address" \
159            -password "$password" \
160            -user "$username" \
161            "$name" > $name-bm-node.yaml
162
163         printf "  image:" >> $name-bm-node.yaml
164         printf "\n    url: ""%s" "$IMAGE_URL" >> $name-bm-node.yaml
165         printf "\n    checksum: ""%s" "$IMAGE_CHECKSUM" >> $name-bm-node.yaml
166         printf "\n  userData:" >> $name-bm-node.yaml
167         printf "\n    name: ""%s" "$name""-user-data" >> $name-bm-node.yaml
168         printf "\n    namespace: metal3\n" >> $name-bm-node.yaml
169         kubectl apply -f $name-bm-node.yaml -n metal3
170     done
171 }
172
173 function configure_nodes {
174     if [ ! -d $IRONIC_DATA_DIR ]; then
175         mkdir -p $IRONIC_DATA_DIR
176     fi
177
178     #make sure nodes.json file in /opt/ironic/ are configured
179     if [ ! -f $IRONIC_DATA_DIR/nodes.json ]; then
180         cp $PWD/nodes.json.sample $IRONIC_DATA_DIR/nodes.json
181     fi
182 }
183
184 function remove_bm_hosts {
185     while read -r name username password address; do
186         deprovision_compute_node $name
187     done
188 }
189
190 function cleanup {
191     while read -r name username password address; do
192         kubectl delete bmh $name -n metal3
193         kubectl delete secrets $name-bmc-secret -n metal3
194         kubectl delete secrets $name-user-data -n metal3
195     done
196 }
197
198 function clean_all {
199     list_nodes | cleanup
200 }
201
202 function apply_bm_hosts {
203     list_nodes | make_bm_hosts
204 }
205
206 function deprovision_all_hosts {
207     list_nodes | remove_bm_hosts
208 }
209
210 if [ "$1" == "launch" ]; then
211     launch_baremetal_operator
212     exit 0
213 fi
214
215 if [ "$1" == "deprovision" ]; then
216     configure_nodes
217     deprovision_all_hosts
218     exit 0
219 fi
220
221 if [ "$1" == "provision" ]; then
222     configure_nodes
223     apply_bm_hosts
224     exit 0
225 fi
226
227 if [ "$1" == "clean" ]; then
228     configure_nodes
229     clean_all
230     exit 0
231 fi
232
233 echo "Usage: metal3.sh"
234 echo "launch      - Launch the metal3 operator"
235 echo "provision   - provision baremetal node as specified in common.sh"
236 echo "deprovision - deprovision baremetal node as specified in common.sh"
237 echo "clean       - clean all the resources"
238 exit 1
239
240 #Following code is tested for the offline mode
241 #Will be intergrated for the offline mode for ICNi v.0.1.0 beta
242 #create_ssh_key
243 #create_userdata
244 #set_compute_key
245 #set_compute_ssh_config