mixlib-install 0.7.1 → 0.8.0.alpha.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ ############