mixlib-install 0.8.0.alpha.2 → 0.8.0.alpha.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -2
  3. data/Rakefile +5 -0
  4. data/acceptance/Gemfile +3 -1
  5. data/acceptance/Gemfile.lock +37 -5
  6. data/acceptance/current/.acceptance/acceptance-cookbook/recipes/provision.rb +3 -1
  7. data/acceptance/current/.kitchen.yml +18 -23
  8. data/acceptance/unstable/.acceptance/acceptance-cookbook/.gitignore +2 -0
  9. data/acceptance/unstable/.acceptance/acceptance-cookbook/metadata.rb +1 -0
  10. data/acceptance/unstable/.acceptance/acceptance-cookbook/recipes/destroy.rb +3 -0
  11. data/acceptance/unstable/.acceptance/acceptance-cookbook/recipes/provision.rb +3 -0
  12. data/acceptance/unstable/.acceptance/acceptance-cookbook/recipes/verify.rb +3 -0
  13. data/acceptance/unstable/.kitchen.yml +40 -0
  14. data/lib/mixlib/install.rb +35 -3
  15. data/lib/mixlib/install/backend/artifactory.rb +108 -34
  16. data/lib/mixlib/install/backend/omnitruck.rb +2 -2
  17. data/lib/mixlib/install/generator.rb +6 -1
  18. data/lib/mixlib/install/generator/base.rb +65 -0
  19. data/lib/mixlib/install/generator/bourne.rb +23 -14
  20. data/lib/mixlib/install/generator/bourne/scripts/artifactory_urls.sh.erb +31 -0
  21. data/lib/mixlib/install/generator/bourne/scripts/{fetch_metadata.sh → fetch_metadata.sh.erb} +1 -1
  22. data/lib/mixlib/install/generator/bourne/scripts/helpers.sh +7 -2
  23. data/lib/mixlib/install/generator/bourne/scripts/platform_detection.sh +8 -0
  24. data/lib/mixlib/install/generator/bourne/scripts/script_cli_parameters.sh +36 -0
  25. data/lib/mixlib/install/generator/powershell.rb +94 -0
  26. data/lib/mixlib/install/generator/powershell/scripts/get_project_metadata.ps1.erb +87 -0
  27. data/lib/mixlib/install/generator/powershell/scripts/get_project_metadata_for_artifactory.ps1.erb +83 -0
  28. data/lib/mixlib/install/generator/powershell/scripts/helpers.ps1 +69 -0
  29. data/lib/mixlib/install/generator/powershell/scripts/install_project.ps1 +96 -0
  30. data/lib/mixlib/install/options.rb +86 -23
  31. data/lib/mixlib/install/version.rb +1 -1
  32. metadata +17 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40e1403861a8c56ae5bef0076ede1a889cece701
4
- data.tar.gz: eab4f0ae8dd1b27a235afd950015421fa7998345
3
+ metadata.gz: 7db151f3905eb7a527cf687018366832a80a2811
4
+ data.tar.gz: 6186b2ea33ee9a2809084e768a33dcb57c162f00
5
5
  SHA512:
6
- metadata.gz: 2434a31ab88a137f45b16df69bfdb61db9fe247a01a26f071977b87086164172ac46d9e144fbc679923f680f843eec408132d9f272901873fc55c96412281fbd
7
- data.tar.gz: e37efeda997e33f7095b3e49b39ce8fa7e9efd1f08e5ae065fa9594eff4d49dba22be2e1d077918ede15814038898a59e15c13e250a4f2147a25f739d0f12af6
6
+ metadata.gz: fc15e3ca92d5ad638a1e9a35ff30b8cd07a88ab091b26816eaebf1de9849db3e97ec88d98c4afdd9cd78eb723276b11e90698dcdf89847a3f87379319cf6caff
7
+ data.tar.gz: d98e85481f590f9e77357bfcf4223620bdfcd7ca623343b20f7a3f174e1b0350c720794b45249de50c9aafc0f964486b0b9608736f09ddeff9155a468b713aea
data/README.md CHANGED
@@ -35,9 +35,16 @@ artifacts.first.url
35
35
  # => "http://opscode-omnibus-packages-current.s3.amazonaws.com/mac_os_x/10.9/x86_64/chef-12.5.1%2B20151009083009-1.dmg"
