Add K8S deployment above Vagrant
[sdc.git] / sdc-os-chef / sdc-cassandra / chef-install.sh
1 #!/bin/sh
2 # WARNING: REQUIRES /bin/sh
3 #
4 # - must run on /bin/sh on solaris 9
5 # - must run on /bin/sh on AIX 6.x
6 #
7 # Copyright:: Copyright (c) 2010-2015 Chef Software, Inc.
8 # License:: Apache License, Version 2.0
9 #
10 # Licensed under the Apache License, Version 2.0 (the "License");
11 # you may not use this file except in compliance with the License.
12 # You may obtain a copy of the License at
13 #
14 #     http://www.apache.org/licenses/LICENSE-2.0
15 #
16 # Unless required by applicable law or agreed to in writing, software
17 # distributed under the License is distributed on an "AS IS" BASIS,
18 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 # See the License for the specific language governing permissions and
20 # limitations under the License.
21 #
22
23 # helpers.sh
24 ############
25 # This section has some helper functions to make life easier.
26 #
27 # Outputs:
28 # $tmp_dir: secure-ish temp directory that can be used during installation.
29 ############
30
31 # Check whether a command exists - returns 0 if it does, 1 if it does not
32 exists() {
33   if command -v $1 >/dev/null 2>&1
34   then
35     return 0
36   else
37     return 1
38   fi
39 }
40
41 # Output the instructions to report bug about this script
42 report_bug() {
43   echo "Version: $version"
44   echo ""
45   echo "Please file a Bug Report at https://github.com/chef/omnitruck/issues/new"
46   echo "Alternatively, feel free to open a Support Ticket at https://www.chef.io/support/tickets"
47   echo "More Chef support resources can be found at https://www.chef.io/support"
48   echo ""
49   echo "Please include as many details about the problem as possible i.e., how to reproduce"
50   echo "the problem (if possible), type of the Operating System and its version, etc.,"
51   echo "and any other relevant details that might help us with troubleshooting."
52   echo ""
53 }
54
55 checksum_mismatch() {
56   echo "Package checksum mismatch!"
57   report_bug
58   exit 1
59 }
60
61 unable_to_retrieve_package() {
62   echo "Unable to retrieve a valid package!"
63   report_bug
64   echo "Metadata URL: $metadata_url"
65   if test "x$download_url" != "x"; then
66     echo "Download URL: $download_url"
67   fi
68   if test "x$stderr_results" != "x"; then
69     echo "\nDEBUG OUTPUT FOLLOWS:\n$stderr_results"
70   fi
71   exit 1
72 }
73
74 http_404_error() {
75   echo "Omnitruck artifact does not exist for version $version on platform $platform"
76   echo ""
77   echo "Either this means:"
78   echo "   - We do not support $platform"
79   echo "   - We do not have an artifact for $version"
80   echo ""
81   echo "This is often the latter case due to running a prerelease or RC version of chef"
82   echo "or a gem version which was only pushed to rubygems and not omnitruck."
83   echo ""
84   echo "You may be able to set your knife[:bootstrap_version] to the most recent stable"
85   echo "release of Chef to fix this problem (or the most recent stable major version number)."
86   echo ""
87   echo "In order to test the version parameter, adventurous users may take the Metadata URL"
88   echo "below and modify the '&v=<number>' parameter until you successfully get a URL that"
89   echo "does not 404 (e.g. via curl or wget).  You should be able to use '&v=11' or '&v=12'"
90   echo "succesfully."
91   echo ""
92   echo "If you cannot fix this problem by setting the bootstrap_version, it probably means"
93   echo "that $platform is not supported."
94   echo ""
95   # deliberately do not call report_bug to suppress bug report noise.
96   echo "Metadata URL: $metadata_url"
97   if test "x$download_url" != "x"; then
98     echo "Download URL: $download_url"
99   fi
100   if test "x$stderr_results" != "x"; then
101     echo "\nDEBUG OUTPUT FOLLOWS:\n$stderr_results"
102   fi
103   exit 1
104 }
105
106 capture_tmp_stderr() {
107   # spool up /tmp/stderr from all the commands we called
108   if test -f "$tmp_dir/stderr"; then
109     output=`cat $tmp_dir/stderr`
110     stderr_results="${stderr_results}\nSTDERR from $1:\n\n$output\n"
111     rm $tmp_dir/stderr
112   fi
113 }
114
115 # do_wget URL FILENAME
116 do_wget() {
117   echo "trying wget..."
118   wget --user-agent="User-Agent: mixlib-install/2.1.8" -O "$2" "$1" 2>$tmp_dir/stderr
119   rc=$?
120   # check for 404
121   grep "ERROR 404" $tmp_dir/stderr 2>&1 >/dev/null
122   if test $? -eq 0; then
123     echo "ERROR 404"
124     http_404_error
125   fi
126
127   # check for bad return status or empty output
128   if test $rc -ne 0 || test ! -s "$2"; then
129     capture_tmp_stderr "wget"
130     return 1
131   fi
132
133   return 0
134 }
135
136 # do_curl URL FILENAME
137 do_curl() {
138   echo "trying curl..."
139   curl -A "User-Agent: mixlib-install/2.1.8" --retry 5 -sL -D $tmp_dir/stderr "$1" > "$2"
140   rc=$?
141   # check for 404
142   grep "404 Not Found" $tmp_dir/stderr 2>&1 >/dev/null
143   if test $? -eq 0; then
144     echo "ERROR 404"
145     http_404_error
146   fi
147
148   # check for bad return status or empty output
149   if test $rc -ne 0 || test ! -s "$2"; then
150     capture_tmp_stderr "curl"
151     return 1
152   fi
153
154   return 0
155 }
156
157 # do_fetch URL FILENAME
158 do_fetch() {
159   echo "trying fetch..."
160   fetch --user-agent="User-Agent: mixlib-install/2.1.8" -o "$2" "$1" 2>$tmp_dir/stderr
161   # check for bad return status
162   test $? -ne 0 && return 1
163   return 0
164 }
165
166 # do_perl URL FILENAME
167 do_perl() {
168   echo "trying perl..."
169   perl -e 'use LWP::Simple; getprint($ARGV[0]);' "$1" > "$2" 2>$tmp_dir/stderr
170   rc=$?
171   # check for 404
172   grep "404 Not Found" $tmp_dir/stderr 2>&1 >/dev/null
173   if test $? -eq 0; then
174     echo "ERROR 404"
175     http_404_error
176   fi
177
178   # check for bad return status or empty output
179   if test $rc -ne 0 || test ! -s "$2"; then
180     capture_tmp_stderr "perl"
181     return 1
182   fi
183
184   return 0
185 }
186
187 # do_python URL FILENAME
188 do_python() {
189   echo "trying python..."
190   python -c "import sys,urllib2; sys.stdout.write(urllib2.urlopen(urllib2.Request(sys.argv[1], headers={ 'User-Agent': 'mixlib-install/2.1.8' })).read())" "$1" > "$2" 2>$tmp_dir/stderr
191   rc=$?
192   # check for 404
193   grep "HTTP Error 404" $tmp_dir/stderr 2>&1 >/dev/null
194   if test $? -eq 0; then
195     echo "ERROR 404"
196     http_404_error
197   fi
198
199   # check for bad return status or empty output
200   if test $rc -ne 0 || test ! -s "$2"; then
201     capture_tmp_stderr "python"
202     return 1
203   fi
204   return 0
205 }
206
207 # returns 0 if checksums match
208 do_checksum() {
209   if exists sha256sum; then
210     echo "Comparing checksum with sha256sum..."
211     checksum=`sha256sum $1 | awk '{ print $1 }'`
212     return `test "x$checksum" = "x$2"`
213   elif exists shasum; then
214     echo "Comparing checksum with shasum..."
215     checksum=`shasum -a 256 $1 | awk '{ print $1 }'`
216     return `test "x$checksum" = "x$2"`
217   else
218     echo "WARNING: could not find a valid checksum program, pre-install shasum or sha256sum in your O/S image to get valdation..."
219     return 0
220   fi
221 }
222
223 # do_download URL FILENAME
224 do_download() {
225   echo "downloading $1"
226   echo "  to file $2"
227
228   url=`echo $1`
229   if test "x$platform" = "xsolaris2"; then
230     if test "x$platform_version" = "x5.9" -o "x$platform_version" = "x5.10"; then
231       # solaris 9 lacks openssl, solaris 10 lacks recent enough credentials - your base O/S is completely insecure, please upgrade
232       url=`echo $url | sed -e 's/https/http/'`
233     fi
234   fi
235
236   # we try all of these until we get success.
237   # perl, in particular may be present but LWP::Simple may not be installed
238
239   if exists wget; then
240     do_wget $url $2 && return 0
241   fi
242
243   if exists curl; then
244     do_curl $url $2 && return 0
245   fi
246
247   if exists fetch; then
248     do_fetch $url $2 && return 0
249   fi
250
251   if exists perl; then
252     do_perl $url $2 && return 0
253   fi
254
255   if exists python; then
256     do_python $url $2 && return 0
257   fi
258
259   unable_to_retrieve_package
260 }
261
262 # install_file TYPE FILENAME
263 # TYPE is "rpm", "deb", "solaris", "sh", etc.
264 install_file() {
265   echo "Installing $project $version"
266   case "$1" in
267     "rpm")
268       if test "x$platform" = "xnexus" || test "x$platform" = "xios_xr"; then
269         echo "installing with yum..."
270         yum install -yv "$2"
271       else
272         echo "installing with rpm..."
273         rpm -Uvh --oldpackage --replacepkgs "$2"
274       fi
275       ;;
276     "deb")
277       echo "installing with dpkg..."
278       dpkg -i "$2"
279       ;;
280     "bff")
281       echo "installing with installp..."
282       installp -aXYgd "$2" all
283       ;;
284     "solaris")
285       echo "installing with pkgadd..."
286       echo "conflict=nocheck" > $tmp_dir/nocheck
287       echo "action=nocheck" >> $tmp_dir/nocheck
288       echo "mail=" >> $tmp_dir/nocheck
289       pkgrm -a $tmp_dir/nocheck -n $project >/dev/null 2>&1 || true
290       pkgadd -G -n -d "$2" -a $tmp_dir/nocheck $project
291       ;;
292     "pkg")
293       echo "installing with installer..."
294       cd / && /usr/sbin/installer -pkg "$2" -target /
295       ;;
296     "dmg")
297       echo "installing dmg file..."
298       hdiutil detach "/Volumes/chef_software" >/dev/null 2>&1 || true
299       hdiutil attach "$2" -mountpoint "/Volumes/chef_software"
300       cd / && /usr/sbin/installer -pkg `find "/Volumes/chef_software" -name \*.pkg` -target /
301       hdiutil detach "/Volumes/chef_software"
302       ;;
303     "sh" )
304       echo "installing with sh..."
305       sh "$2"
306       ;;
307     "p5p" )
308       echo "installing p5p package..."
309       pkg install -g "$2" $project
310       ;;
311     *)
312       echo "Unknown filetype: $1"
313       report_bug
314       exit 1
315       ;;
316   esac
317   if test $? -ne 0; then
318     echo "Installation failed"
319     report_bug
320     exit 1
321   fi
322 }
323
324 if test "x$TMPDIR" = "x"; then
325   tmp="/tmp"
326 else
327   tmp=$TMPDIR
328 fi
329 # secure-ish temp dir creation without having mktemp available (DDoS-able but not expliotable)
330 tmp_dir="$tmp/install.sh.$$"
331 (umask 077 && mkdir $tmp_dir) || exit 1
332
333 ############
334 # end of helpers.sh
335 ############
336
337
338 # script_cli_parameters.sh
339 ############
340 # This section reads the CLI parameters for the install script and translates
341 #   them to the local parameters to be used later by the script.
342 #
343 # Outputs:
344 # $version: Requested version to be installed.
345 # $channel: Channel to install the product from
346 # $project: Project to be installed
347 # $cmdline_filename: Name of the package downloaded on local disk.
348 # $cmdline_dl_dir: Name of the directory downloaded package will be saved to on local disk.
349 ############
350
351 # Defaults
352 channel="stable"
353 project="chef"
354
355 while getopts pnv:c:f:P:d: opt
356 do
357   case "$opt" in
358
359     v)  version="$OPTARG";;
360     c)  channel="$OPTARG";;
361     p)  channel="current";; # compat for prerelease option
362     n)  channel="current";; # compat for nightlies option
363     f)  cmdline_filename="$OPTARG";;
364     P)  project="$OPTARG";;
365     d)  cmdline_dl_dir="$OPTARG";;
366     \?)   # unknown flag
367       echo >&2 \
368       "usage: $0 [-P project] [-c release_channel] [-v version] [-f filename | -d download_dir]"
369       exit 1;;
370   esac
371 done
372
373 shift `expr $OPTIND - 1`
374
375
376 # platform_detection.sh
377 ############
378 # This section makes platform detection compatible with omnitruck on the system
379 #   it runs.
380 #
381 # Outputs:
382 # $platform: Name of the platform.
383 # $platform_version: Version of the platform.
384 # $machine: System's architecture.
385 ############
386
387 #
388 # Platform and Platform Version detection
389 #
390 # NOTE: This should now match ohai platform and platform_version matching.
391 # do not invented new platform and platform_version schemas, just make this behave
392 # like what ohai returns as platform and platform_version for the server.
393 #
394 # ALSO NOTE: Do not mangle platform or platform_version here.  It is less error
395 # prone and more future-proof to do that in the server, and then all omnitruck clients
396 # will 'inherit' the changes (install.sh is not the only client of the omnitruck
397 # endpoint out there).
398 #
399
400 machine=`uname -m`
401 os=`uname -s`
402
403 if test -f "/etc/lsb-release" && grep -q DISTRIB_ID /etc/lsb-release && ! grep -q wrlinux /etc/lsb-release; then
404   platform=`grep DISTRIB_ID /etc/lsb-release | cut -d "=" -f 2 | tr '[A-Z]' '[a-z]'`
405   platform_version=`grep DISTRIB_RELEASE /etc/lsb-release | cut -d "=" -f 2`
406
407   if test "$platform" = "\"cumulus linux\""; then
408     platform="cumulus_linux"
409   elif test "$platform" = "\"cumulus networks\""; then
410     platform="cumulus_networks"
411   fi
412
413 elif test -f "/etc/debian_version"; then
414   platform="debian"
415   platform_version=`cat /etc/debian_version`
416 elif test -f "/etc/Eos-release"; then
417   # EOS may also contain /etc/redhat-release so this check must come first.
418   platform=arista_eos
419   platform_version=`awk '{print $4}' /etc/Eos-release`
420   machine="i386"
421 elif test -f "/etc/redhat-release"; then
422   platform=`sed 's/^\(.\+\) release.*/\1/' /etc/redhat-release | tr '[A-Z]' '[a-z]'`
423   platform_version=`sed 's/^.\+ release \([.0-9]\+\).*/\1/' /etc/redhat-release`
424
425   # If /etc/redhat-release exists, we act like RHEL by default
426   if test "$platform" = "fedora"; then
427     # FIXME: stop remapping fedora to el
428     # FIXME: remove client side platform_version mangling and hard coded yolo
429     # Change platform version for use below.
430     platform_version="6.0"
431   fi
432
433   if test "$platform" = "xenserver"; then
434     # Current XenServer 6.2 is based on CentOS 5, platform is not reset to "el" server should hanlde response
435     platform="xenserver"
436   else
437     # FIXME: use "redhat"
438     platform="el"
439   fi
440
441 elif test -f "/etc/system-release"; then
442   platform=`sed 's/^\(.\+\) release.\+/\1/' /etc/system-release | tr '[A-Z]' '[a-z]'`
443   platform_version=`sed 's/^.\+ release \([.0-9]\+\).*/\1/' /etc/system-release | tr '[A-Z]' '[a-z]'`
444   # amazon is built off of fedora, so act like RHEL
445   if test "$platform" = "amazon linux ami"; then
446     # FIXME: remove client side platform_version mangling and hard coded yolo, and remapping to deprecated "el"
447     platform="el"
448     platform_version="6.0"
449   fi
450 # Apple OS X
451 elif test -f "/usr/bin/sw_vers"; then
452   platform="mac_os_x"
453   # Matching the tab-space with sed is error-prone
454   platform_version=`sw_vers | awk '/^ProductVersion:/ { print $2 }' | cut -d. -f1,2`
455
456   # x86_64 Apple hardware often runs 32-bit kernels (see OHAI-63)
457   x86_64=`sysctl -n hw.optional.x86_64`
458   if test $x86_64 -eq 1; then
459     machine="x86_64"
460   fi
461 elif test -f "/etc/release"; then
462   machine=`/usr/bin/uname -p`
463   if grep -q SmartOS /etc/release; then
464     platform="smartos"
465     platform_version=`grep ^Image /etc/product | awk '{ print $3 }'`
466   else
467     platform="solaris2"
468     platform_version=`/usr/bin/uname -r`
469   fi
470 elif test -f "/etc/SuSE-release"; then
471   if grep -q 'Enterprise' /etc/SuSE-release;
472   then
473       platform="sles"
474       platform_version=`awk '/^VERSION/ {V = $3}; /^PATCHLEVEL/ {P = $3}; END {print V "." P}' /etc/SuSE-release`
475   else
476       platform="suse"
477       platform_version=`awk '/^VERSION =/ { print $3 }' /etc/SuSE-release`
478   fi
479 elif test "x$os" = "xFreeBSD"; then
480   platform="freebsd"
481   platform_version=`uname -r | sed 's/-.*//'`
482 elif test "x$os" = "xAIX"; then
483   platform="aix"
484   platform_version="`uname -v`.`uname -r`"
485   machine="powerpc"
486 elif test -f "/etc/os-release"; then
487   . /etc/os-release
488   if test "x$CISCO_RELEASE_INFO" != "x"; then
489     . $CISCO_RELEASE_INFO
490   fi
491
492   platform=$ID
493   platform_version=$VERSION
494 fi
495
496 if test "x$platform" = "x"; then
497   echo "Unable to determine platform version!"
498   report_bug
499   exit 1
500 fi
501
502 #
503 # NOTE: platform manging in the install.sh is DEPRECATED
504 #
505 # - install.sh should be true to ohai and should not remap
506 #   platform or platform versions.
507 #
508 # - remapping platform and mangling platform version numbers is
509 #   now the complete responsibility of the server-side endpoints
510 #
511
512 major_version=`echo $platform_version | cut -d. -f1`
513 case $platform in
514   # FIXME: should remove this case statement completely
515   "el")
516     # FIXME:  "el" is deprecated, should use "redhat"
517     platform_version=$major_version
518     ;;
519   "debian")
520     if test "x$major_version" = "x5"; then
521       # This is here for potential back-compat.
522       # We do not have 5 in versions we publish for anymore but we
523       # might have it for earlier versions.
524       platform_version="6"
525     else
526       platform_version=$major_version
527     fi
528     ;;
529   "freebsd")
530     platform_version=$major_version
531     ;;
532   "sles")
533     platform_version=$major_version
534     ;;
535   "suse")
536     platform_version=$major_version
537     ;;
538 esac
539
540 # normalize the architecture we detected
541 case $machine in
542   "x86_64"|"amd64"|"x64")
543     machine="x86_64"
544     ;;
545   "i386"|"i86pc"|"x86"|"i686")
546     machine="i386"
547     ;;
548   "sparc"|"sun4u"|"sun4v")
549     machine="sparc"
550     ;;
551 esac
552
553 if test "x$platform_version" = "x"; then
554   echo "Unable to determine platform version!"
555   report_bug
556   exit 1
557 fi
558
559 if test "x$platform" = "xsolaris2"; then
560   # hack up the path on Solaris to find wget, pkgadd
561   PATH=/usr/sfw/bin:/usr/sbin:$PATH
562   export PATH
563 fi
564
565 echo "$platform $platform_version $machine"
566
567 ############
568 # end of platform_detection.sh
569 ############
570
571
572 # fetch_metadata.sh
573 ############
574 # This section calls omnitruck to get the information about the build to be
575 #   installed.
576 #
577 # Inputs:
578 # $channel:
579 # $project:
580 # $version:
581 # $platform:
582 # $platform_version:
583 # $machine:
584 # $tmp_dir:
585 #
586 # Outputs:
587 # $download_url:
588 # $sha256:
589 ############
590
591 echo "Getting information for $project $channel $version for $platform..."
592
593 metadata_filename="$tmp_dir/metadata.txt"
594 metadata_url="https://omnitruck-direct.chef.io/$channel/$project/metadata?v=$version&p=$platform&pv=$platform_version&m=$machine"
595
596 do_download "$metadata_url"  "$metadata_filename"
597
598 cat "$metadata_filename"
599
600 echo ""
601 # check that all the mandatory fields in the downloaded metadata are there
602 if grep '^url' $metadata_filename > /dev/null && grep '^sha256' $metadata_filename > /dev/null; then
603   echo "downloaded metadata file looks valid..."
604 else
605   echo "downloaded metadata file is corrupted or an uncaught error was encountered in downloading the file..."
606   # this generally means one of the download methods downloaded a 404 or something like that and then reported a successful exit code,
607   # and this should be fixed in the function that was doing the download.
608   report_bug
609   exit 1
610 fi
611
612 download_url=`awk '$1 == "url" { print $2 }' "$metadata_filename"`
613 sha256=`awk '$1 == "sha256" { print $2 }' "$metadata_filename"`
614
615 ############
616 # end of fetch_metadata.sh
617 ############
618
619
620 # fetch_package.sh
621 ############
622 # This section fetchs a package from $download_url and verifies its metadata.
623 #
624 # Inputs:
625 # $download_url:
626 # $tmp_dir:
627 # Optional Inputs:
628 # $cmdline_filename: Name of the package downloaded on local disk.
629 # $cmdline_dl_dir: Name of the directory downloaded package will be saved to on local disk.
630 #
631 # Outputs:
632 # $download_filename: Name of the downloaded file on local disk.
633 # $filetype: Type of the file downloaded.
634 ############
635
636 filename=`echo $download_url | sed -e 's/^.*\///'`
637 filetype=`echo $filename | sed -e 's/^.*\.//'`
638
639 # use either $tmp_dir, the provided directory (-d) or the provided filename (-f)
640 if test "x$cmdline_filename" != "x"; then
641   download_filename="$cmdline_filename"
642 elif test "x$cmdline_dl_dir" != "x"; then
643   download_filename="$cmdline_dl_dir/$filename"
644 else
645   download_filename="$tmp_dir/$filename"
646 fi
647
648 # ensure the parent directory where to download the installer always exists
649 download_dir=`dirname $download_filename`
650 (umask 077 && mkdir -p $download_dir) || exit 1
651
652 # check if we have that file locally available and if so verify the checksum
653 cached_file_available="false"
654 if test -f $download_filename; then
655   echo "$download_filename already exists, verifiying checksum..."
656   if do_checksum "$download_filename" "$sha256"; then
657     echo "checksum compare succeeded, using existing file!"
658     cached_file_available="true"
659   else
660     echo "checksum mismatch, downloading latest version of the file"
661   fi
662 fi
663
664 # download if no local version of the file available
665 if test "x$cached_file_available" != "xtrue"; then
666   do_download "$download_url"  "$download_filename"
667   do_checksum "$download_filename" "$sha256" || checksum_mismatch
668 fi
669
670 ############
671 # end of fetch_package.sh
672 ############
673
674
675 # install_package.sh
676 ############
677 # Installs a package and removed the temp directory.
678 #
679 # Inputs:
680 # $download_filename: Name of the file to be installed.
681 # $filetype: Type of the file to be installed.
682 # $version: The version requested. Used only for warning user if not set.
683 ############
684
685 if test "x$version" = "x"; then
686   echo
687   echo "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
688   echo
689   echo "You are installing an omnibus package without a version pin.  If you are installing"
690   echo "on production servers via an automated process this is DANGEROUS and you will"
691   echo "be upgraded without warning on new releases, even to new major releases."
692   echo "Letting the version float is only appropriate in desktop, test, development or"
693   echo "CI/CD environments."
694   echo
695   echo "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
696   echo
697 fi
698
699 install_file $filetype "$download_filename"
700
701 if test "x$tmp_dir" != "x"; then
702   rm -r "$tmp_dir"
703 fi
704
705 ############
706 # end of install_package.sh
707 ############