mixlib-install 0.7.1 → 0.8.0.alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/CONTRIBUTING.md +14 -0
  4. data/Gemfile +1 -0
  5. data/README.md +30 -21
  6. data/Rakefile +5 -1
  7. data/acceptance/.gitignore +2 -0
  8. data/acceptance/Gemfile +10 -0
  9. data/acceptance/Gemfile.lock +57 -0
  10. data/acceptance/current/.acceptance/acceptance-cookbook/.chef/config.rb +1 -0
  11. data/acceptance/current/.acceptance/acceptance-cookbook/metadata.rb +1 -0
  12. data/acceptance/current/.acceptance/acceptance-cookbook/recipes/destroy.rb +3 -0
  13. data/acceptance/current/.acceptance/acceptance-cookbook/recipes/provision.rb +1 -0
  14. data/acceptance/current/.acceptance/acceptance-cookbook/recipes/verify.rb +3 -0
  15. data/acceptance/current/.kitchen.yml +45 -0
  16. data/lib/mixlib/install.rb +50 -173
  17. data/lib/mixlib/install/artifact_info.rb +76 -0
  18. data/lib/mixlib/install/backend.rb +36 -0
  19. data/lib/mixlib/install/backend/artifactory.rb +90 -0
  20. data/lib/mixlib/install/backend/omnitruck.rb +76 -0
  21. data/lib/mixlib/install/generator.rb +28 -0
  22. data/lib/mixlib/install/generator/bourne.rb +62 -0
  23. data/lib/mixlib/install/generator/bourne/scripts/fetch_metadata.sh +47 -0
  24. data/lib/mixlib/install/generator/bourne/scripts/fetch_package.sh +53 -0
  25. data/lib/mixlib/install/generator/bourne/scripts/helpers.sh +335 -0
  26. data/lib/mixlib/install/generator/bourne/scripts/install_package.sh +33 -0
  27. data/lib/mixlib/install/generator/bourne/scripts/platform_detection.sh +157 -0
  28. data/lib/mixlib/install/options.rb +98 -0
  29. data/lib/mixlib/install/script_generator.rb +217 -0
  30. data/lib/mixlib/install/version.rb +1 -1
  31. data/mixlib-install.gemspec +5 -3
  32. data/support/install_command.ps1 +4 -4
  33. metadata +71 -5
