b922a90a55502b8ee97e0b96320f5eb7df019def
[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         rm -rf $GOPATH/src/github.com/metal3-io/baremetal-operator
98     fi
99
100     docker pull integratedcloudnative/baremetal-operator:v1.0-icn
101     docker tag integratedcloudnative/baremetal-operator:v1.0-icn \
102         quay.io/metal3-io/baremetal-operator:master
103
104     mkdir -p $GOPATH/src/github.com/metal3-io
105     pushd $GOPATH/src/github.com/metal3-io
106     git clone --single-branch --branch v1.0-icn \
107         https://github.com/akraino-icn/baremetal-operator.git
108     kubectl apply -f baremetal-operator/deploy/namespace/namespace.yaml
109     kubectl apply -f baremetal-operator/deploy/rbac/service_account.yaml -n metal3
110     kubectl apply -f baremetal-operator/deploy/rbac/role.yaml -n metal3
111     kubectl apply -f baremetal-operator/deploy/rbac/role_binding.yaml
112     kubectl apply -f baremetal-operator/deploy/crds/metal3.io_baremetalhosts_crd.yaml
113     kubectl apply -f baremetal-operator/deploy/operator/no_ironic/operator.yaml -n metal3
114     popd
115 }
116
117 function remove_baremetal_operator {
118     if [ ! -d $GOPATH/src/github.com/metal3-io/baremetal-operator ]; then
119         pushd $GOPATH/src/github.com/metal3-io
120         git clone --single-branch --branch v1.0-icn \
121                 https://github.com/akraino-icn/baremetal-operator.git
122         popd
123     fi
124
125     pushd $GOPATH/src/github.com/metal3-io
126     kubectl delete -f baremetal-operator/deploy/operator/no_ironic/operator.yaml -n metal3
127     kubectl delete -f baremetal-operator/deploy/crds/metal3.io_baremetalhosts_crd.yaml
128     kubectl delete -f baremetal-operator/deploy/rbac/role_binding.yaml
129     kubectl delete -f baremetal-operator/deploy/rbac/role.yaml -n metal3
130     kubectl delete -f baremetal-operator/deploy/rbac/service_account.yaml -n metal3
131     kubectl delete -f baremetal-operator/deploy/namespace/namespace.yaml
132     popd
133     rm -rf $GOPATH/src/github.com/metal3-io/baremetal-operator
134 }
135
136 function network_config_files {
137     cat << 'EOF'
138 write_files:
139 - path: /opt/ironic_net.sh
140   owner: root:root
141   permissions: '0777'
142   content: |
143     #!/usr/bin/env bash
144     set -xe
145     for intf in /sys/class/net/*; do
146         sudo ifconfig `basename $intf` up
147         sudo dhclient -nw `basename $intf`
148     done
149 EOF
150 cat << EOF
151 - path: /opt/user_net.sh
152   owner: root:root
153   permissions: '0777'
154   content: |
155     #!/usr/bin/env bash
156     set -xe
157     route add default gw $PROVIDER_NETWORK_GATEWAY
158     sed -i -e 's/^#DNS=.*/DNS=$PROVIDER_NETWORK_DNS/g' /etc/systemd/resolved.conf
159     systemctl daemon-reload
160     systemctl restart systemd-resolved
161 runcmd:
162  - [ /opt/ironic_net.sh ]
163  - [ /opt/user_net.sh ]
164 EOF
165 }
166
167 function apply_userdata_credential {
168     name="$1"
169     cat <<EOF > ./$name-user-data-credential.yaml
170 apiVersion: v1
171 data:
172   userData: $(base64 -w 0 $name-userdata.yaml)
173 kind: Secret
174 metadata:
175   name: $name-user-data
176   namespace: metal3
177 type: Opaque
178 EOF
179     kubectl apply -n metal3 -f $name-user-data-credential.yaml
180 }
181
182 function make_bm_hosts {
183     while read -r name username password address; do
184         create_userdata $name
185         apply_userdata_credential $name
186
187         go run $GOPATH/src/github.com/metal3-io/baremetal-operator/cmd/make-bm-worker/main.go \
188            -address "ipmi://$address" \
189            -password "$password" \
190            -user "$username" \
191            "$name" > $name-bm-node.yaml
192
193         printf "  image:" >> $name-bm-node.yaml
194         printf "\n    url: ""%s" "$IMAGE_URL" >> $name-bm-node.yaml
195         printf "\n    checksum: ""%s" "$IMAGE_CHECKSUM" >> $name-bm-node.yaml
196         printf "\n  userData:" >> $name-bm-node.yaml
197         printf "\n    name: ""%s" "$name""-user-data" >> $name-bm-node.yaml
198         printf "\n    namespace: metal3\n" >> $name-bm-node.yaml
199         kubectl apply -f $name-bm-node.yaml -n metal3
200     done
201 }
202
203 function configure_nodes {
204     if [ ! -d $IRONIC_DATA_DIR ]; then
205         mkdir -p $IRONIC_DATA_DIR
206     fi
207
208     #make sure nodes.json file in /opt/ironic/ are configured
209     if [ ! -f $IRONIC_DATA_DIR/nodes.json ]; then
210         cp $PWD/nodes.json.sample $IRONIC_DATA_DIR/nodes.json
211     fi
212 }
213
214 function remove_bm_hosts {
215     while read -r name username password address; do
216         deprovision_compute_node $name
217     done
218 }
219
220 function cleanup {
221     while read -r name username password address; do
222         kubectl delete bmh $name -n metal3
223         kubectl delete secrets $name-bmc-secret -n metal3
224         kubectl delete secrets $name-user-data -n metal3
225         if [ -f $name-bm-node.yaml ]; then
226             rm -rf $name-bm-node.yaml
227         fi
228
229         if [ -f $name-user-data-credential.yaml ]; then
230             rm -rf $name-user-data-credential.yaml
231         fi
232
233         if [ -f $name-userdata.yaml ]; then
234             rm -rf $name-userdata.yaml
235         fi
236     done
237 }
238
239 function clean_all {
240     list_nodes | cleanup
241     if [ -f $IRONIC_DATA_DIR/nodes.json ]; then
242         rm -rf $IRONIC_DATA_DIR/nodes.json
243     fi
244 }
245
246 function apply_bm_hosts {
247     list_nodes | make_bm_hosts
248 }
249
250 function deprovision_all_hosts {
251     list_nodes | remove_bm_hosts
252 }
253
254 if [ "$1" == "launch" ]; then
255     launch_baremetal_operator
256     exit 0
257 fi
258
259 if [ "$1" == "deprovision" ]; then
260     configure_nodes
261     deprovision_all_hosts
262     exit 0
263 fi
264
265 if [ "$1" == "provision" ]; then
266     configure_nodes
267     apply_bm_hosts
268     exit 0
269 fi
270
271 if [ "$1" == "clean" ]; then
272     configure_nodes
273     clean_all
274     exit 0
275 fi
276
277 if [ "$1" == "remove" ]; then
278     remove_baremetal_operator
279     exit 0
280 fi
281
282 echo "Usage: metal3.sh"
283 echo "launch      - Launch the metal3 operator"
284 echo "provision   - provision baremetal node as specified in common.sh"
285 echo "deprovision - deprovision baremetal node as specified in common.sh"
286 echo "clean       - clean all the bmh resources"
287 echo "remove      - remove baremetal operator"
288 exit 1
289
290 #Following code is tested for the offline mode
291 #Will be intergrated for the offline mode for ICNi v.0.1.0 beta
292 #create_ssh_key
293 #create_userdata
294 #set_compute_key
295 #set_compute_ssh_config