Sync with recent changes in fuel-main
[fuel.git] / build / f_isoroot / f_bootstrap / bootstrap_admin_node.sh
1 #!/bin/bash
2 mkdir -p /var/log/puppet
3 exec > >(tee -i /var/log/puppet/bootstrap_admin_node.log)
4 exec 2>&1
5
6 FUEL_RELEASE=$(cat /etc/fuel_release)
7 ASTUTE_YAML='/etc/fuel/astute.yaml'
8 BOOTSTRAP_NODE_CONFIG="/etc/fuel/bootstrap_admin_node.conf"
9 bs_build_log='/var/log/fuel-bootstrap-image-build.log'
10 bs_status=0
11 # Backup network configs to this folder. Folder will be created only if
12 # backup process actually will be.
13 bup_folder="/var/bootstrap_admin_node_bup_$(date +%Y-%m-%d-%H-%M-%S)/"
14 ### Long messages inside code makes them more complicated to read...
15 # bootstrap messages
16 # FIXME fix help links
17 bs_skip_message="WARNING: Ubuntu bootstrap build has been skipped. \
18 Please build and activate bootstrap manually with CLI command \
19 \`fuel-bootstrap build --activate\`. \
20 While you don't activate any bootstrap - new nodes cannot be discovered \
21 and added to cluster. \
22 For more information please visit \
23 https://docs.mirantis.com/openstack/fuel/fuel-master/"
24 bs_error_message="WARNING: Failed to build the bootstrap image, see $bs_build_log \
25 for details. Perhaps your Internet connection is broken. Please fix the \
26 problem and run \`fuel-bootstrap build --activate\`. \
27 While you don\'t activate any bootstrap - new nodes cannot be discovered \
28 and added to cluster. \
29 For more information please visit \
30 https://docs.mirantis.com/openstack/fuel/fuel-master/"
31 bs_progress_message="There is no active bootstrap. Bootstrap image building \
32 is in progress. Usually it takes 15-20 minutes. It depends on your internet \
33 connection and hardware performance. Please reboot failed to discover nodes \
34 after bootstrap image become available."
35 bs_done_message="Default bootstrap image building done. Now you can boot new \
36 nodes over PXE, they will be discovered and become available for installing \
37 OpenStack on them"
38 bs_centos_message="WARNING: Deprecated Centos bootstrap has been chosen \
39 and activated. Now you can boot new nodes over PXE, they will be discovered \
40 and become available for installing OpenStack on them."
41 # Update issues messages
42 update_warn_message="There is an issue connecting to the Fuel update repository. \
43 Please fix your connection prior to applying any updates. \
44 Once the connection is fixed, we recommend reviewing and applying \
45 Maintenance Updates for this release of Mirantis OpenStack: \
46 https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\
47 release-notes.html#maintenance-updates"
48 update_done_message="We recommend reviewing and applying Maintenance Updates \
49 for this release of Mirantis OpenStack: \
50 https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\
51 release-notes.html#maintenance-updates"
52 fuelmenu_fail_message="Fuelmenu was not able to generate '/etc/fuel/astute.yaml' file! \
53 Please, restart it manualy using 'fuelmenu' command."
54
55 function countdown() {
56   local i
57   sleep 1
58   for ((i=$1-1; i>=1; i--)); do
59     printf '\b\b\b\b%04d' "$i"
60     sleep 1
61   done
62 }
63
64 function fail() {
65   echo "ERROR: Fuel node deployment FAILED! Check /var/log/puppet/bootstrap_admin_node.log for details" 1>&2
66   exit 1
67 }
68 # LANG variable is a workaround for puppet-3.4.2 bug. See LP#1312758 for details
69 export LANG=en_US.UTF8
70 export ADMIN_INTERFACE=eth0
71
72 showmenu="no"
73 if [ -f /etc/fuel/bootstrap_admin_node.conf ]; then
74   . /etc/fuel/bootstrap_admin_node.conf
75   echo "Applying admin interface '$ADMIN_INTERFACE'"
76 fi
77
78 echo "Applying default Fuel settings..."
79 set -x
80 fuelmenu --save-only --iface=$ADMIN_INTERFACE
81 set +x
82 echo "Done!"
83
84 ### OPNFV addition BEGIN
85 shopt -s nullglob
86 for script in /opt/opnfv/bootstrap/pre.d/*.sh
87 do
88   echo "Pre script: $script" >> /root/pre.log 2>&1
89   $script >> /root/pre.log 2>&1
90 done
91 shopt -u nullglob
92 ### OPNFV addition END
93
94 if [[ "$showmenu" == "yes" || "$showmenu" == "YES" ]]; then
95   fuelmenu
96   else
97   #Give user 15 seconds to enter fuelmenu or else continue
98   echo
99   echo -n "Press a key to enter Fuel Setup (or press ESC to skip)...   15"
100   countdown 15 & pid=$!
101   if ! read -s -n 1 -t 15 key; then
102     echo -e "\nSkipping Fuel Setup..."
103   else
104     { kill "$pid"; wait $!; } 2>/dev/null
105     case "$key" in
106       $'\e')  echo "Skipping Fuel Setup.."
107               ;;
108       *)      echo -e "\nEntering Fuel Setup..."
109               fuelmenu
110               ;;
111     esac
112   fi
113 fi
114
115 if [ ! -f "${ASTUTE_YAML}" ]; then
116   echo ${fuelmenu_fail_message}
117   fail
118 fi
119
120 systemctl reload sshd
121
122 # Enable iptables
123 systemctl enable iptables.service
124 systemctl start iptables.service
125
126
127 if [ "$wait_for_external_config" == "yes" ]; then
128   wait_timeout=3000
129   pidfile=/var/lock/wait_for_external_config
130   echo -n "Waiting for external configuration (or press ESC to skip)...
131 $wait_timeout"
132   countdown $wait_timeout & countdown_pid=$!
133   exec -a wait_for_external_config sleep $wait_timeout & wait_pid=$!
134   echo $wait_pid > $pidfile
135   while ps -p $countdown_pid &> /dev/null && ps -p $wait_pid &>/dev/null; do
136     read -s -n 1 -t 2 key
137     case "$key" in
138       $'\e')   echo -e "\b\b\b\b abort on user input"
139                break
140                ;;
141       *)       ;;
142     esac
143   done
144   { kill $countdown_pid $wait_pid & wait $!; }
145   rm -f $pidfile
146 fi
147
148
149 #Reread /etc/sysconfig/network to inform puppet of changes
150 . /etc/sysconfig/network
151 hostname "$HOSTNAME"
152
153 # XXX: ssh keys which should be included into the bootstrap image are
154 # generated during containers deployment. However cobbler checkfs for
155 # a kernel and initramfs when creating a profile, which poses chicken
156 # and egg problem. Fortunately cobbler is pretty happy with empty files
157 # so it's easy to break the loop.
158 make_ubuntu_bootstrap_stub () {
159         local bootstrap_dir='/var/www/nailgun/bootstrap/ubuntu'
160         mkdir -p $bootstrap_dir
161         for item in linux initramfs.img; do
162                 touch "$bootstrap_dir/$item"
163         done
164 }
165
166 get_bootstrap_flavor () {
167         python <<-EOF
168         from yaml import safe_load
169         with open("$ASTUTE_YAML", 'r') as f:
170             conf = safe_load(f).get('BOOTSTRAP', {})
171         print(conf.get('flavor', 'centos').lower())
172         EOF
173 }
174
175 get_bootstrap_skip () {
176         python <<-EOF
177         from yaml import safe_load
178         with open("$ASTUTE_YAML", 'r') as f:
179             conf = safe_load(f).get('BOOTSTRAP', {})
180         print(conf.get('skip_default_img_build', False))
181         EOF
182 }
183
184 set_ui_bootstrap_error () {
185         # This notify can't be closed or removed by user.
186         # For remove notify - send empty string.
187         local message=$1
188         python <<-EOF
189         from fuel_bootstrap.utils import notifier
190         notifier.notify_webui('${message}')
191         EOF
192 }
193
194 # Actually build the bootstrap image
195 build_ubuntu_bootstrap () {
196         local ret=1
197         echo ${bs_progress_message} >&2
198         set_ui_bootstrap_error "${bs_progress_message}" >&2
199 # OPNFV modification to turn off biosdevname on the line below (extend-kopts)
200         if fuel-bootstrap -v --debug build --activate \
201         --extend-kopts "biosdevname=0 net.ifnames=0 debug ignore_loglevel log_buf_len=10M print_fatal_signals=1 LOGLEVEL=8" \
202         >>"$bs_build_log" 2>&1; then
203           ret=0
204           fuel notify --topic "done" --send "${bs_done_message}"
205         else
206           ret=1
207           set_ui_bootstrap_error "${bs_error_message}" >&2
208         fi
209         # perform hard-return from func
210         # this part will update input $1 variable
211         local  __resultvar=$1
212         eval $__resultvar="'${ret}'"
213         return $ret
214 }
215
216
217 # Create empty files to make cobbler happy
218 # (even if we don't use Ubuntu based bootstrap)
219 make_ubuntu_bootstrap_stub
220
221 service docker start
222
223 if [ -f /root/.build_images ]; then
224   #Fail on all errors
225   set -e
226   trap fail EXIT
227
228   echo "Loading Fuel base image for Docker..."
229   docker load -i /var/www/nailgun/docker/images/fuel-images.tar
230
231   echo "Building Fuel Docker images..."
232   WORKDIR=$(mktemp -d /tmp/docker-buildXXX)
233   SOURCE=/var/www/nailgun/docker
234   REPO_CONT_ID=$(docker -D run -d -p 80 -v /var/www/nailgun:/var/www/nailgun fuel/centos sh -c 'mkdir /var/www/html/os;ln -sf /var/www/nailgun/centos/x86_64 /var/www/html/os/x86_64;/usr/sbin/apachectl -DFOREGROUND')
235   RANDOM_PORT=$(docker port $REPO_CONT_ID 80 | cut -d':' -f2)
236
237   for imagesource in /var/www/nailgun/docker/sources/*; do
238     if ! [ -f "$imagesource/Dockerfile" ]; then
239       echo "Skipping ${imagesource}..."
240       continue
241     fi
242     image=$(basename "$imagesource")
243     cp -R "$imagesource" $WORKDIR/$image
244     mkdir -p $WORKDIR/$image/etc
245     cp -R /etc/puppet /etc/fuel $WORKDIR/$image/etc
246     sed -e "s/_PORT_/${RANDOM_PORT}/" -i $WORKDIR/$image/Dockerfile
247     sed -e 's/production:.*/production: "docker-build"/' -i $WORKDIR/$image/etc/fuel/version.yaml
248     docker build -t fuel/${image}_${FUEL_RELEASE} $WORKDIR/$image
249   done
250   docker rm -f $REPO_CONT_ID
251   rm -rf "$WORKDIR"
252
253   #Remove trap for normal deployment
254   trap - EXIT
255   set +e
256 else
257   echo "Loading docker images. (This may take a while)"
258   docker load -i /var/www/nailgun/docker/images/fuel-images.tar
259 fi
260
261 # apply puppet
262 puppet apply --detailed-exitcodes -d -v /etc/puppet/modules/nailgun/examples/host-only.pp
263 if [ $? -ge 4 ];then
264   fail
265 fi
266
267 rmdir /var/log/remote && ln -s /var/log/docker-logs/remote /var/log/remote
268
269 dockerctl check || fail
270 bash /etc/rc.local
271
272 if [ "`get_bootstrap_flavor`" = "ubuntu" ]; then
273         build_ubuntu_bootstrap || true
274 fi
275
276 ### OPNFV addition BEGIN
277 shopt -s nullglob
278 for script in /opt/opnfv/bootstrap/post.d/*.sh
279 do
280   echo "Post script: $script" >> /root/post.log 2>&1
281   $script >> /root/post.log 2>&1
282 done
283 shopt -u nullglob
284 ### OPNFV addition END
285
286 # Enable updates repository
287 cat > /etc/yum.repos.d/mos${FUEL_RELEASE}-updates.repo << EOF
288 [mos${FUEL_RELEASE}-updates]
289 name=mos${FUEL_RELEASE}-updates
290 baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos${FUEL_RELEASE}-centos6-fuel/updates/x86_64/
291 gpgcheck=0
292 skip_if_unavailable=1
293 EOF
294
295 # Enable security repository
296 cat > /etc/yum.repos.d/mos${FUEL_RELEASE}-security.repo << EOF
297 [mos${FUEL_RELEASE}-security]
298 name=mos${FUEL_RELEASE}-security
299 baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos${FUEL_RELEASE}-centos6-fuel/security/x86_64/
300 gpgcheck=0
301 skip_if_unavailable=1
302 EOF
303
304 #Check if repo is accessible
305 echo "Checking for access to updates repository..."
306 repourl=$(grep baseurl /etc/yum.repos.d/*updates* 2>/dev/null | cut -d'=' -f2- | head -1)
307 if urlaccesscheck check "$repourl" ; then
308   UPDATE_ISSUES=0
309 else
310   UPDATE_ISSUES=1
311 fi
312
313 if [ $UPDATE_ISSUES -eq 1 ]; then
314   message="There is an issue connecting to the Fuel update repository. \
315 Please fix your connection prior to applying any updates. \
316 Once the connection is fixed, we recommend reviewing and applying \
317 Maintenance Updates for this release of Mirantis OpenStack: \
318 https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\
319 release-notes.html#maintenance-updates"
320   level="warning"
321 else
322   message="We recommend reviewing and applying Maintenance Updates \
323 for this release of Mirantis OpenStack: \
324 https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\
325 release-notes.html#maintenance-updates"
326   level="done"
327 fi
328 echo
329 echo "*************************************************"
330 echo -e "${message}"
331 echo "*************************************************"
332 echo "Sending notification to Fuel UI..."
333 fuel notify --topic "${level}" --send "${message}"
334
335 # TODO(kozhukalov) If building of bootstrap image fails
336 # and if this image was supposed to be a default bootstrap image
337 # we need to warn a user about this and give her
338 # advice how to treat this.
339
340 echo "Fuel node deployment complete!"