36
36
  ```
37
37
 
38
+ ## Unstable channel
39
+ The `:unstable` channel is currently only available when connected to Chef's internal network.
40
+ Configure Artifactory access by setting the following environment variables:
41
+ ```
42
+ export ARTIFACTORY_USERNAME='username'
43
+ export ARTIFACTORY_PASSWORD='password'
44
+ ```
38
45
 
39
- ## Test
40
- Some tests are tagged `:unstable` and can only run when connected to Chef's internal network. These are excluded by default. To run the `:unstable` tests run: `bundle exec rspec --tag unstable`.
46
+ ### Unstable channel specs
47
+ Some spec examples are tagged `:unstable` and can only run when connected to Chef's internal network. These are excluded by default. To run the `:unstable` tests run: `rake unstable`.
41
48
 
42
49
  ## Contributing
43
50
 
data/Rakefile CHANGED
@@ -18,6 +18,11 @@ end
18
18
  desc "Run all tests"
19
19
  task test: [:rubocop, :spec]
20
20
 
21
+ desc "Run unstable channel tests"
22
+ task "unstable" do
23
+ system("bundle exec rspec -t unstable")
24
+ end
25
+
21
26
  desc "Render product matrix documentation"
22
27
  task "matrix" do
23
28
  require "mixlib/install/product"
@@ -1,10 +1,12 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gem "mixlib-install", path: "../"
4
- gem "test-kitchen", github: "sersut/test-kitchen"
4
+ gem "test-kitchen", github: "sersut/test-kitchen", branch: "sersut/mixlib-install-update"
5
5
  gem "chef-acceptance", github: "chef/chef-acceptance"
6
6
  gem "pry"
7
7
 
8
8
  group(:development) do
9
9
  gem "kitchen-vagrant"
10
+ gem "windows_chef_zero"
11
+ gem "winrm-transport"
10
12
  end
@@ -1,16 +1,16 @@
1
1
  GIT
2
2
  remote: git://github.com/chef/chef-acceptance.git
3
- revision: e28d67891b0359af83836ec55c91eb07e8b062d1
3
+ revision: 47f5f54e561981802122168ca01ae03907965312
4
4
  specs:
5
5
  chef-acceptance (0.2.0)
6
6
  thor (~> 0.19)
7
7
 
8
8
  GIT
9
9
  remote: git://github.com/sersut/test-kitchen.git
10
- revision: 5e4fa6baff5d51dc983be3f7b67ffe1bcbf2a8d2
10
+ revision: fd05389ec556fdcac96b92b1aea2a9ed48802e75
11
+ branch: sersut/mixlib-install-update
11
12
  specs:
12
13
  test-kitchen (1.4.3.dev.0)
13
- mixlib-install (~> 0.7)
14
14
  mixlib-shellout (>= 1.2, < 3.0)
15
15
  net-scp (~> 1.1)
16
16
  net-ssh (~> 2.7, < 2.10)
@@ -20,7 +20,7 @@ GIT
20
20
  PATH
21
21
  remote: ../
22
22
  specs:
23
- mixlib-install (0.8.0.alpha.0)
23
+ mixlib-install (0.8.0.alpha.2)
24
24
  artifactory (~> 2.3.0)
25
25
  mixlib-versioning (~> 1.1.0)
26
26
 
@@ -28,22 +28,52 @@ GEM
28
28
  remote: https://rubygems.org/
29
29
  specs:
30
30
  artifactory (2.3.2)
31
+ builder (3.2.2)
31
32
  coderay (1.1.0)
33
+ ffi (1.9.10)
34
+ gssapi (1.2.0)
35
+ ffi (>= 1.0.1)
36
+ gyoku (1.3.1)
37
+ builder (>= 2.1.2)
38
+ httpclient (2.7.0.1)
32
39
  kitchen-vagrant (0.19.0)
33
40
  test-kitchen (~> 1.4)
41
+ little-plugger (1.1.4)
42
+ logging (2.0.0)
43
+ little-plugger (~> 1.1)
44
+ multi_json (~> 1.10)
34
45
  method_source (0.8.2)
35
- mixlib-shellout (2.2.3)
46
+ mixlib-shellout (2.2.5)
36
47
  mixlib-versioning (1.1.0)
48
+ multi_json (1.11.2)
37
49
  net-scp (1.2.1)
38
50
  net-ssh (>= 2.6.5)
39
51
  net-ssh (2.9.2)
52
+ nori (2.6.0)
40
53
  pry (0.10.3)
41
54
  coderay (~> 1.1.0)
42
55
  method_source (~> 0.8.1)
43
56
  slop (~> 3.4)
57
+ rubyntlm (0.4.0)
58
+ rubyzip (1.1.7)
44
59
  safe_yaml (1.0.4)
45
60
  slop (3.6.0)
46
61
  thor (0.19.1)
62
+ uuidtools (2.1.5)
63
+ windows_chef_zero (2.0.0)
64
+ test-kitchen (>= 1.2.1)
65
+ winrm (1.3.6)
66
+ builder (>= 2.1.2)
67
+ gssapi (~> 1.2)
68
+ gyoku (~> 1.0)
69
+ httpclient (~> 2.2, >= 2.2.0.2)
70
+ logging (>= 1.6.1, < 3.0)
71
+ nori (~> 2.0)
72
+ rubyntlm (~> 0.4.0)
73
+ uuidtools (~> 2.1.2)
74
+ winrm-transport (1.0.3)
75
+ rubyzip (~> 1.1, >= 1.1.7)
76
+ winrm (~> 1.3)
47
77
 
48
78
  PLATFORMS
49
79
  ruby
@@ -54,6 +84,8 @@ DEPENDENCIES
54
84
  mixlib-install!
55
85
  pry
56
86
  test-kitchen!
87
+ windows_chef_zero
88
+ winrm-transport
57
89
 
58
90
  BUNDLED WITH
59
91
  1.10.6
@@ -1 +1,3 @@
1
- log 'provision recipe'
1
+ execute 'kitchen converge' do
2
+ cwd node['chef-acceptance']['suite-dir']
3
+ end
@@ -7,39 +7,34 @@ driver:
7
7
 
8
8
  provisioner:
9
9
  name: chef_zero
10
- product_name: chef
11
- product_version: latest
12
- channel: current
13
10
 
14
11
  platforms:
15
12
  - name: centos-6.5
16
13
  run_list:
17
- # - name: debian-7.4
18
- # run_list:
19
- # - name: freebsd-10.0
20
- # run_list:
14
+ - name: debian-7.4
15
+ run_list:
16
+ - name: freebsd-10.0
17
+ run_list:
21
18
  - name: ubuntu-14.04
22
19
  run_list:
23
- # - name: macosx-10.10
24
- # driver:
25
- # box: chef/macosx-10.10 # private
26
- # - name: windows-7-professional
27
- # provisioner:
28
- # name: windows_chef_zero
29
- # require_chef_omnibus: 11.12.4
30
- # driver:
31
- # box: chef/windows-7-professional # private
20
+ - name: macosx-10.10
21
+ driver:
22
+ box: chef/macosx-10.10 # private
23
+ - name: windows-server-2012r2-standard
24
+ driver:
25
+ box: chef/windows-server-2012r2-standard # private
32
26
 
33
27
  suites:
34
- - name: mixlib-install-chef
28
+ - name: chef-current-install
35
29
  provisioner:
36
30
  product_name: chef
37
31
  product_version: latest
38
32
  channel: current
39
33
  run_list:
40
- # - name: mixlib-install-chefdk
41
- # provisioner:
42
- # product_name: chefdk
43
- # product_version: latest
44
- # channel: current
45
- # run_list:
34
+ - name: chefdk-current-install
35
+ excludes: [ 'freebsd-10.0' ]
36
+ provisioner:
37
+ product_name: chefdk
38
+ product_version: latest
39
+ channel: current
40
+ run_list:
@@ -0,0 +1 @@
1
+ name 'acceptance-cookbook'
@@ -0,0 +1,3 @@
1
+ execute 'kitchen destroy' do
2
+ cwd node['chef-acceptance']['suite-dir']
3
+ end
@@ -0,0 +1,3 @@
1
+ execute 'kitchen converge' do
2
+ cwd node['chef-acceptance']['suite-dir']
3
+ end
@@ -0,0 +1,3 @@
1
+ execute 'kitchen verify' do
2
+ cwd node['chef-acceptance']['suite-dir']
3
+ end
@@ -0,0 +1,40 @@
1
+ driver:
2
+ name: vagrant
3
+ forward_agent: yes
4
+ customize:
5
+ cpus: 2
6
+ memory: 1024
7
+
8
+ provisioner:
9
+ name: chef_zero
10
+
11
+ platforms:
12
+ - name: centos-6.5
13
+ run_list:
14
+ - name: debian-7.4
15
+ run_list:
16
+ - name: freebsd-10.0
17
+ run_list:
18
+ - name: ubuntu-14.04
19
+ run_list:
20
+ - name: macosx-10.10
21
+ driver:
22
+ box: chef/macosx-10.10 # private
23
+ - name: windows-server-2012r2-standard
24
+ driver:
25
+ box: chef/windows-server-2012r2-standard # private
26
+
27
+ suites:
28
+ - name: chef-unstable-install
29
+ provisioner:
30
+ product_name: chef
31
+ product_version: latest
32
+ channel: unstable
33
+ run_list:
34
+ - name: chefdk-unstable-install
35
+ excludes: [ 'freebsd-10.0' ]
36
+ provisioner:
37
+ product_name: chefdk
38
+ product_version: latest
39
+ channel: unstable
40
+ run_list:
@@ -22,6 +22,8 @@ require "mixlib/versioning"
22
22
  require "mixlib/install/backend"
23
23
  require "mixlib/install/options"
24
24
  require "mixlib/install/generator"
25
+ require "mixlib/install/generator/bourne"
26
+ require "mixlib/install/generator/powershell"
25
27
 
26
28
  module Mixlib
27
29
  class Install
@@ -56,10 +58,13 @@ module Mixlib
56
58
  # @return [String] the installation directory for the project
57
59
  #
58
60
  def root
59
- # TODO: Support root as "$env:systemdrive\\opscode\\chef" when on windows.
60
61
  # This only works for chef and chefdk but they are the only projects
61
62
  # we are supporting as of now.
62
- "/opt/#{options.product_name}"
63
+ if options.for_ps1?
64
+ "$env:systemdrive\\opscode\\#{options.product_name}"
65
+ else
66
+ "/opt/#{options.product_name}"
67
+ end
63
68
  end
64
69
 
65
70
  #
@@ -72,7 +77,12 @@ module Mixlib
72
77
  # install directory which can be different than the product name (e.g.
73
78
  # chef-server -> /opt/opscode). But this is OK for now since
74
79
  # chef & chefdk are the only supported products.
75
- version_manifest_file = "/opt/#{options.product_name}/version-manifest.json"
80
+ version_manifest_file = if options.for_ps1?
81
+ "$env:systemdrive\\opscode\\#{options.product_name}\\version-manifest.json"
82
+ else
83
+ "/opt/#{options.product_name}/version-manifest.json"
84
+ end
85
+
76
86
  if File.exist? version_manifest_file
77
87
  JSON.parse(File.read(version_manifest_file))["build_version"]
78
88
  end
@@ -88,5 +98,27 @@ module Mixlib
88
98
  current_ver = Mixlib::Versioning.parse(current_version)
89
99
  (available_ver > current_ver)
90
100
  end
101
+
102
+ #
103
+ # Returns the install.sh script
104
+ # Supported context parameters:
105
+ # ------------------
106
+ # base_url [String]
107
+ # url pointing to the omnitruck to be queried by the script.
108
+ #
109
+ def self.install_sh(context = {})
110
+ Mixlib::Install::Generator::Bourne.install_sh(context)
111
+ end
112
+
113
+ #
114
+ # Returns the install.ps1 script
115
+ # Supported context parameters:
116
+ # ------------------
117
+ # base_url [String]
118
+ # url pointing to the omnitruck to be queried by the script.
119
+ #
120
+ def self.install_ps1(context = {})
121
+ Mixlib::Install::Generator::PowerShell.install_ps1(context)
122
+ end
91
123
  end
92
124
  end
@@ -25,64 +25,138 @@ module Mixlib
25
25
  class Install
26
26
  class Backend
27
27
  class Artifactory
28
- ARTIFACTORY_ENDPOINT = "http://artifactory.chef.co".freeze
28
+ class ConnectionError < StandardError; end
29
+ class AuthenticationError < StandardError; end
29
30
 
30
- attr_reader :options
31
- attr_reader :client
31
+ ENDPOINT = "http://artifactory.chef.co".freeze
32
+
33
+ attr_accessor :options
32
34
 
33
35
  def initialize(options)
34
36
  @options = options
35
- @client = ::Artifactory::Client.new(endpoint: ARTIFACTORY_ENDPOINT)
36
37
  end
37
38
 
39
+ # Create filtered list of artifacts
40
+ #
41
+ # @return [Array<ArtifactInfo>] list of artifacts for the configured
42
+ # channel, product name, and product version.
43
+ # @return [ArtifactInfo] arifact info for the configured
44
+ # channel, product name, product version and platform info
45
+ #
38
46
  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."
47
+ artifacts = artifactory_info.collect { |a| create_artifact(a) }
48
+
49
+ artifacts_for_version = artifacts.find_all do |a|
50
+ a.version == options.resolved_version(artifacts)
44
51
  end
45
52
 
46
53
  if options.platform
47
- artifact(results.first)
48
- else
49
- results.collect do |result|
50
- artifact(result)
54
+ artifacts_for_version.find do |a|
55
+ a.platform == options.platform &&
56
+ a.platform_version == options.platform_version &&
57
+ a.architecture == options.architecture
51
58
  end
59
+ else
60
+ artifacts_for_version
52
61
  end
53
62
  end
54
63
 
55
- private
64
+ # Fetches all artifacts from the configured Artifactory repository using
65
+ # channel and product name as search criteria
66
+ #
67
+ # @return [Array<Hash>] list of artifactory hash data
68
+ #
69
+ # Hash data:
70
+ # download_uri: The full url download path
71
+ # <property_name>: The names of the properties associcated to the artifact
72
+ #
73
+ def artifactory_info
74
+ query = <<-QUERY
75
+ items.find(
76
+ {"repo": "omnibus-#{options.channel}-local"},
77
+ {"@omnibus.project": "#{options.product_name}"}
78
+ ).include("repo", "path", "name", "property")
79
+ QUERY
56
80
 
57
- def artifact(result)
81
+ results = artifactory_request do
82
+ client.post("/api/search/aql", query, "Content-Type" => "text/plain")
83
+ end
84
+
85
+ # Merge artifactory properties and downloadUri to a flat Hash
86
+ results["results"].collect do |result|
87
+ { "downloadUri" => generate_download_uri(result) }.merge(
88
+ map_properties(result["properties"])
89
+ )
90
+ end
91
+ end
92
+
93
+ def create_artifact(artifact_map)
58
94
  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"]
95
+ md5: artifact_map["omnibus.md5"],
96
+ sha256: artifact_map["omnibus.sha256"],
97
+ version: artifact_map["omnibus.version"],
98
+ platform: artifact_map["omnibus.platform"],
99
+ platform_version: artifact_map["omnibus.platform_version"],
100
+ architecture: artifact_map["omnibus.architecture"],
101
+ url: artifact_map["downloadUri"]
66
102
  )
67
103
  end
68
104
 
69
- def params
70
- params = {
71
- "repos" => "omnibus-current-local",
72
- "omnibus.version" => options.product_version
73
- }
105
+ private
74
106
 
75
- if options.platform
76
- params["omnibus.platform"] = options.platform
77
- params["omnibus.platform_version"] = options.platform_version
78
- params["omnibus.architecture"] = options.architecture
107
+ # Converts Array<Hash> where the Hash is a key pair and
108
+ # value pair to a simplifed key/pair Hash
109
+ #
110
+ def map_properties(properties)
111
+ return {} if properties.nil?
112
+ properties.each_with_object({}) do |prop, h|
113
+ h[prop["key"]] = prop["value"]
79
114
  end
115
+ end
116
+
117
+ # Construct the downloadUri from raw artifactory data
118
+ #
119
+ def generate_download_uri(result)
120
+ uri = []
121
+ uri << endpoint.sub(/\/$/, "")
122
+ uri << result["repo"]
123
+ uri << result["path"]
124
+ uri << result["name"]
125
+ uri.join("/")
126
+ end
80
127
 
81
- params
128
+ def client
129
+ @client ||= ::Artifactory::Client.new(
130
+ endpoint: endpoint,
131
+ username: ENV["ARTIFACTORY_USERNAME"],
132
+ password: ENV["ARTIFACTORY_PASSWORD"]
133
+ )
82
134
  end
83
135
 
84
- def headers
85
- { "X-Result-Detail" => "properties" }
136
+ def endpoint
137
+ @endpoint ||= ENV.fetch("ARTIFACTORY_ENDPOINT", ENDPOINT)
138
+ end
139
+
140
+ def artifactory_request
141
+ begin
142
+ results = yield
143
+ rescue Errno::ETIMEDOUT, ::Artifactory::Error::ConnectionError
144
+ raise ConnectionError, <<-EOS
145
+ Artifactory endpoint '#{::Artifactory.endpoint}' is unreachable. Check that
146
+ the endpoint is correct and there is an open connection to Chef's private network.
147
+ EOS
148
+ rescue ::Artifactory::Error::HTTPError => e
149
+ if e.code == 401 && e.message =~ /Bad credentials/
150
+ raise AuthenticationError, <<-EOS
151
+ Artifactory server denied credentials. Verify ARTIFACTORY_USERNAME and
152
+ ARTIFACTORY_PASSWORD environment variables are configured properly.
153
+ EOS
154
+ else
155
+ raise e
156
+ end
157
+ end
158
+
159
+ results
86
160
  end
87
161
  end
88
162
  end