@@ -0,0 +1,76 @@
1
+ #
2
+ # Author:: Patrick Wright (<patrick@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ module Mixlib
20
+ class Install
21
+ class ArtifactInfo
22
+ attr_accessor :url
23
+ attr_accessor :md5
24
+ attr_accessor :sha256
25
+ attr_accessor :version
26
+
27
+ attr_accessor :platform
28
+ attr_accessor :platform_version
29
+ attr_accessor :architecture
30
+
31
+ def initialize(data)
32
+ @url = data[:url]
33
+ @md5 = data[:md5]
34
+ @sha256 = data[:sha256]
35
+ @version = data[:version]
36
+ @platform = data[:platform]
37
+ @platform_version = data[:platform_version]
38
+ @architecture = data[:architecture]
39
+ end
40
+
41
+ def self.from_json(json, platform_info)
42
+ ArtifactInfo.new(JSON.parse(json, symbolize_names: true).merge(platform_info))
43
+ end
44
+
45
+ def self.from_metadata_map(json)
46
+ artifacts = []
47
+
48
+ JSON.parse(json, symbolize_names: true).each do |p, p_data|
49
+ p_data.each do |pv, pv_data|
50
+ pv_data.each do |m, metadata|
51
+ artifacts << ArtifactInfo.new(metadata.merge(
52
+ platform: p,
53
+ platform_version: pv,
54
+ architecture: m
55
+ ))
56
+ end
57
+ end
58
+ end
59
+
60
+ artifacts
61
+ end
62
+
63
+ def to_hash
64
+ {
65
+ url: url,
66
+ md5: md5,
67
+ sha256: sha256,
68
+ version: version,
69
+ platform: platform,
70
+ platform_version: platform_version,
71
+ architecture: architecture
72
+ }
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,36 @@
1
+ #
2
+ # Author:: Patrick Wright (<patrick@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require "mixlib/install/backend/omnitruck"
20
+ require "mixlib/install/backend/artifactory"
21
+
22
+ module Mixlib
23
+ class Install
24
+ class Backend
25
+ def self.info(options)
26
+ backend = if options.for_omnitruck?
27
+ Backend::Omnitruck.new(options)
28
+ elsif options.for_artifactory?
29
+ Backend::Artifactory.new(options)
30
+ end
31
+
32
+ backend.info
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,90 @@
1
+ #
2
+ # Author:: Patrick Wright (<patrick@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require "net/http"
20
+ require "json"
21
+ require "mixlib/install/artifact_info"
22
+ require "artifactory"
23
+
24
+ module Mixlib
25
+ class Install
26
+ class Backend
27
+ class Artifactory
28
+ ARTIFACTORY_ENDPOINT = "http://artifactory.chef.co".freeze
29
+
30
+ attr_reader :options
31
+ attr_reader :client
32
+
33
+ def initialize(options)
34
+ @options = options
35
+ @client = ::Artifactory::Client.new(endpoint: ARTIFACTORY_ENDPOINT)
36
+ end
37
+
38
+ def info
39
+ begin
40
+ results = client.get("/api/search/prop", params, headers)["results"]
41
+ rescue Errno::ETIMEDOUT => e
42
+ raise e, "unstable channel uses endpoint #{ARTIFACTORY_ENDPOINT} \
43
+ which is currently only accessible through Chef's internal network."
44
+ end
45
+
46
+ if options.platform
47
+ artifact(results.first)
48
+ else
49
+ results.collect do |result|
50
+ artifact(result)
51
+ end
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def artifact(result)
58
+ ArtifactInfo.new(
59
+ md5: result["properties"]["omnibus.md5"].first,
60
+ sha256: result["properties"]["omnibus.sha256"].first,
61
+ version: result["properties"]["omnibus.version"].first,
62
+ platform: result["properties"]["omnibus.platform"].first,
63
+ platform_version: result["properties"]["omnibus.platform_version"].first,
64
+ architecture: result["properties"]["omnibus.architecture"].first,
65
+ url: result["uri"]
66
+ )
67
+ end
68
+
69
+ def params
70
+ params = {
71
+ "repos" => "omnibus-current-local",
72
+ "omnibus.version" => options.product_version
73
+ }
74
+
75
+ if options.platform
76
+ params["omnibus.platform"] = options.platform
77
+ params["omnibus.platform_version"] = options.platform_version
78
+ params["omnibus.architecture"] = options.architecture
79
+ end
80
+
81
+ params
82
+ end
83
+
84
+ def headers
85
+ { "X-Result-Detail" => "properties" }
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,76 @@
1
+ #
2
+ # Author:: Patrick Wright (<patrick@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require "net/http"
20
+ require "json"
21
+ require "mixlib/install/artifact_info"
22
+
23
+ module Mixlib
24
+ class Install
25
+ class Backend
26
+ class Omnitruck
27
+ OMNITRUCK_ENDPOINT = "https://omnitruck.chef.io"
28
+
29
+ attr_accessor :options
30
+
31
+ def initialize(options)
32
+ @options = options
33
+ end
34
+
35
+ def info
36
+ # If we are querying a single platform we need to call metadata
37
+ # endpoint otherwise we need to call versions endpoint in omnitruck
38
+ if options.platform
39
+ build = omnitruck_get("metadata", p: options.platform,
40
+ pv: options.platform_version,
41
+ m: options.architecture,
42
+ v: options.product_version
43
+ )
44
+ ArtifactInfo.from_json(build,
45
+ platform: options.platform,
46
+ platform_version: options.platform_version,
47
+ architecture: options.architecture
48
+ )
49
+ else
50
+ builds = omnitruck_get("versions", v: options.product_version)
51
+ ArtifactInfo.from_metadata_map(builds)
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def omnitruck_get(resource, parameters)
58
+ uri = URI.parse(OMNITRUCK_ENDPOINT)
59
+ http = Net::HTTP.new(uri.host, uri.port)
60
+ http.use_ssl = (uri.scheme == "https")
61
+
62
+ path = "/#{options.channel}/#{options.product_name}/#{resource}"
63
+ full_path = [path, URI.encode_www_form(parameters)].join("?")
64
+ request = Net::HTTP::Get.new(full_path)
65
+ request["Accept"] = "application/json"
66
+
67
+ res = http.request(request)
68
+
69
+ # Raise if response is not 2XX
70
+ res.value
71
+ res.body
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,28 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2015 Chef, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require "mixlib/install/generator/bourne"
19
+
20
+ module Mixlib
21
+ class Install
22
+ class Generator
23
+ def self.install_command(options)
24
+ Bourne.new(options).install_command
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,62 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2015 Chef, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ module Mixlib
19
+ class Install
20
+ class Generator
21
+ class Bourne
22
+ attr_reader :options
23
+
24
+ def initialize(options)
25
+ @options = options
26
+ end
27
+
28
+ def install_command
29
+ install_command = []
30
+ install_command << get_script(:helpers)
31
+ install_command << render_variables
32
+ install_command << get_script(:platform_detection)
33
+ if options.for_artifactory?
34
+ install_command << artifactory_urls
35
+ else
36
+ install_command << get_script(:fetch_metadata)
37
+ end
38
+ install_command << get_script(:fetch_package)
39
+ install_command << get_script(:install_package)
40
+
41
+ install_command.join("\n\n")
42
+ end
43
+
44
+ def render_variables
45
+ <<EOS
46
+ project=#{options.product_name}
47
+ version=#{options.product_version}
48
+ channel=#{options.channel}
49
+ EOS
50
+ end
51
+
52
+ def artifactory_urls
53
+ raise "not implemented yet"
54
+ end
55
+
56
+ def get_script(name)
57
+ File.read(File.join(File.dirname(__FILE__), "bourne/scripts/#{name}.sh"))
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,47 @@
1
+ # fetch_metadata.sh
2
+ ############
3
+ # This section calls omnitruck to get the information about the build to be
4
+ # installed.
5
+ #
6
+ # Inputs:
7
+ # $channel:
8
+ # $project:
9
+ # $version:
10
+ # $platform:
11
+ # $platform_version:
12
+ # $machine:
13
+ # $tmp_dir:
14
+ #
15
+ # Outputs:
16
+ # $download_url:
17
+ # $sha256:
18
+ # $md5:
19
+ ############
20
+
21
+ echo "Getting information for $project $channel $version for $platform..."
22
+
23
+ metadata_filename="$tmp_dir/metadata.txt"
24
+ metadata_url="https://omnitruck.chef.io/$channel/$project/metadata?v=$version&p=$platform&pv=$platform_version&m=$machine"
25
+
26
+ do_download "$metadata_url" "$metadata_filename"
27
+
28
+ cat "$metadata_filename"
29
+
30
+ # check that all the mandatory fields in the downloaded metadata are there
31
+ if grep '^url' $metadata_filename > /dev/null && grep '^sha256' $metadata_filename > /dev/null && grep '^md5' $metadata_filename > /dev/null; then
32
+ echo "downloaded metadata file looks valid..."
33
+ else
34
+ echo "downloaded metadata file is corrupted or an uncaught error was encountered in downloading the file..."
35
+ # this generally means one of the download methods downloaded a 404 or something like that and then reported a successful exit code,
36
+ # and this should be fixed in the function that was doing the download.
37
+ report_bug
38
+ exit 1
39
+ fi
40
+
41
+ download_url=`awk '$1 == "url" { print $2 }' "$metadata_filename"`
42
+ sha256=`awk '$1 == "sha256" { print $2 }' "$metadata_filename"`
43
+ md5=`awk '$1 == "md5" { print $2 }' "$metadata_filename"`
44
+
45
+ ############
46
+ # end of fetch_metadata.sh
47
+ ############
@@ -0,0 +1,53 @@
1
+ # fetch_package.sh
2
+ ############
3
+ # This section fetchs a package from $download_url and verifies its metadata.
4
+ #
5
+ # Inputs:
6
+ # $download_url:
7
+ # $tmp_dir:
8
+ # Optional Inputs:
9
+ # $cmdline_filename: Name of the package downloaded on local disk.
10
+ # $cmdline_dl_dir: Name of the directory downloaded package will be saved to on local disk.
11
+ #
12
+ # Outputs:
13
+ # $download_filename: Name of the downloaded file on local disk.
14
+ # $filetype: Type of the file downloaded.
15
+ ############
16
+
17
+ filename=`echo $download_url | sed -e 's/^.*\///'`
18
+ filetype=`echo $filename | sed -e 's/^.*\.//'`
19
+
20
+ # use either $tmp_dir, the provided directory (-d) or the provided filename (-f)
21
+ if test "x$cmdline_filename" != "x"; then
22
+ download_filename="$cmdline_filename"
23
+ elif test "x$cmdline_dl_dir" != "x"; then
24
+ download_filename="$cmdline_dl_dir/$filename"
25
+ else
26
+ download_filename="$tmp_dir/$filename"
27
+ fi
28
+
29
+ # ensure the parent directory where to download the installer always exists
30
+ download_dir=`dirname $download_filename`
31
+ (umask 077 && mkdir -p $download_dir) || exit 1
32
+
33
+ # check if we have that file locally available and if so verify the checksum
34
+ cached_file_available="false"
35
+ if test -f $download_filename; then
36
+ echo "$download_filename already exists, verifiying checksum..."
37
+ if do_checksum "$download_filename" "$sha256" "$md5"; then
38
+ echo "checksum compare succeeded, using existing file!"
39
+ cached_file_available="true"
40
+ else
41
+ echo "checksum mismatch, downloading latest version of the file"
42
+ fi
43
+ fi
44
+
45
+ # download if no local version of the file available
46
+ if test "x$cached_file_available" != "xtrue"; then
47
+ do_download "$download_url" "$download_filename"
48
+ do_checksum "$download_filename" "$sha256" "$md5" || checksum_mismatch
49
+ fi
50
+
51
+ ############
52
+ # end of fetch_package.sh
53
+ ############