mixlib-install 1.1.0 → 1.2.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.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +9 -0
- data/Gemfile +0 -2
- data/PRODUCT_MATRIX.md +2 -1
- data/README.md +19 -0
- data/Rakefile +21 -3
- data/lib/mixlib/install.rb +17 -0
- data/lib/mixlib/install/backend.rb +12 -6
- data/lib/mixlib/install/backend/artifactory.rb +106 -17
- data/lib/mixlib/install/backend/base.rb +69 -0
- data/lib/mixlib/install/backend/bintray.rb +20 -60
- data/lib/mixlib/install/generator/bourne.rb +3 -1
- data/lib/mixlib/install/generator/bourne/scripts/helpers.sh +4 -0
- data/lib/mixlib/install/generator/bourne/scripts/platform_detection.sh +4 -0
- data/lib/mixlib/install/generator/powershell.rb +5 -3
- data/lib/mixlib/install/generator/powershell/scripts/helpers.ps1 +80 -13
- data/lib/mixlib/install/generator/powershell/scripts/install_project.ps1 +43 -7
- data/lib/mixlib/install/options.rb +4 -3
- data/lib/mixlib/install/product.rb +36 -1
- data/lib/mixlib/install/script_generator.rb +2 -3
- data/lib/mixlib/install/version.rb +1 -1
- data/mixlib-install.gemspec +2 -0
- data/support/install_command.ps1 +125 -23
- metadata +31 -4
- data/.rubocop.yml +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af96827b91f93939e6376192d760548132394e7e
|
4
|
+
data.tar.gz: 39e849c94aebecb08b7f0f5e4328aeb8a45cb038
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cb34501343fb8891d181076ef8c213d034cdcbad866fc758754fdf24830883660bbca4c77282b0006118d48f1c22748a74ec6aba3935482349ed0fe446ed8af
|
7
|
+
data.tar.gz: 7320f109233968d75a508f959fc3a5c71964c40eb7921563dd21a5c1cf353ed5a2a8103e04b2770755d1e05981c356f7504a5948c4eb9229453250cffceb656c
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [1.2.0]
|
4
|
+
- Fix omnibus project mappings
|
5
|
+
- Add `available_versions` method to API
|
6
|
+
- Add `chef-automate` product
|
7
|
+
- Add install support for Arista EOS
|
8
|
+
- Add p5p package support
|
9
|
+
- Add s390x architecture support
|
10
|
+
- Add Nano support
|
11
|
+
|
3
12
|
## [1.1.0]
|
4
13
|
- Remove delivery-cli from Product Matrix since we are now shipping it within ChefDK
|
5
14
|
|
data/Gemfile
CHANGED
data/PRODUCT_MATRIX.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
| Analytics Platform | analytics |
|
4
4
|
| Angry Omnibus Toolchain | angry-omnibus-toolchain |
|
5
5
|
| Angry Chef Client | angrychef |
|
6
|
+
| Chef Automate | automate |
|
6
7
|
| Chef Client | chef |
|
7
8
|
| Chef Backend | chef-backend |
|
8
9
|
| Chef Server | chef-server |
|
@@ -15,7 +16,7 @@
|
|
15
16
|
| Chef Cloud Marketplace addon | marketplace |
|
16
17
|
| Omnibus Toolchain | omnibus-toolchain |
|
17
18
|
| Enterprise Chef (legacy) | private-chef |
|
18
|
-
| Chef Push
|
19
|
+
| Chef Push Client | push-jobs-client |
|
19
20
|
| Chef Push Server | push-jobs-server |
|
20
21
|
| Chef Server Reporting addon | reporting |
|
21
22
|
| Supermarket | supermarket |
|
data/README.md
CHANGED
@@ -67,9 +67,28 @@ artifact.platform # => "ubuntu"
|
|
67
67
|
artifact.platform_version # => "14.04"
|
68
68
|
```
|
69
69
|
|
70
|
+
### List the available versions for a product and channel
|
71
|
+
```ruby
|
72
|
+
# Note that this feature currently only works for :unstable channel
|
73
|
+
options = {
|
74
|
+
channel: :unstable,
|
75
|
+
product_name: 'chef',
|
76
|
+
}
|
77
|
+
|
78
|
+
Mixlib::Install.new(options).available_versions
|
79
|
+
|
80
|
+
# => ["12.13.3", "12.13.7", "12.13.8+20160721014124", "12.13.11+20160721165202"]
|
81
|
+
```
|
82
|
+
|
70
83
|
## Unstable channel
|
71
84
|
The `:unstable` channel is currently only available when connected to Chef's internal network.
|
72
85
|
|
86
|
+
## Feature Flags
|
87
|
+
|
88
|
+
Below are the environment variables you can set to tune certain aspects of mixlib-install. They enable some features that are currently under development. You should use these features with care.
|
89
|
+
|
90
|
+
`MIXLIB_INSTALL_UNIFIED_BACKEND` => Enables unified backend feature which uses Artifactory backend for all available channels.
|
91
|
+
|
73
92
|
## Development
|
74
93
|
Since mixlib-install needs to interact with Bintray and Artifactory and since Artifactory instances are only available in Chef's network, this project uses [vcr](https://github.com/vcr/vcr).
|
75
94
|
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
3
|
|
4
|
-
task default: :
|
4
|
+
task default: :ci
|
5
5
|
|
6
6
|
desc "Run specs"
|
7
7
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
@@ -18,11 +18,21 @@ rescue LoadError
|
|
18
18
|
puts "chefstyle/rubocop is not available. gem install chefstyle to do style checking."
|
19
19
|
end
|
20
20
|
|
21
|
+
desc "Run specs for unified_backend (artifactory)"
|
22
|
+
task :unified_backend do
|
23
|
+
ENV["MIXLIB_INSTALL_UNIFIED_BACKEND"] = "true"
|
24
|
+
ENV["ARTIFACTORY_ENDPOINT"] = "https://packages-acceptance.chef.io"
|
25
|
+
Rake::Task["spec"].reenable
|
26
|
+
Rake::Task["spec"].invoke
|
27
|
+
ENV.delete "MIXLIB_INSTALL_UNIFIED_BACKEND"
|
28
|
+
ENV.delete "ARTIFACTORY_ENDPOINT"
|
29
|
+
end
|
30
|
+
|
21
31
|
desc "Run all tests"
|
22
|
-
task test: [:style, :spec]
|
32
|
+
task test: [:style, :spec, :unified_backend]
|
23
33
|
|
24
34
|
desc "Run tests for Travis CI"
|
25
|
-
task ci: [:style, :spec]
|
35
|
+
task ci: [:style, :spec, :unified_backend]
|
26
36
|
|
27
37
|
desc "Render product matrix documentation"
|
28
38
|
task "matrix" do
|
@@ -42,3 +52,11 @@ task "matrix" do
|
|
42
52
|
f.puts("Do not modify this file manually. It is automatically rendered via a rake task.")
|
43
53
|
end
|
44
54
|
end
|
55
|
+
|
56
|
+
task :console do
|
57
|
+
require "irb"
|
58
|
+
require "irb/completion"
|
59
|
+
require "mixlib/install"
|
60
|
+
ARGV.clear
|
61
|
+
IRB.start
|
62
|
+
end
|
data/lib/mixlib/install.rb
CHANGED
@@ -46,6 +46,15 @@ module Mixlib
|
|
46
46
|
Backend.info(options)
|
47
47
|
end
|
48
48
|
|
49
|
+
#
|
50
|
+
# List available versions
|
51
|
+
#
|
52
|
+
# @return [Array<String>] list of available versions for the given
|
53
|
+
# product_name and channel.
|
54
|
+
def available_versions
|
55
|
+
Backend.available_versions(options)
|
56
|
+
end
|
57
|
+
|
49
58
|
#
|
50
59
|
# Returns an install script for the given options
|
51
60
|
#
|
@@ -174,5 +183,13 @@ module Mixlib
|
|
174
183
|
def self.install_ps1(context = {})
|
175
184
|
Mixlib::Install::Generator::PowerShell.install_ps1(context)
|
176
185
|
end
|
186
|
+
|
187
|
+
#
|
188
|
+
# Returns if unified_backend feature flag for mixlib-install is enabled
|
189
|
+
#
|
190
|
+
# @return [Boolean] true if feature is enabled, false otherwise.
|
191
|
+
def self.unified_backend?
|
192
|
+
!ENV["MIXLIB_INSTALL_UNIFIED_BACKEND"].nil?
|
193
|
+
end
|
177
194
|
end
|
178
195
|
end
|
@@ -22,14 +22,20 @@ require "mixlib/install/backend/bintray"
|
|
22
22
|
module Mixlib
|
23
23
|
class Install
|
24
24
|
class Backend
|
25
|
+
def self.available_versions(options)
|
26
|
+
backend(options).available_versions
|
27
|
+
end
|
28
|
+
|
25
29
|
def self.info(options)
|
26
|
-
backend
|
27
|
-
|
28
|
-
else
|
29
|
-
Backend::Bintray.new(options)
|
30
|
-
end
|
30
|
+
backend(options).info
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
+
def self.backend(options)
|
34
|
+
if options.for_artifactory?
|
35
|
+
Backend::Artifactory.new(options)
|
36
|
+
else
|
37
|
+
Backend::Bintray.new(options)
|
38
|
+
end
|
33
39
|
end
|
34
40
|
end
|
35
41
|
end
|
@@ -43,11 +43,45 @@ module Mixlib
|
|
43
43
|
# @return [Array<ArtifactInfo>] list of artifacts for the configured
|
44
44
|
# channel, product name, and product version.
|
45
45
|
def available_artifacts
|
46
|
-
if options.latest_version?
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
artifacts = if options.latest_version?
|
47
|
+
artifactory_latest
|
48
|
+
else
|
49
|
+
artifactory_artifacts(options.product_version)
|
50
|
+
end
|
51
|
+
|
52
|
+
windows_artifact_fixup!(artifacts)
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Gets available versions from Artifactory via AQL.
|
57
|
+
#
|
58
|
+
# @return [Array<String>] Array of available versions
|
59
|
+
def available_versions
|
60
|
+
query = <<-QUERY
|
61
|
+
items.find(
|
62
|
+
{"repo": "omnibus-#{options.channel}-local"},
|
63
|
+
{"@omnibus.project": "#{omnibus_project}"},
|
64
|
+
{"name": {"$nmatch": "*.metadata.json" }}
|
65
|
+
).include("@omnibus.version", "artifact.module.build")
|
66
|
+
QUERY
|
67
|
+
items = artifactory_query(query)
|
68
|
+
|
69
|
+
# Filter out the partial builds if we are in :unstable channel
|
70
|
+
# In other channels we do not need to do this since all builds are
|
71
|
+
# always complete. Infact we should not do this since for some arcane
|
72
|
+
# builds like Chef Client 10.X we do not have build record created in
|
73
|
+
# artifactory.
|
74
|
+
if options.channel == :unstable
|
75
|
+
# We check if "artifacts" field contains something since it is only
|
76
|
+
# populated with the build record if "artifact.module.build" exists.
|
77
|
+
items.reject! { |i| i["artifacts"].nil? }
|
50
78
|
end
|
79
|
+
|
80
|
+
# We are only including a single property, version and that exists
|
81
|
+
# under the properties in the following structure:
|
82
|
+
# "properties" => [ {"key"=>"omnibus.version", "value"=>"12.13.3"} ]
|
83
|
+
items.map! { |i| i["properties"].first["value"] }
|
84
|
+
items.uniq
|
51
85
|
end
|
52
86
|
|
53
87
|
#
|
@@ -58,7 +92,7 @@ module Mixlib
|
|
58
92
|
# Get the list of builds from the REST api.
|
59
93
|
# We do this because a user in the readers group does not have
|
60
94
|
# permissions to run aql against builds.
|
61
|
-
builds = client.get("/api/build/#{
|
95
|
+
builds = client.get("/api/build/#{omnibus_project}")
|
62
96
|
|
63
97
|
if builds.nil?
|
64
98
|
raise NoArtifactsError, <<-MSG
|
@@ -100,16 +134,19 @@ Can not find any builds for #{options.product_name} in #{::Artifactory.endpoint}
|
|
100
134
|
results = artifactory_query(<<-QUERY
|
101
135
|
items.find(
|
102
136
|
{"repo": "omnibus-#{options.channel}-local"},
|
103
|
-
{"@omnibus.project": "#{
|
137
|
+
{"@omnibus.project": "#{omnibus_project}"},
|
104
138
|
{"@omnibus.version": "#{version}"},
|
105
139
|
{"name": {"$nmatch": "*.metadata.json" }}
|
106
140
|
).include("repo", "path", "name", "property")
|
107
141
|
QUERY
|
108
142
|
)
|
109
143
|
|
110
|
-
# Merge artifactory properties
|
144
|
+
# Merge artifactory properties to a flat Hash
|
111
145
|
results.collect! do |result|
|
112
|
-
{
|
146
|
+
{
|
147
|
+
"artifactory_standard_path" => generate_artifactory_standard_path(result),
|
148
|
+
"filename" => result["name"],
|
149
|
+
}.merge(
|
113
150
|
map_properties(result["properties"])
|
114
151
|
)
|
115
152
|
end
|
@@ -130,15 +167,42 @@ items.find(
|
|
130
167
|
results["results"]
|
131
168
|
end
|
132
169
|
|
170
|
+
#
|
171
|
+
# Artifactory GET request
|
172
|
+
#
|
173
|
+
def get(url)
|
174
|
+
results = artifactory_request do
|
175
|
+
client.get(url)
|
176
|
+
end
|
177
|
+
|
178
|
+
results["results"]
|
179
|
+
end
|
180
|
+
|
133
181
|
def create_artifact(artifact_map)
|
182
|
+
platform, platform_version = normalize_platform(artifact_map["omnibus.platform"],
|
183
|
+
artifact_map["omnibus.platform_version"])
|
184
|
+
|
185
|
+
chef_standard_path = generate_chef_standard_path(options.channel,
|
186
|
+
platform,
|
187
|
+
platform_version,
|
188
|
+
artifact_map["filename"]
|
189
|
+
)
|
190
|
+
|
134
191
|
ArtifactInfo.new(
|
135
192
|
md5: artifact_map["omnibus.md5"],
|
136
193
|
sha256: artifact_map["omnibus.sha256"],
|
194
|
+
sha1: artifact_map["omnibus.sha1"],
|
137
195
|
version: artifact_map["omnibus.version"],
|
138
|
-
platform:
|
139
|
-
platform_version:
|
140
|
-
architecture: artifact_map["omnibus.architecture"],
|
141
|
-
url
|
196
|
+
platform: platform,
|
197
|
+
platform_version: platform_version,
|
198
|
+
architecture: normalize_architecture(artifact_map["omnibus.architecture"]),
|
199
|
+
# Select what type of url we are going to display based on the enabled
|
200
|
+
# feature flags.
|
201
|
+
url: if Mixlib::Install.unified_backend?
|
202
|
+
chef_standard_path
|
203
|
+
else
|
204
|
+
artifact_map["artifactory_standard_path"]
|
205
|
+
end
|
142
206
|
)
|
143
207
|
end
|
144
208
|
|
@@ -154,9 +218,20 @@ items.find(
|
|
154
218
|
end
|
155
219
|
end
|
156
220
|
|
157
|
-
#
|
158
|
-
#
|
159
|
-
def
|
221
|
+
# Generates a chef standard download uri in the form of
|
222
|
+
# http://endpoint/channel/platform/platform_version/filename
|
223
|
+
def generate_chef_standard_path(channel, platform, platform_version, filename)
|
224
|
+
uri = []
|
225
|
+
uri << endpoint.sub(/\/$/, "")
|
226
|
+
uri << channel
|
227
|
+
uri << platform
|
228
|
+
uri << platform_version
|
229
|
+
uri << filename
|
230
|
+
uri.join("/")
|
231
|
+
end
|
232
|
+
|
233
|
+
# Generates an artifactory standard download uri
|
234
|
+
def generate_artifactory_standard_path(result)
|
160
235
|
uri = []
|
161
236
|
uri << endpoint.sub(/\/$/, "")
|
162
237
|
uri << result["repo"]
|
@@ -196,8 +271,22 @@ the endpoint is correct and there is an open connection to Chef's private networ
|
|
196
271
|
results
|
197
272
|
end
|
198
273
|
|
199
|
-
def
|
200
|
-
@
|
274
|
+
def omnibus_project
|
275
|
+
@omnibus_project ||= PRODUCT_MATRIX.lookup(options.product_name, options.product_version).omnibus_project
|
276
|
+
end
|
277
|
+
|
278
|
+
#
|
279
|
+
# Normalizes architecture information that we receive.
|
280
|
+
#
|
281
|
+
# @param [String] architecture
|
282
|
+
#
|
283
|
+
# @return String [architecture]
|
284
|
+
def normalize_architecture(architecture)
|
285
|
+
if %w{ sun4u sun4v }.include?(architecture)
|
286
|
+
architecture = "sparc"
|
287
|
+
end
|
288
|
+
|
289
|
+
architecture
|
201
290
|
end
|
202
291
|
end
|
203
292
|
end
|
@@ -38,6 +38,20 @@ module Mixlib
|
|
38
38
|
raise "Must implement available_artifacts method that returns Array<ArtifactInfo>"
|
39
39
|
end
|
40
40
|
|
41
|
+
#
|
42
|
+
# Returns the list of available versions for a given product_name
|
43
|
+
# and channel.
|
44
|
+
#
|
45
|
+
# @abstract Subclasses should define this method.
|
46
|
+
# Currently this method is only available in the Artifactory
|
47
|
+
# subclass.
|
48
|
+
#
|
49
|
+
# @return Array<String>
|
50
|
+
# List of available versions as strings.
|
51
|
+
def available_versions
|
52
|
+
raise "available_versions API is only available for Artifactory backend."
|
53
|
+
end
|
54
|
+
|
41
55
|
#
|
42
56
|
# See #filter_artifacts
|
43
57
|
def info
|
@@ -106,6 +120,61 @@ module Mixlib
|
|
106
120
|
return []
|
107
121
|
end
|
108
122
|
|
123
|
+
# On windows, if we do not have a native 64-bit package available
|
124
|
+
# in the discovered artifacts, we will make 32-bit artifacts available
|
125
|
+
# for 64-bit architecture.
|
126
|
+
def windows_artifact_fixup!(artifacts)
|
127
|
+
new_artifacts = [ ]
|
128
|
+
native_artifacts = [ ]
|
129
|
+
|
130
|
+
artifacts.each do |r|
|
131
|
+
next if r.platform != "windows"
|
132
|
+
|
133
|
+
# Store all native 64-bit artifacts and clone 32-bit artifacts to
|
134
|
+
# be used as 64-bit.
|
135
|
+
case r.architecture
|
136
|
+
when "i386"
|
137
|
+
new_artifacts << r.clone_with(architecture: "x86_64")
|
138
|
+
when "x86_64"
|
139
|
+
native_artifacts << r.clone
|
140
|
+
else
|
141
|
+
puts "Unknown architecture '#{r.architecture}' for windows."
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Now discard the cloned artifacts if we find an equivalent native
|
146
|
+
# artifact
|
147
|
+
native_artifacts.each do |r|
|
148
|
+
new_artifacts.delete_if do |x|
|
149
|
+
x.platform_version == r.platform_version
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# add the remaining cloned artifacts to the original set
|
154
|
+
artifacts += new_artifacts
|
155
|
+
end
|
156
|
+
|
157
|
+
#
|
158
|
+
# Normalizes platform and platform_version information that we receive.
|
159
|
+
# There are a few entries that we historically published
|
160
|
+
# that we need to normalize. They are:
|
161
|
+
# * solaris -> solaris2 & 10 -> 5.10 for solaris.
|
162
|
+
#
|
163
|
+
# @param [String] platform
|
164
|
+
# @param [String] platform_version
|
165
|
+
#
|
166
|
+
# @return Array<String> [platform, platform_version]
|
167
|
+
def normalize_platform(platform, platform_version)
|
168
|
+
if platform == "solaris"
|
169
|
+
platform = "solaris2"
|
170
|
+
|
171
|
+
# Here platform_version is set to either 10 or 11 and we would like
|
172
|
+
# to normalize that to 5.10 and 5.11.
|
173
|
+
platform_version = "5.#{platform_version}"
|
174
|
+
end
|
175
|
+
|
176
|
+
[platform, platform_version]
|
177
|
+
end
|
109
178
|
end
|
110
179
|
end
|
111
180
|
end
|
@@ -81,7 +81,7 @@ module Mixlib
|
|
81
81
|
# @return [String] latest version value
|
82
82
|
#
|
83
83
|
def latest_version
|
84
|
-
result = bintray_get("#{options.channel}/#{
|
84
|
+
result = bintray_get("#{options.channel}/#{bintray_product_name}/versions/_latest")
|
85
85
|
result["name"]
|
86
86
|
end
|
87
87
|
|
@@ -93,11 +93,11 @@ module Mixlib
|
|
93
93
|
def available_artifacts
|
94
94
|
version = options.latest_version? ? latest_version : options.product_version
|
95
95
|
begin
|
96
|
-
results = bintray_get("#{options.channel}/#{
|
96
|
+
results = bintray_get("#{options.channel}/#{bintray_product_name}/versions/#{version}/files")
|
97
97
|
rescue Net::HTTPServerException => e
|
98
98
|
if e.message =~ /404 "Not Found"/
|
99
99
|
raise VersionNotFound,
|
100
|
-
"Specified version (#{version}) not found for #{
|
100
|
+
"Specified version (#{version}) not found for #{bintray_product_name} in #{options.channel} channel."
|
101
101
|
else
|
102
102
|
raise
|
103
103
|
end
|
@@ -119,40 +119,6 @@ module Mixlib
|
|
119
119
|
windows_artifact_fixup!(results)
|
120
120
|
end
|
121
121
|
|
122
|
-
# On windows, if we do not have a native 64-bit package available
|
123
|
-
# in the discovered artifacts, we will make 32-bit artifacts available
|
124
|
-
# for 64-bit architecture.
|
125
|
-
def windows_artifact_fixup!(artifacts)
|
126
|
-
new_artifacts = [ ]
|
127
|
-
native_artifacts = [ ]
|
128
|
-
|
129
|
-
artifacts.each do |r|
|
130
|
-
next if r.platform != "windows"
|
131
|
-
|
132
|
-
# Store all native 64-bit artifacts and clone 32-bit artifacts to
|
133
|
-
# be used as 64-bit.
|
134
|
-
case r.architecture
|
135
|
-
when "i386"
|
136
|
-
new_artifacts << r.clone_with(architecture: "x86_64")
|
137
|
-
when "x86_64"
|
138
|
-
native_artifacts << r.clone
|
139
|
-
else
|
140
|
-
puts "Unknown architecture '#{r.architecture}' for windows."
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# Now discard the cloned artifacts if we find an equivalent native
|
145
|
-
# artifact
|
146
|
-
native_artifacts.each do |r|
|
147
|
-
new_artifacts.delete_if do |x|
|
148
|
-
x.platform_version == r.platform_version
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
# add the remaining cloned artifacts to the original set
|
153
|
-
artifacts += new_artifacts
|
154
|
-
end
|
155
|
-
|
156
122
|
#
|
157
123
|
# Creates an instance of ArtifactInfo
|
158
124
|
#
|
@@ -238,29 +204,6 @@ module Mixlib
|
|
238
204
|
}
|
239
205
|
end
|
240
206
|
|
241
|
-
#
|
242
|
-
# Normalizes platform and platform_version information that we receive
|
243
|
-
# from bintray. There are a few entries that we historically published
|
244
|
-
# that we need to normalize. They are:
|
245
|
-
# * solaris -> solaris2 & 10 -> 5.10 for solaris.
|
246
|
-
#
|
247
|
-
# @param [String] platform
|
248
|
-
# @param [String] platform_version
|
249
|
-
#
|
250
|
-
# @return Array<String> [platform, platform_version]
|
251
|
-
def normalize_platform(platform, platform_version)
|
252
|
-
if platform == "solaris"
|
253
|
-
platform = "solaris2"
|
254
|
-
|
255
|
-
# Here platform_version is set to either 10 or 11 and we would like
|
256
|
-
# to normalize that to 5.10 and 5.11.
|
257
|
-
|
258
|
-
platform_version = "5.#{platform_version}"
|
259
|
-
end
|
260
|
-
|
261
|
-
[platform, platform_version]
|
262
|
-
end
|
263
|
-
|
264
207
|
#
|
265
208
|
# Determines the architecture for which a file is published from from
|
266
209
|
# filename.
|
@@ -290,6 +233,8 @@ module Mixlib
|
|
290
233
|
"powerpc"
|
291
234
|
elsif %w{ sparc sun4u sun4v }.fuzzy_include?(filename)
|
292
235
|
"sparc"
|
236
|
+
elsif %w{ s390x }.fuzzy_include?(filename)
|
237
|
+
"s390x"
|
293
238
|
# Note that ppc64le should come before ppc64 otherwise our search
|
294
239
|
# will think ppc64le matches ppc64. Ubuntu also calls it ppc64el.
|
295
240
|
elsif %w{ ppc64le ppc64el }.fuzzy_include?(filename)
|
@@ -332,6 +277,21 @@ module Mixlib
|
|
332
277
|
"architecture can not be determined for '#{filename}'"
|
333
278
|
end
|
334
279
|
end
|
280
|
+
|
281
|
+
private
|
282
|
+
|
283
|
+
#
|
284
|
+
# This is a temporary workaround until we move to the unified backend
|
285
|
+
# for all channels. Some products are published to Bintray using their
|
286
|
+
# Omnibus project name as opposed to their mixlib-install product key.
|
287
|
+
#
|
288
|
+
def bintray_product_name
|
289
|
+
if %w{automate}.include?(options.product_name)
|
290
|
+
PRODUCT_MATRIX.lookup(options.product_name).omnibus_project
|
291
|
+
else
|
292
|
+
options.product_name
|
293
|
+
end
|
294
|
+
end
|
335
295
|
end
|
336
296
|
end
|
337
297
|
end
|
@@ -46,7 +46,9 @@ module Mixlib
|
|
46
46
|
install_command << get_script("helpers.sh")
|
47
47
|
install_command << render_variables
|
48
48
|
install_command << get_script("platform_detection.sh")
|
49
|
-
|
49
|
+
# Since omnitruck can not resolve unstable we need to inject direct
|
50
|
+
# urls for the packages here.
|
51
|
+
if options.for_unstable?
|
50
52
|
install_command << artifactory_urls
|
51
53
|
else
|
52
54
|
install_command << get_script("fetch_metadata.sh")
|
@@ -96,6 +96,10 @@ elif test "x$os" = "xAIX"; then
|
|
96
96
|
platform="aix"
|
97
97
|
platform_version="`uname -v`.`uname -r`"
|
98
98
|
machine="powerpc"
|
99
|
+
elif test -f "/etc/Eos-release"; then
|
100
|
+
platform=arista_eos
|
101
|
+
platform_version=`awk '{print $4}' /etc/Eos-release`
|
102
|
+
machine="i386"
|
99
103
|
elif test -f "/etc/os-release"; then
|
100
104
|
. /etc/os-release
|
101
105
|
if test "x$CISCO_RELEASE_INFO" != "x"; then
|
@@ -46,7 +46,9 @@ module Mixlib
|
|
46
46
|
def install_command
|
47
47
|
install_project_module = []
|
48
48
|
install_project_module << get_script("helpers.ps1")
|
49
|
-
|
49
|
+
# Since omnitruck can not resolve unstable we need to inject direct
|
50
|
+
# urls for the packages here.
|
51
|
+
install_project_module << if options.for_unstable?
|
50
52
|
artifactory_urls
|
51
53
|
else
|
52
54
|
get_script("get_project_metadata.ps1")
|
@@ -73,7 +75,7 @@ module Mixlib
|
|
73
75
|
|
74
76
|
def artifactory_urls
|
75
77
|
get_script("get_project_metadata_for_artifactory.ps1",
|
76
|
-
artifacts: artifacts)
|
78
|
+
artifacts: Array(artifacts))
|
77
79
|
end
|
78
80
|
|
79
81
|
def artifacts
|
@@ -81,7 +83,7 @@ module Mixlib
|
|
81
83
|
end
|
82
84
|
|
83
85
|
def product_version
|
84
|
-
if options.
|
86
|
+
if options.for_unstable?
|
85
87
|
artifacts.first.version
|
86
88
|
else
|
87
89
|
options.product_version
|
@@ -1,16 +1,22 @@
|
|
1
1
|
function Get-PlatformVersion {
|
2
|
-
switch -regex ((
|
3
|
-
'10\.0\.\d+' {$platform_version = '
|
2
|
+
switch -regex ((Get-WMIQuery win32_operatingsystem).version) {
|
3
|
+
'10\.0\.\d+' {$platform_version = '2016'}
|
4
4
|
'6\.3\.\d+' {$platform_version = '2012r2'}
|
5
5
|
'6\.2\.\d+' {$platform_version = '2012'}
|
6
6
|
'6\.1\.\d+' {$platform_version = '2008r2'}
|
7
7
|
'6\.0\.\d+' {$platform_version = '2008'}
|
8
8
|
}
|
9
|
+
|
10
|
+
if(Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server\ServerLevels') {
|
11
|
+
$levels = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server\ServerLevels'
|
12
|
+
if($levels.NanoServer -eq 1) { $platform_version += 'nano' }
|
13
|
+
}
|
14
|
+
|
9
15
|
return $platform_version
|
10
16
|
}
|
11
17
|
|
12
18
|
function Get-PlatformArchitecture {
|
13
|
-
if ((
|
19
|
+
if ((Get-WMIQuery win32_operatingsystem).osarchitecture -like '64-bit') {
|
14
20
|
$architecture = 'x86_64'
|
15
21
|
} else {
|
16
22
|
$architecture = 'i386'
|
@@ -22,7 +28,8 @@ function New-Uri {
|
|
22
28
|
param ($baseuri, $newuri)
|
23
29
|
|
24
30
|
try {
|
25
|
-
|
31
|
+
$base = new-object System.Uri $baseuri
|
32
|
+
new-object System.Uri $base, $newuri
|
26
33
|
}
|
27
34
|
catch [System.Management.Automation.MethodInvocationException]{
|
28
35
|
Write-Error "$($_.exception.message)"
|
@@ -32,17 +39,13 @@ function New-Uri {
|
|
32
39
|
|
33
40
|
function Get-WebContent {
|
34
41
|
param ($uri, $filepath)
|
35
|
-
$proxy = New-Object -TypeName System.Net.WebProxy
|
36
|
-
$wc = new-object System.Net.WebClient
|
37
|
-
$proxy.Address = $env:http_proxy
|
38
|
-
$wc.Proxy = $proxy
|
39
42
|
|
40
43
|
try {
|
41
|
-
if
|
42
|
-
$
|
44
|
+
if($PSVersionTable.PSEdition -eq 'Core') {
|
45
|
+
Get-WebContentOnCore $uri $filepath
|
43
46
|
}
|
44
47
|
else {
|
45
|
-
$
|
48
|
+
Get-WebContentOnFullNet $uri $filepath
|
46
49
|
}
|
47
50
|
}
|
48
51
|
catch {
|
@@ -56,17 +59,61 @@ function Get-WebContent {
|
|
56
59
|
}
|
57
60
|
}
|
58
61
|
|
62
|
+
function Get-WebContentOnFullNet {
|
63
|
+
param ($uri, $filepath)
|
64
|
+
|
65
|
+
$proxy = New-Object -TypeName System.Net.WebProxy
|
66
|
+
$wc = new-object System.Net.WebClient
|
67
|
+
$proxy.Address = $env:http_proxy
|
68
|
+
$wc.Proxy = $proxy
|
69
|
+
|
70
|
+
if ([string]::IsNullOrEmpty($filepath)) {
|
71
|
+
$wc.downloadstring($uri)
|
72
|
+
}
|
73
|
+
else {
|
74
|
+
$wc.downloadfile($uri, $filepath)
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
function Get-WebContentOnCore {
|
79
|
+
param ($uri, $filepath)
|
80
|
+
|
81
|
+
$handler = New-Object System.Net.Http.HttpClientHandler
|
82
|
+
$client = New-Object System.Net.Http.HttpClient($handler)
|
83
|
+
$client.Timeout = New-Object System.TimeSpan(0, 30, 0)
|
84
|
+
$cancelTokenSource = [System.Threading.CancellationTokenSource]::new()
|
85
|
+
$responseMsg = $client.GetAsync([System.Uri]::new($uri), $cancelTokenSource.Token)
|
86
|
+
$responseMsg.Wait()
|
87
|
+
if (!$responseMsg.IsCanceled) {
|
88
|
+
$response = $responseMsg.Result
|
89
|
+
if ($response.IsSuccessStatusCode) {
|
90
|
+
if ([string]::IsNullOrEmpty($filepath)) {
|
91
|
+
$response.Content.ReadAsStringAsync().Result
|
92
|
+
}
|
93
|
+
else {
|
94
|
+
$downloadedFileStream = [System.IO.FileStream]::new($filepath, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
|
95
|
+
$copyStreamOp = $response.Content.CopyToAsync($downloadedFileStream)
|
96
|
+
$copyStreamOp.Wait()
|
97
|
+
$downloadedFileStream.Close()
|
98
|
+
if ($copyStreamOp.Exception -ne $null) {
|
99
|
+
throw $copyStreamOp.Exception
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
59
106
|
function Test-ProjectPackage {
|
60
107
|
[cmdletbinding()]
|
61
108
|
param ($Path, $Algorithm = 'SHA256', $Hash)
|
62
109
|
|
63
|
-
if (-not (get-command get-filehash))
|
110
|
+
if (-not (get-command get-filehash -ErrorAction 'SilentlyContinue')) {
|
64
111
|
function disposable($o){($o -is [IDisposable]) -and (($o | get-member | foreach-object {$_.name}) -contains 'Dispose')}
|
65
112
|
function use($obj, [scriptblock]$sb){try {& $sb} catch [exception]{throw $_} finally {if (disposable $obj) {$obj.Dispose()}} }
|
66
113
|
function Get-FileHash ($Path, $Algorithm) {
|
67
114
|
$Path = (resolve-path $path).providerpath
|
68
115
|
$hash = @{Algorithm = $Algorithm; Path = $Path}
|
69
|
-
use ($c =
|
116
|
+
use ($c = Get-SHA256Converter) {
|
70
117
|
use ($in = (gi $path).OpenRead()) {
|
71
118
|
$hash.Hash = ([BitConverter]::ToString($c.ComputeHash($in))).Replace("-", "").ToUpper()
|
72
119
|
}
|
@@ -84,3 +131,23 @@ function Test-ProjectPackage {
|
|
84
131
|
}
|
85
132
|
return $Valid
|
86
133
|
}
|
134
|
+
|
135
|
+
function Get-SHA256Converter {
|
136
|
+
if($PSVersionTable.PSEdition -eq 'Core') {
|
137
|
+
[System.Security.Cryptography.SHA256]::Create()
|
138
|
+
}
|
139
|
+
else {
|
140
|
+
New-Object -TypeName Security.Cryptography.SHA256Managed
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
function Get-WMIQuery {
|
145
|
+
param ($class)
|
146
|
+
|
147
|
+
if(Get-Command -Name Get-CimInstance -ErrorAction SilentlyContinue) {
|
148
|
+
Get-CimInstance $class
|
149
|
+
}
|
150
|
+
else {
|
151
|
+
Get-WmiObject $class
|
152
|
+
}
|
153
|
+
}
|
@@ -83,14 +83,15 @@ function Install-Project {
|
|
83
83
|
$installingProject = $True
|
84
84
|
$installAttempts = 0
|
85
85
|
while ($installingProject) {
|
86
|
-
$
|
87
|
-
$
|
88
|
-
if
|
89
|
-
|
90
|
-
continue
|
91
|
-
} elseif ($p.ExitCode -ne 0) {
|
92
|
-
throw "msiexec was not successful. Received exit code $($p.ExitCode)"
|
86
|
+
$installAttempts++
|
87
|
+
$result = $false
|
88
|
+
if($download_destination.EndsWith(".appx")) {
|
89
|
+
$result = Install-ChefAppx $download_destination $project
|
93
90
|
}
|
91
|
+
else {
|
92
|
+
$result = Install-ChefMsi $download_destination
|
93
|
+
}
|
94
|
+
if(!$result) { continue }
|
94
95
|
$installingProject = $False
|
95
96
|
}
|
96
97
|
}
|
@@ -100,4 +101,39 @@ function Install-Project {
|
|
100
101
|
}
|
101
102
|
}
|
102
103
|
set-alias install -value Install-Project
|
104
|
+
|
105
|
+
Function Install-ChefMsi($msi) {
|
106
|
+
$p = Start-Process -FilePath "msiexec.exe" -ArgumentList "/qn /i $msi" -Passthru -Wait
|
107
|
+
$p.WaitForExit()
|
108
|
+
if ($p.ExitCode -eq 1618) {
|
109
|
+
Write-Host "Another msi install is in progress (exit code 1618), retrying ($($installAttempts))..."
|
110
|
+
return $false
|
111
|
+
} elseif ($p.ExitCode -ne 0) {
|
112
|
+
throw "msiexec was not successful. Received exit code $($p.ExitCode)"
|
113
|
+
}
|
114
|
+
return $true
|
115
|
+
}
|
116
|
+
|
117
|
+
Function Install-ChefAppx($appx, $project) {
|
118
|
+
Add-AppxPackage -Path $appx -ErrorAction Stop
|
119
|
+
$package = (Get-AppxPackage -Name $project).InstallLocation
|
120
|
+
$installRoot = "$env:SystemDrive/opscode"
|
121
|
+
$link = Join-Path $installRoot $project
|
122
|
+
|
123
|
+
# Remove link from a previous install
|
124
|
+
# There is currently a bug in removing symbolic links from Powershell
|
125
|
+
# so we use the fisher-price cmd shell to do it
|
126
|
+
if(Test-Path $link) {
|
127
|
+
cmd /c rmdir $link
|
128
|
+
}
|
129
|
+
|
130
|
+
if(!(Test-Path $installRoot)) {
|
131
|
+
New-Item -ItemType Directory -Path $installRoot
|
132
|
+
}
|
133
|
+
push-Location $installRoot
|
134
|
+
New-Item -ItemType SymbolicLink -Name $project -Target $package
|
135
|
+
Pop-Location
|
136
|
+
return $true
|
137
|
+
}
|
138
|
+
|
103
139
|
export-modulemember -function 'Install-Project','Get-ProjectMetadata' -alias 'install'
|
@@ -71,11 +71,11 @@ module Mixlib
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def for_artifactory?
|
74
|
-
ARTIFACTORY_CHANNELS.include?(channel)
|
74
|
+
Mixlib::Install.unified_backend? || ARTIFACTORY_CHANNELS.include?(channel)
|
75
75
|
end
|
76
76
|
|
77
|
-
def
|
78
|
-
|
77
|
+
def for_unstable?
|
78
|
+
channel == :unstable
|
79
79
|
end
|
80
80
|
|
81
81
|
def for_omnitruck?
|
@@ -109,6 +109,7 @@ module Mixlib
|
|
109
109
|
{
|
110
110
|
shell_type: :sh,
|
111
111
|
platform_version_compatibility_mode: false,
|
112
|
+
product_version: :latest,
|
112
113
|
}
|
113
114
|
end
|
114
115
|
|
@@ -66,6 +66,33 @@ module Mixlib
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
+
#
|
70
|
+
# Set omnibus_project when configured, otherwise fall back to
|
71
|
+
# package_name
|
72
|
+
#
|
73
|
+
def omnibus_project(value = nil)
|
74
|
+
if value.nil?
|
75
|
+
@omnibus_project || package_name
|
76
|
+
else
|
77
|
+
@omnibus_project = value
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Return all known omnibus project names for a product
|
83
|
+
#
|
84
|
+
def known_omnibus_projects
|
85
|
+
# iterate through min/max versions for all product names
|
86
|
+
# and collect the name for both versions
|
87
|
+
projects = %w{ 0.0.0 1000.1000.1000 }.collect do |v|
|
88
|
+
@version = v
|
89
|
+
omnibus_project
|
90
|
+
end
|
91
|
+
# remove duplicates and return multiple known names or return the single
|
92
|
+
# project name
|
93
|
+
projects.uniq || projects
|
94
|
+
end
|
95
|
+
|
69
96
|
#
|
70
97
|
# Sets or retrieves the version for the product. This is used later
|
71
98
|
# when we are reading the value of a property if a Proc is specified
|
@@ -160,6 +187,13 @@ PRODUCT_MATRIX = Mixlib::Install::ProductMatrix.new do
|
|
160
187
|
package_name "angrychef"
|
161
188
|
end
|
162
189
|
|
190
|
+
product "automate" do
|
191
|
+
product_name "Chef Automate"
|
192
|
+
package_name "delivery"
|
193
|
+
ctl_command "delivery-ctl"
|
194
|
+
config_file "/etc/delivery/delivery.rb"
|
195
|
+
end
|
196
|
+
|
163
197
|
product "chef" do
|
164
198
|
product_name "Chef Client"
|
165
199
|
package_name "chef"
|
@@ -181,6 +215,7 @@ PRODUCT_MATRIX = Mixlib::Install::ProductMatrix.new do
|
|
181
215
|
"chef-server-core"
|
182
216
|
end
|
183
217
|
end
|
218
|
+
omnibus_project "chef-server"
|
184
219
|
ctl_command "chef-server-ctl"
|
185
220
|
config_file "/etc/opscode/chef-server.rb"
|
186
221
|
end
|
@@ -252,7 +287,7 @@ PRODUCT_MATRIX = Mixlib::Install::ProductMatrix.new do
|
|
252
287
|
end
|
253
288
|
|
254
289
|
product "push-jobs-client" do
|
255
|
-
product_name "Chef Push
|
290
|
+
product_name "Chef Push Client"
|
256
291
|
package_name do |v|
|
257
292
|
v < version_for("1.3.0") ? "opscode-push-jobs-client" : "push-jobs-client"
|
258
293
|
end
|
@@ -132,8 +132,7 @@ module Mixlib
|
|
132
132
|
def install_command_vars_for_powershell
|
133
133
|
[
|
134
134
|
shell_var("chef_omnibus_root", root),
|
135
|
-
|
136
|
-
].tap { |vars|
|
135
|
+
].tap do |vars|
|
137
136
|
if install_msi_url
|
138
137
|
vars << shell_var("chef_msi_url", install_msi_url)
|
139
138
|
else
|
@@ -141,7 +140,7 @@ module Mixlib
|
|
141
140
|
vars << shell_var("pretty_version", Util.pretty_version(version))
|
142
141
|
vars << shell_var("version", version)
|
143
142
|
end
|
144
|
-
|
143
|
+
end.join("\n")
|
145
144
|
end
|
146
145
|
|
147
146
|
def validate_opts!(opt)
|
data/mixlib-install.gemspec
CHANGED
@@ -25,6 +25,8 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
26
26
|
spec.add_development_dependency "rspec", "~> 3.3"
|
27
27
|
spec.add_development_dependency "pry"
|
28
|
+
spec.add_development_dependency "rb-readline"
|
28
29
|
spec.add_development_dependency "vcr"
|
29
30
|
spec.add_development_dependency "webmock", "~> 1.0"
|
31
|
+
spec.add_development_dependency "chefstyle", "~> 0.3"
|
30
32
|
end
|
data/support/install_command.ps1
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
Function Check-UpdateChef($root, $version) {
|
2
|
-
if (-Not (Test-Path $root)) { return $true }
|
2
|
+
if (-Not (Test-Path "$root\embedded")) { return $true }
|
3
3
|
elseif ("$version" -eq "true") { return $false }
|
4
4
|
elseif ("$version" -eq "latest") { return $true }
|
5
5
|
|
@@ -14,8 +14,7 @@ Function Check-UpdateChef($root, $version) {
|
|
14
14
|
}
|
15
15
|
|
16
16
|
Function Get-ChefMetadata($url) {
|
17
|
-
|
18
|
-
Finally { if ($c -ne $null) { $c.Dispose() } }
|
17
|
+
$response = Get-WebContent $url
|
19
18
|
|
20
19
|
$md = ConvertFrom-StringData $response.Replace("`t", "=")
|
21
20
|
return @($md.url, $md.sha256)
|
@@ -23,52 +22,154 @@ Function Get-ChefMetadata($url) {
|
|
23
22
|
|
24
23
|
Function Get-SHA256($src) {
|
25
24
|
Try {
|
26
|
-
$c =
|
25
|
+
$c = Get-SHA256Converter
|
27
26
|
$bytes = $c.ComputeHash(($in = (Get-Item $src).OpenRead()))
|
28
27
|
return ([System.BitConverter]::ToString($bytes)).Replace("-", "").ToLower()
|
29
28
|
} Finally { if (($c -ne $null) -and ($c.GetType().GetMethod("Dispose") -ne $null)) { $c.Dispose() }; if ($in -ne $null) { $in.Dispose() } }
|
30
29
|
}
|
31
30
|
|
31
|
+
function Get-SHA256Converter {
|
32
|
+
if($PSVersionTable.PSEdition -eq 'Core') {
|
33
|
+
[System.Security.Cryptography.SHA256]::Create()
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
New-Object -TypeName Security.Cryptography.SHA256Managed
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
32
40
|
Function Download-Chef($url, $sha256, $dst) {
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
Log "Download complete."
|
37
|
-
} Finally { if ($c -ne $null) { $c.Dispose() } }
|
41
|
+
Log "Downloading package from $url"
|
42
|
+
Get-WebContent $url $dst
|
43
|
+
Log "Download complete."
|
38
44
|
|
39
45
|
if ($sha256 -eq $null) { Log "Skipping sha256 verification" }
|
40
46
|
elseif (($dsha256 = Get-SHA256 $dst) -eq $sha256) { Log "Successfully verified $dst" }
|
41
47
|
else { throw "SHA256 for $dst $dsha256 does not match $sha256" }
|
42
48
|
}
|
43
49
|
|
44
|
-
Function Install-Chef($msi) {
|
50
|
+
Function Install-Chef($msi, $chef_omnibus_root) {
|
45
51
|
Log "Installing Chef Omnibus package $msi"
|
46
52
|
$installingChef = $True
|
47
53
|
$installAttempts = 0
|
48
54
|
while ($installingChef) {
|
49
55
|
$installAttempts++
|
50
|
-
$
|
51
|
-
$
|
52
|
-
|
53
|
-
Log "Another msi install is in progress (exit code 1618), retrying ($($installAttempts))..."
|
54
|
-
continue
|
55
|
-
} elseif ($p.ExitCode -ne 0) {
|
56
|
-
throw "msiexec was not successful. Received exit code $($p.ExitCode)"
|
56
|
+
$result = $false
|
57
|
+
if($msi.EndsWith(".appx")) {
|
58
|
+
$result = Install-ChefAppx $msi $chef_omnibus_root
|
57
59
|
}
|
60
|
+
else {
|
61
|
+
$result = Install-ChefMsi $msi
|
62
|
+
}
|
63
|
+
if(!$result) { continue }
|
58
64
|
$installingChef = $False
|
59
65
|
}
|
60
66
|
Remove-Item $msi -Force
|
61
67
|
Log "Installation complete"
|
62
68
|
}
|
63
69
|
|
70
|
+
Function Install-ChefMsi($msi) {
|
71
|
+
$p = Start-Process -FilePath "msiexec.exe" -ArgumentList "/qn /i $msi" -Passthru -Wait
|
72
|
+
$p.WaitForExit()
|
73
|
+
if ($p.ExitCode -eq 1618) {
|
74
|
+
Log "Another msi install is in progress (exit code 1618), retrying ($($installAttempts))..."
|
75
|
+
return $false
|
76
|
+
} elseif ($p.ExitCode -ne 0) {
|
77
|
+
throw "msiexec was not successful. Received exit code $($p.ExitCode)"
|
78
|
+
}
|
79
|
+
return $true
|
80
|
+
}
|
81
|
+
|
82
|
+
Function Install-ChefAppx($appx, $chef_omnibus_root) {
|
83
|
+
Add-AppxPackage -Path $appx -ErrorAction Stop
|
84
|
+
|
85
|
+
$rootParent = Split-Path $chef_omnibus_root -Parent
|
86
|
+
$rootFolder = Split-Path $chef_omnibus_root -Leaf
|
87
|
+
$link = Join-Path $rootParent $rootFolder
|
88
|
+
|
89
|
+
# Remove link from a previous install
|
90
|
+
# There is currently a bug in removing symbolic links from Powershell
|
91
|
+
# so we use the fisher-price cmd shell to do it
|
92
|
+
if(Test-Path $link) {
|
93
|
+
cmd /c rmdir $link
|
94
|
+
}
|
95
|
+
|
96
|
+
$package = (Get-AppxPackage -Name chef).InstallLocation
|
97
|
+
if(!(Test-Path $rootParent)) {
|
98
|
+
New-Item -ItemType Directory -Path $rootParent
|
99
|
+
}
|
100
|
+
push-Location $rootParent
|
101
|
+
New-Item -ItemType SymbolicLink -Name $rootFolder -Target $package
|
102
|
+
Pop-Location
|
103
|
+
|
104
|
+
return $true
|
105
|
+
}
|
106
|
+
|
64
107
|
Function Log($m) { Write-Host " $m`n" }
|
65
108
|
|
66
|
-
|
109
|
+
function Get-WebContent {
|
110
|
+
param ($uri, $filepath)
|
111
|
+
|
112
|
+
try {
|
113
|
+
if($PSVersionTable.PSEdition -eq 'Core') {
|
114
|
+
Get-WebContentOnCore $uri $filepath
|
115
|
+
}
|
116
|
+
else {
|
117
|
+
Get-WebContentOnFullNet $uri $filepath
|
118
|
+
}
|
119
|
+
}
|
120
|
+
catch {
|
121
|
+
$exception = $_.Exception
|
122
|
+
Write-Host "There was an error: "
|
123
|
+
do {
|
124
|
+
Write-Host "`t$($exception.message)"
|
125
|
+
$exception = $exception.innerexception
|
126
|
+
} while ($exception)
|
127
|
+
throw "Failed to download from $uri."
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
function Get-WebContentOnFullNet {
|
132
|
+
param ($uri, $filepath)
|
133
|
+
|
67
134
|
$proxy = New-Object -TypeName System.Net.WebProxy
|
135
|
+
$wc = new-object System.Net.WebClient
|
68
136
|
$proxy.Address = $env:http_proxy
|
69
|
-
$
|
70
|
-
|
71
|
-
|
137
|
+
$wc.Proxy = $proxy
|
138
|
+
|
139
|
+
if ([string]::IsNullOrEmpty($filepath)) {
|
140
|
+
$wc.downloadstring($uri)
|
141
|
+
}
|
142
|
+
else {
|
143
|
+
$wc.downloadfile($uri, $filepath)
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
function Get-WebContentOnCore {
|
148
|
+
param ($uri, $filepath)
|
149
|
+
|
150
|
+
$handler = New-Object System.Net.Http.HttpClientHandler
|
151
|
+
$client = New-Object System.Net.Http.HttpClient($handler)
|
152
|
+
$client.Timeout = New-Object System.TimeSpan(0, 30, 0)
|
153
|
+
$cancelTokenSource = [System.Threading.CancellationTokenSource]::new()
|
154
|
+
$responseMsg = $client.GetAsync([System.Uri]::new($uri), $cancelTokenSource.Token)
|
155
|
+
$responseMsg.Wait()
|
156
|
+
if (!$responseMsg.IsCanceled) {
|
157
|
+
$response = $responseMsg.Result
|
158
|
+
if ($response.IsSuccessStatusCode) {
|
159
|
+
if ([string]::IsNullOrEmpty($filepath)) {
|
160
|
+
$response.Content.ReadAsStringAsync().Result
|
161
|
+
}
|
162
|
+
else {
|
163
|
+
$downloadedFileStream = [System.IO.FileStream]::new($filepath, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
|
164
|
+
$copyStreamOp = $response.Content.CopyToAsync($downloadedFileStream)
|
165
|
+
$copyStreamOp.Wait()
|
166
|
+
$downloadedFileStream.Close()
|
167
|
+
if ($copyStreamOp.Exception -ne $null) {
|
168
|
+
throw $copyStreamOp.Exception
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
72
173
|
}
|
73
174
|
|
74
175
|
Function Unresolve-Path($p) {
|
@@ -77,7 +178,6 @@ Function Unresolve-Path($p) {
|
|
77
178
|
}
|
78
179
|
|
79
180
|
$chef_omnibus_root = Unresolve-Path $chef_omnibus_root
|
80
|
-
$msi = Unresolve-Path $msi
|
81
181
|
|
82
182
|
if (Check-UpdateChef $chef_omnibus_root $version) {
|
83
183
|
Write-Host "-----> Installing Chef Omnibus ($pretty_version)`n"
|
@@ -87,8 +187,10 @@ if (Check-UpdateChef $chef_omnibus_root $version) {
|
|
87
187
|
$url = $chef_msi_url
|
88
188
|
$sha256 = $null
|
89
189
|
}
|
190
|
+
$msi = Join-Path $env:temp "$url".Split("/")[-1]
|
191
|
+
$msi = Unresolve-Path $msi
|
90
192
|
Download-Chef "$url" $sha256 $msi
|
91
|
-
Install-Chef $msi
|
193
|
+
Install-Chef $msi $chef_omnibus_root
|
92
194
|
} else {
|
93
195
|
Write-Host "-----> Chef Omnibus installation detected ($pretty_version)`n"
|
94
196
|
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mixlib-install
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thom May
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-09-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: artifactory
|
@@ -109,6 +109,20 @@ dependencies:
|
|
109
109
|
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: rb-readline
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
112
126
|
- !ruby/object:Gem::Dependency
|
113
127
|
name: vcr
|
114
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,6 +151,20 @@ dependencies:
|
|
137
151
|
- - "~>"
|
138
152
|
- !ruby/object:Gem::Version
|
139
153
|
version: '1.0'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: chefstyle
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - "~>"
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0.3'
|
161
|
+
type: :development
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - "~>"
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0.3'
|
140
168
|
description:
|
141
169
|
email:
|
142
170
|
- thom@chef.io
|
@@ -147,7 +175,6 @@ extra_rdoc_files: []
|
|
147
175
|
files:
|
148
176
|
- ".gitignore"
|
149
177
|
- ".rspec"
|
150
|
-
- ".rubocop.yml"
|
151
178
|
- ".travis.yml"
|
152
179
|
- CHANGELOG.md
|
153
180
|
- CONTRIBUTING.md
|
@@ -222,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
249
|
version: '0'
|
223
250
|
requirements: []
|
224
251
|
rubyforge_project:
|
225
|
-
rubygems_version: 2.
|
252
|
+
rubygems_version: 2.6.6
|
226
253
|
signing_key:
|
227
254
|
specification_version: 4
|
228
255
|
summary: A mixin to help with omnitruck installs
|