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
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