2 # WARNING: REQUIRES /bin/sh
4 # - must run on /bin/sh on solaris 9
5 # - must run on /bin/sh on AIX 6.x
7 # Copyright:: Copyright (c) 2010-2015 Chef Software, Inc.
8 # License:: Apache License, Version 2.0
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
14 # http://www.apache.org/licenses/LICENSE-2.0
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.
25 # This section has some helper functions to make life easier.
28 # $tmp_dir: secure-ish temp directory that can be used during installation.
31 # Check whether a command exists - returns 0 if it does, 1 if it does not
33 if command -v $1 >/dev/null 2>&1
41 # Output the instructions to report bug about this script
43 echo "Version: $version"
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"
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."
56 echo "Package checksum mismatch!"
61 unable_to_retrieve_package() {
62 echo "Unable to retrieve a valid package!"
64 echo "Metadata URL: $metadata_url"
65 if test "x$download_url" != "x"; then
66 echo "Download URL: $download_url"
68 if test "x$stderr_results" != "x"; then
69 echo "\nDEBUG OUTPUT FOLLOWS:\n$stderr_results"
75 echo "Omnitruck artifact does not exist for version $version on platform $platform"
77 echo "Either this means:"
78 echo " - We do not support $platform"
79 echo " - We do not have an artifact for $version"
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."
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)."
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'"
92 echo "If you cannot fix this problem by setting the bootstrap_version, it probably means"
93 echo "that $platform is not supported."
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"
100 if test "x$stderr_results" != "x"; then
101 echo "\nDEBUG OUTPUT FOLLOWS:\n$stderr_results"
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"
115 # do_wget URL FILENAME
117 echo "trying wget..."
118 wget --user-agent="User-Agent: mixlib-install/2.1.8" -O "$2" "$1" 2>$tmp_dir/stderr
121 grep "ERROR 404" $tmp_dir/stderr 2>&1 >/dev/null
122 if test $? -eq 0; then
127 # check for bad return status or empty output
128 if test $rc -ne 0 || test ! -s "$2"; then
129 capture_tmp_stderr "wget"
136 # do_curl URL FILENAME
138 echo "trying curl..."
139 curl -A "User-Agent: mixlib-install/2.1.8" --retry 5 -sL -D $tmp_dir/stderr "$1" > "$2"
142 grep "404 Not Found" $tmp_dir/stderr 2>&1 >/dev/null
143 if test $? -eq 0; then
148 # check for bad return status or empty output
149 if test $rc -ne 0 || test ! -s "$2"; then
150 capture_tmp_stderr "curl"
157 # do_fetch URL FILENAME
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
166 # do_perl URL FILENAME
168 echo "trying perl..."
169 perl -e 'use LWP::Simple; getprint($ARGV[0]);' "$1" > "$2" 2>$tmp_dir/stderr
172 grep "404 Not Found" $tmp_dir/stderr 2>&1 >/dev/null
173 if test $? -eq 0; then
178 # check for bad return status or empty output
179 if test $rc -ne 0 || test ! -s "$2"; then
180 capture_tmp_stderr "perl"
187 # do_python URL FILENAME
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
193 grep "HTTP Error 404" $tmp_dir/stderr 2>&1 >/dev/null
194 if test $? -eq 0; then
199 # check for bad return status or empty output
200 if test $rc -ne 0 || test ! -s "$2"; then
201 capture_tmp_stderr "python"
207 # returns 0 if checksums match
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"`
218 echo "WARNING: could not find a valid checksum program, pre-install shasum or sha256sum in your O/S image to get valdation..."
223 # do_download URL FILENAME
225 echo "downloading $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/'`
236 # we try all of these until we get success.
237 # perl, in particular may be present but LWP::Simple may not be installed
240 do_wget $url $2 && return 0
244 do_curl $url $2 && return 0
247 if exists fetch; then
248 do_fetch $url $2 && return 0
252 do_perl $url $2 && return 0
255 if exists python; then
256 do_python $url $2 && return 0
259 unable_to_retrieve_package
262 # install_file TYPE FILENAME
263 # TYPE is "rpm", "deb", "solaris", "sh", etc.
265 echo "Installing $project $version"
268 if test "x$platform" = "xnexus" || test "x$platform" = "xios_xr"; then
269 echo "installing with yum..."
272 echo "installing with rpm..."
273 rpm -Uvh --oldpackage --replacepkgs "$2"
277 echo "installing with dpkg..."
281 echo "installing with installp..."
282 installp -aXYgd "$2" all
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
293 echo "installing with installer..."
294 cd / && /usr/sbin/installer -pkg "$2" -target /
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"
304 echo "installing with sh..."
308 echo "installing p5p package..."
309 pkg install -g "$2" $project
312 echo "Unknown filetype: $1"
317 if test $? -ne 0; then
318 echo "Installation failed"
324 if test "x$TMPDIR" = "x"; then
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
338 # script_cli_parameters.sh
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.
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.
355 while getopts pnv:c:f:P:d: opt
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";;
368 "usage: $0 [-P project] [-c release_channel] [-v version] [-f filename | -d download_dir]"
373 shift `expr $OPTIND - 1`
376 # platform_detection.sh
378 # This section makes platform detection compatible with omnitruck on the system
382 # $platform: Name of the platform.
383 # $platform_version: Version of the platform.
384 # $machine: System's architecture.
388 # Platform and Platform Version detection
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.
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).
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`
407 if test "$platform" = "\"cumulus linux\""; then
408 platform="cumulus_linux"
409 elif test "$platform" = "\"cumulus networks\""; then
410 platform="cumulus_networks"
413 elif test -f "/etc/debian_version"; then
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.
419 platform_version=`awk '{print $4}' /etc/Eos-release`
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`
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"
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
437 # FIXME: use "redhat"
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"
448 platform_version="6.0"
451 elif test -f "/usr/bin/sw_vers"; then
453 # Matching the tab-space with sed is error-prone
454 platform_version=`sw_vers | awk '/^ProductVersion:/ { print $2 }' | cut -d. -f1,2`
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
461 elif test -f "/etc/release"; then
462 machine=`/usr/bin/uname -p`
463 if grep -q SmartOS /etc/release; then
465 platform_version=`grep ^Image /etc/product | awk '{ print $3 }'`
468 platform_version=`/usr/bin/uname -r`
470 elif test -f "/etc/SuSE-release"; then
471 if grep -q 'Enterprise' /etc/SuSE-release;
474 platform_version=`awk '/^VERSION/ {V = $3}; /^PATCHLEVEL/ {P = $3}; END {print V "." P}' /etc/SuSE-release`
477 platform_version=`awk '/^VERSION =/ { print $3 }' /etc/SuSE-release`
479 elif test "x$os" = "xFreeBSD"; then
481 platform_version=`uname -r | sed 's/-.*//'`
482 elif test "x$os" = "xAIX"; then
484 platform_version="`uname -v`.`uname -r`"
486 elif test -f "/etc/os-release"; then
488 if test "x$CISCO_RELEASE_INFO" != "x"; then
489 . $CISCO_RELEASE_INFO
493 platform_version=$VERSION
496 if test "x$platform" = "x"; then
497 echo "Unable to determine platform version!"
503 # NOTE: platform manging in the install.sh is DEPRECATED
505 # - install.sh should be true to ohai and should not remap
506 # platform or platform versions.
508 # - remapping platform and mangling platform version numbers is
509 # now the complete responsibility of the server-side endpoints
512 major_version=`echo $platform_version | cut -d. -f1`
514 # FIXME: should remove this case statement completely
516 # FIXME: "el" is deprecated, should use "redhat"
517 platform_version=$major_version
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.
526 platform_version=$major_version
530 platform_version=$major_version
533 platform_version=$major_version
536 platform_version=$major_version
540 # normalize the architecture we detected
542 "x86_64"|"amd64"|"x64")
545 "i386"|"i86pc"|"x86"|"i686")
548 "sparc"|"sun4u"|"sun4v")
553 if test "x$platform_version" = "x"; then
554 echo "Unable to determine platform version!"
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
565 echo "$platform $platform_version $machine"
568 # end of platform_detection.sh
574 # This section calls omnitruck to get the information about the build to be
591 echo "Getting information for $project $channel $version for $platform..."
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"
596 do_download "$metadata_url" "$metadata_filename"
598 cat "$metadata_filename"
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..."
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.
612 download_url=`awk '$1 == "url" { print $2 }' "$metadata_filename"`
613 sha256=`awk '$1 == "sha256" { print $2 }' "$metadata_filename"`
616 # end of fetch_metadata.sh
622 # This section fetchs a package from $download_url and verifies its metadata.
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.
632 # $download_filename: Name of the downloaded file on local disk.
633 # $filetype: Type of the file downloaded.
636 filename=`echo $download_url | sed -e 's/^.*\///'`
637 filetype=`echo $filename | sed -e 's/^.*\.//'`
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"
645 download_filename="$tmp_dir/$filename"
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
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"
660 echo "checksum mismatch, downloading latest version of the file"
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
671 # end of fetch_package.sh
677 # Installs a package and removed the temp directory.
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.
685 if test "x$version" = "x"; then
687 echo "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
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."
695 echo "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
699 install_file $filetype "$download_filename"
701 if test "x$tmp_dir" != "x"; then
706 # end of install_package.sh