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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 44b48b3b10f12bd9546d4d5c24c8b1dc632b215b
4
- data.tar.gz: 34b56d0d2c05de9adba3e9e91d40783c040b43e1
3
+ metadata.gz: 1988cb752e5752ed1b0c356f95c821e1d3376570
4
+ data.tar.gz: 4a85a7442cc38bc55df9136f736eea91d6bd7bcd
5
5
  SHA512:
6
- metadata.gz: e2a3813bcc897d90da0ada2c2c94910d5da49ce624d8ec930996556e768bfa8bf51aa5969ddd7bd89910287777ac700ab6b82092862dead759ed0a9bd8889ebe
7
- data.tar.gz: b5efb4ed22f94acbc36d13a948d49465394e9581b1a7aa2ef8aae1a596f851144ee29760816dc90faf437112ffec448d9c0eddfee95149fd528aa3a9bba35cd2
6
+ metadata.gz: 5464fd31ead9f86d3665c156cafe93b72ca7413fa7f34911aaee22bfcbf9ed9ed2858ae78064387a7f49db5d0b5e04e4498107a1a1d8012ee2f77f10b5655472
7
+ data.tar.gz: b3867d25ee74bb1d72e418a135dfe7b881601fec995319ca139f7e9721da37d749340570055dc1901de55b9682bb5e22de10404861346af4202d9a3bacb1d8df
data/.gitignore CHANGED
@@ -8,3 +8,6 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  tags
11
+ .ruby-version
12
+ .kitchen/
13
+ .kitchen.local.yml
@@ -0,0 +1,14 @@
1
+ This project is maintained by the contribution guidelines identified for
2
+ [chef](https://github.com/chef/chef) project. You can find the guidelines here:
3
+
4
+ https://github.com/chef/chef/blob/master/CONTRIBUTING.md
5
+
6
+ Pull requests in this project are merged when they have two :+1:s from maintainers.
7
+
8
+ ## Maintainers
9
+
10
+
11
+ - [Thom May](https://github.com/thommay)
12
+ - [Patrick Wright](https://github.com/patrick-wright)
13
+ - [Serdar Sutay](https://github.com/sersut)
14
+ - [Seth Chisamore](https://github.com/schisamo)
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gem "finstyle"
4
+
4
5
  gemspec
data/README.md CHANGED
@@ -1,34 +1,43 @@
1
1
  # Mixlib::Install
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/mixlib/install`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
6
-
7
- ## Installation
8
-
9
- Add this line to your application's Gemfile:
3
+ ## Usage
10
4
 
5
+ ### Get URL for specific platform and package version
11
6
  ```ruby
12
- gem 'mixlib-install'
7
+ options = {
8
+ channel: :current,
9
+ product_name: 'chef',
10
+ product_version: :latest,
11
+ platform: 'mac_os_x',
12
+ platform_version: '10.9',
13
+ architecture: 'x86_64'
14
+ }
15
+
16
+ artifact = Mixlib::Install.new(options).artifact_info
17
+ # => ArtifactInfo
18
+
19
+ artifact.url
20
+ # => "http://opscode-omnibus-packages-current.s3.amazonaws.com/mac_os_x/10.9/x86_64/chef-12.5.1%2B20151009083009-1.dmg"
13
21
  ```
14
22
 
15
- And then execute:
16
-
17
- $ bundle
18
-
19
- Or install it yourself as:
20
-
21
- $ gem install mixlib-install
22
-
23
- ## Usage
23
+ ### Get list of artifacts for all platforms given a package version
24
+ ```ruby
25
+ options = {
26
+ channel: :current,
27
+ product_name: 'chef',
28
+ product_version: :latest
29
+ }
24
30
 
25
- TODO: Write usage instructions here
31
+ artifacts = Mixlib::Install.new(options).artifact_info
32
+ # => Array<ArtifactInfo>
26
33
 
27
- ## Development
34
+ artifacts.first.url
35
+ # => "http://opscode-omnibus-packages-current.s3.amazonaws.com/mac_os_x/10.9/x86_64/chef-12.5.1%2B20151009083009-1.dmg"
36
+ ```
28
37
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
30
38
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
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`.
32
41
 
33
42
  ## Contributing
34
43
 
data/Rakefile CHANGED
@@ -3,13 +3,17 @@ require "finstyle"
3
3
  require "rubocop/rake_task"
4
4
  require "rspec/core/rake_task"
5
5
 
6
- task default: :spec
6
+ task default: :test
7
7
 
8
8
  desc "Run specs"
9
9
  RSpec::Core::RakeTask.new(:spec) do |spec|
10
10
  spec.pattern = "spec/**/*_spec.rb"
11
11
  end
12
12
 
13
+ desc "Run rubocop"
13
14
  RuboCop::RakeTask.new do |task|
14
15
  task.options << "--display-cop-names"
15
16
  end
17
+
18
+ desc "Run all tests"
19
+ task test: [:rubocop, :spec]
@@ -0,0 +1,2 @@
1
+ local-mode-cache/
2
+ nodes/
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "mixlib-install", path: "../"
4
+ gem "test-kitchen", github: "sersut/test-kitchen"
5
+ gem "chef-acceptance", github: "chef/chef-acceptance"
6
+ gem "pry"
7
+
8
+ group(:development) do
9
+ gem "kitchen-vagrant"
10
+ end
@@ -0,0 +1,57 @@
1
+ GIT
2
+ remote: git://github.com/chef/chef-acceptance.git
3
+ revision: 2d1a192851a3731cb61f794d155ad2b156cdaec5
4
+ specs:
5
+ chef-acceptance (0.2.0)
6
+ thor (~> 0.19)
7
+
8
+ GIT
9
+ remote: git://github.com/sersut/test-kitchen.git
10
+ revision: 5e4fa6baff5d51dc983be3f7b67ffe1bcbf2a8d2
11
+ specs:
12
+ test-kitchen (1.4.3.dev.0)
13
+ mixlib-install (~> 0.7)
14
+ mixlib-shellout (>= 1.2, < 3.0)
15
+ net-scp (~> 1.1)
16
+ net-ssh (~> 2.7, < 2.10)
17
+ safe_yaml (~> 1.0)
18
+ thor (~> 0.18)
19
+
20
+ PATH
21
+ remote: ../
22
+ specs:
23
+ mixlib-install (0.8.0)
24
+ artifactory (~> 2.3.0)
25
+
26
+ GEM
27
+ remote: https://rubygems.org/
28
+ specs:
29
+ artifactory (2.3.1)
30
+ coderay (1.1.0)
31
+ kitchen-vagrant (0.19.0)
32
+ test-kitchen (~> 1.4)
33
+ method_source (0.8.2)
34
+ mixlib-shellout (2.2.3)
35
+ net-scp (1.2.1)
36
+ net-ssh (>= 2.6.5)
37
+ net-ssh (2.9.2)
38
+ pry (0.10.3)
39
+ coderay (~> 1.1.0)
40
+ method_source (~> 0.8.1)
41
+ slop (~> 3.4)
42
+ safe_yaml (1.0.4)
43
+ slop (3.6.0)
44
+ thor (0.19.1)
45
+
46
+ PLATFORMS
47
+ ruby
48
+
49
+ DEPENDENCIES
50
+ chef-acceptance!
51
+ kitchen-vagrant
52
+ mixlib-install!
53
+ pry
54
+ test-kitchen!
55
+
56
+ BUNDLED WITH
57
+ 1.10.6
@@ -0,0 +1 @@
1
+ cookbook_path File.join(File.dirname(__FILE__), '..', '..')
@@ -0,0 +1 @@
1
+ name 'acceptance-cookbook'
@@ -0,0 +1,3 @@
1
+ execute 'kitchen destroy' do
2
+ cwd File.join(File.dirname(__FILE__), "../../../../../../../..")
3
+ end
@@ -0,0 +1,3 @@
1
+ execute 'kitchen verify' do
2
+ cwd File.join(File.dirname(__FILE__), "../../../../../../../..")
3
+ end
@@ -0,0 +1,45 @@
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
+ product_name: chef
11
+ product_version: latest
12
+ channel: current
13
+
14
+ platforms:
15
+ - name: centos-6.5
16
+ run_list:
17
+ # - name: debian-7.4
18
+ # run_list:
19
+ # - name: freebsd-10.0
20
+ # run_list:
21
+ - name: ubuntu-14.04
22
+ 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
32
+
33
+ suites:
34
+ - name: mixlib-install-chef
35
+ provisioner:
36
+ product_name: chef
37
+ product_version: latest
38
+ channel: current
39
+ run_list:
40
+ # - name: mixlib-install-chefdk
41
+ # provisioner:
42
+ # product_name: chefdk
43
+ # product_version: latest
44
+ # channel: current
45
+ # run_list:
@@ -1,5 +1,6 @@
1
1
  #
2
2
  # Author:: Thom May (<thom@chef.io>)
3
+ # Author:: Patrick Wright (<patrick@chef.io>)
3
4
  # Copyright:: Copyright (c) 2015 Chef, Inc.
4
5
  # License:: Apache License, Version 2.0
5
6
  #
@@ -16,200 +17,76 @@
16
17
  # limitations under the License.
17
18
  #
18
19
 
19
- require "mixlib/install/util"
20
- require "cgi"
20
+ require "mixlib/versioning"
21
+
22
+ require "mixlib/install/backend"
23
+ require "mixlib/install/options"
24
+ require "mixlib/install/generator"
21
25
 
22
26
  module Mixlib
23
27
  class Install
24
- attr_accessor :version
25
-
26
- attr_accessor :powershell
27
-
28
- attr_accessor :prerelease
29
-
30
- attr_accessor :nightlies
31
-
32
- attr_accessor :install_flags
33
-
34
- attr_accessor :endpoint
35
28
 
36
- attr_accessor :root
29
+ attr_reader :options
37
30
 
38
- attr_accessor :use_sudo
39
-
40
- attr_reader :sudo_command
41
-
42
- def sudo_command=(cmd)
43
- if cmd.nil?
44
- @use_sudo = false
45
- else
46
- @sudo_command = cmd
47
- end
31
+ def initialize(options = {})
32
+ @options = Options.new(options)
48
33
  end
49
34
 
50
- attr_accessor :http_proxy
51
- attr_accessor :https_proxy
52
-
53
- attr_accessor :omnibus_url
54
- attr_accessor :install_msi_url
55
-
56
- VALID_INSTALL_OPTS = %w(omnibus_url
57
- endpoint
58
- http_proxy
59
- https_proxy
60
- install_flags
61
- install_msi_url
62
- nightlies
63
- prerelease
64
- project
65
- root
66
- use_sudo
67
- sudo_command)
68
-
69
- def initialize(version, powershell = false, opts = {})
70
- @version = version || "latest"
71
- @powershell = powershell
72
- @http_proxy = nil
73
- @https_proxy = nil
74
- @install_flags = nil
75
- @prerelease = false
76
- @nightlies = false
77
- @endpoint = "metadata"
78
- @omnibus_url = "https://www.chef.io/chef/install.sh"
79
- @use_sudo = true
80
- @sudo_command = "sudo -E"
81
-
82
- @root = if powershell
83
- "$env:systemdrive\\opscode\\chef"
84
- else
85
- "/opt/chef"
86
- end
87
-
88
- parse_opts(opts)
35
+ #
36
+ # Fetch artifact metadata information
37
+ #
38
+ # @return [ArtifactInfo] fetched artifact data
39
+ #
40
+ def artifact_info
41
+ Backend.info(options)
89
42
  end
90
43
 
44
+ #
45
+ # Returns an install script for the given options
46
+ #
47
+ # @return [String] script for installing with given options
48
+ #
91
49
  def install_command
92
- vars = if powershell
93
- install_command_vars_for_powershell
94
- else
95
- install_command_vars_for_bourne
96
- end
97
- shell_code_from_file(vars)
50
+ Generator.install_command(options)
98
51
  end
99
52
 
100
- private
101
-
102
- # Generates the install command variables for Bourne shell-based
103
- # platforms.
104
53
  #
105
- # @return [String] shell variable lines
106
- # @api private
107
- def install_command_vars_for_bourne
108
- flags = %w[latest true nightlies].include?(version) ? "" : "-v #{CGI.escape(version)}"
109
- flags << " " << "-n" if nightlies
110
- flags << " " << "-p" if prerelease
111
- flags << " " << install_flags if install_flags
112
-
113
- [
114
- shell_var("chef_omnibus_root", root),
115
- shell_var("chef_omnibus_url", omnibus_url),
116
- shell_var("install_flags", flags.strip),
117
- shell_var("pretty_version", Util.pretty_version(version)),
118
- shell_var("sudo_sh", sudo("sh")),
119
- shell_var("version", version)
120
- ].join("\n")
121
- end
122
-
123
- # Generates the install command variables for PowerShell-based platforms.
54
+ # Returns the base installation directory for the given options
124
55
  #
125
- # @param version [String] version string
126
- # @param metadata_url [String] The metadata URL for the Chef Omnitruck API server
127
- # @param omnibus_root [String] The base directory the project is installed to
128
- # @return [String] shell variable lines
129
- # @api private
130
- def install_command_vars_for_powershell
131
- [
132
- shell_var("chef_omnibus_root", root),
133
- shell_var("msi", "$env:TEMP\\chef-#{version}.msi"),
134
- ].tap { |vars|
135
- if install_msi_url
136
- vars << shell_var("chef_msi_url", install_msi_url)
137
- else
138
- vars << shell_var("chef_metadata_url", windows_metadata_url)
139
- vars << shell_var("pretty_version", Util.pretty_version(version))
140
- vars << shell_var("version", version)
141
- end
142
- }.join("\n")
143
- end
144
-
145
- def validate_opts!(opt)
146
- err_msg = ["#{opt} is not a valid option",
147
- "valid options are #{VALID_INSTALL_OPTS.join(' ')}"].join(',')
148
- fail ArgumentError, err_msg unless VALID_INSTALL_OPTS.include?(opt.to_s)
149
- end
150
-
151
- # rubocop:disable Metrics/MethodLength
152
- def parse_opts(opts)
153
- opts.each do |opt, setting|
154
- validate_opts!(opt)
155
- case opt.to_s
156
- when 'project', 'endpoint'
157
- self.endpoint = metadata_endpoint_from_project(setting)
158
- else
159
- send("#{opt.to_sym}=", setting)
160
- end
161
- end
162
- end
163
-
164
- def shell_code_from_file(vars)
165
- fn = File.join(
166
- File.dirname(__FILE__),
167
- %w[.. .. support],
168
- "install_command"
169
- )
170
- Util.shell_code_from_file(vars, fn, powershell,
171
- http_proxy: http_proxy, https_proxy: https_proxy)
172
- end
173
-
174
- # Builds a shell variable assignment string for the required shell type.
56
+ # @return [String] the installation directory for the project
175
57
  #
176
- # @param name [String] variable name
177
- # @param value [String] variable value
178
- # @return [String] shell variable assignment
179
- # @api private
180
- def shell_var(name, value)
181
- Util.shell_var(name, value, powershell)
182
- end
183
-
184
- # @return the correct Chef Omnitruck API metadata endpoint, based on project
185
- def metadata_endpoint_from_project(project = nil)
186
- if project.nil? || project.downcase == "chef"
187
- "metadata"
188
- else
189
- "metadata-#{project.downcase}"
190
- end
58
+ def root
59
+ # TODO: Support root as "$env:systemdrive\\opscode\\chef" when on windows.
60
+ # This only works for chef and chefdk but they are the only projects
61
+ # we are supporting as of now.
62
+ "/opt/#{options.product_name}"
191
63
  end
192
64
 
193
- def windows_metadata_url
194
- base = if omnibus_url =~ %r{/install.sh$}
195
- "#{File.dirname(omnibus_url)}/"
65
+ #
66
+ # Returns the current version of the installed product.
67
+ # Returns nil if the product is not installed.
68
+ #
69
+ def current_version
70
+ # Note that this logic does not work for products other than
71
+ # chef & chefdk since version-manifest is created under the
72
+ # install directory which can be different than the product name (e.g.
73
+ # chef-server -> /opt/opscode). But this is OK for now since
74
+ # chef & chefdk are the only supported products.
75
+ version_manifest_file = "/opt/#{options.product_name}/version-manifest.json"
76
+ if File.exist? version_manifest_file
77
+ JSON.parse(File.read(version_manifest_file))["build_version"]
196
78
  end
197
-
198
- url = "#{base}#{endpoint}"
199
- url << "?p=windows&m=x86_64&pv=2008r2" # same package for all versions
200
- url << "&v=#{CGI.escape(version.to_s.downcase)}"
201
- url << "&prerelease=true" if prerelease
202
- url << "&nightlies=true" if nightlies
203
- url
204
79
  end
205
80
 
206
- # Conditionally prefixes a command with a sudo command.
207
81
  #
208
- # @param command [String] command to be prefixed
209
- # @return [String] the command, conditionaly prefixed with sudo
210
- # @api private
211
- def sudo(script)
212
- use_sudo ? "#{sudo_command} #{script}" : script
82
+ # Returns true if an upgradable version is available, false otherwise.
83
+ #
84
+ def upgrade_available?
85
+ return true if current_version.nil?
86
+
87
+ available_ver = Mixlib::Versioning.parse(artifact_info.first.version)
88
+ current_ver = Mixlib::Versioning.parse(current_version)
89
+ (available_ver > current_ver)
213
90
  end
214
91
  end
215
92
  end