kitchen-cinc 1.0.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 +7 -0
- data/Gemfile +31 -0
- data/LICENSE +201 -0
- data/Rakefile +26 -0
- data/kitchen-cinc.gemspec +32 -0
- data/lib/kitchen/provisioner/cinc/berkshelf.rb +115 -0
- data/lib/kitchen/provisioner/cinc/common_sandbox.rb +348 -0
- data/lib/kitchen/provisioner/cinc/policyfile.rb +154 -0
- data/lib/kitchen/provisioner/cinc_apply.rb +124 -0
- data/lib/kitchen/provisioner/cinc_base.rb +525 -0
- data/lib/kitchen/provisioner/cinc_infra.rb +164 -0
- data/lib/kitchen/provisioner/cinc_solo.rb +86 -0
- data/lib/kitchen/provisioner/cinc_target.rb +131 -0
- data/lib/kitchen/provisioner/cinc_version.rb +5 -0
- data/lib/kitchen/provisioner/cinc_zero.rb +18 -0
- data/support/cinc-client-fail-if-update-handler.rb +15 -0
- data/support/cinc_base_init_command.ps1 +18 -0
- data/support/cinc_base_init_command.sh +2 -0
- data/support/cinc_base_install_command.ps1 +86 -0
- data/support/cinc_base_install_command.sh +229 -0
- data/support/download_helpers.sh +99 -0
- data/support/dummy-validation.pem +27 -0
- metadata +118 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (C) 2013, Fletcher Nichol
|
|
3
|
+
# Copyright (C) 2026, Oregon State University
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
require_relative "cinc_base"
|
|
18
|
+
|
|
19
|
+
module Kitchen
|
|
20
|
+
module Provisioner
|
|
21
|
+
# Cinc Solo provisioner.
|
|
22
|
+
#
|
|
23
|
+
# @author Cinc Project
|
|
24
|
+
class CincSolo < CincBase
|
|
25
|
+
kitchen_provisioner_api_version 2
|
|
26
|
+
|
|
27
|
+
plugin_version Kitchen::VERSION
|
|
28
|
+
|
|
29
|
+
# CincSolo is dependent on Berkshelf, which is not thread-safe.
|
|
30
|
+
# See discussion on https://github.com/test-kitchen/test-kitchen/issues/1307
|
|
31
|
+
no_parallel_for :converge
|
|
32
|
+
|
|
33
|
+
default_config :solo_rb, {}
|
|
34
|
+
|
|
35
|
+
default_config :cinc_solo_path do |provisioner|
|
|
36
|
+
provisioner
|
|
37
|
+
.remote_path_join(%W{#{provisioner[:cinc_omnibus_root]} bin cinc-solo})
|
|
38
|
+
.tap { |path| path.concat(".bat") if provisioner.windows_os? }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
default_config :ruby_bindir do |provisioner|
|
|
42
|
+
provisioner
|
|
43
|
+
.remote_path_join(%W{#{provisioner[:cinc_omnibus_root]} embedded bin})
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# (see Base#config_filename)
|
|
47
|
+
def config_filename
|
|
48
|
+
"solo.rb"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# (see Base#create_sandbox)
|
|
52
|
+
def create_sandbox
|
|
53
|
+
super
|
|
54
|
+
prepare_config_rb
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# (see Base#run_command)
|
|
58
|
+
def run_command
|
|
59
|
+
cmd = sudo(config[:cinc_solo_path]).dup
|
|
60
|
+
.tap { |str| str.insert(0, "& ") if powershell_shell? }
|
|
61
|
+
|
|
62
|
+
chef_cmd(cmd)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
# Returns an Array of command line arguments for the cinc-solo client.
|
|
68
|
+
#
|
|
69
|
+
# @return [Array<String>] an array of command line arguments
|
|
70
|
+
# @api private
|
|
71
|
+
def chef_args(solo_rb_filename)
|
|
72
|
+
args = [
|
|
73
|
+
"--config #{remote_path_join(config[:root_path], solo_rb_filename)}",
|
|
74
|
+
"--log_level #{config[:log_level]}",
|
|
75
|
+
"--force-formatter",
|
|
76
|
+
"--no-color",
|
|
77
|
+
"--json-attributes #{remote_path_join(config[:root_path], "dna.json")}",
|
|
78
|
+
]
|
|
79
|
+
args << "--logfile #{config[:log_file]}" if config[:log_file]
|
|
80
|
+
args << "--profile-ruby" if config[:profile_ruby]
|
|
81
|
+
args << "--legacy-mode" if config[:legacy_mode]
|
|
82
|
+
args
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (C) 2023, Thomas Heinen
|
|
3
|
+
# Copyright (C) 2026, Oregon State University
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
require_relative "cinc_infra"
|
|
18
|
+
|
|
19
|
+
module Kitchen
|
|
20
|
+
module Provisioner
|
|
21
|
+
# Cinc Target Mode provisioner for remote execution.
|
|
22
|
+
#
|
|
23
|
+
# Requires Cinc Client 19.0.0+ and Train-based transport.
|
|
24
|
+
#
|
|
25
|
+
# @author Cinc Project
|
|
26
|
+
class CincTarget < CincInfra
|
|
27
|
+
MIN_VERSION_REQUIRED = "19.0.0".freeze
|
|
28
|
+
class CincVersionTooLow < UserError; end
|
|
29
|
+
class CincClientNotFound < UserError; end
|
|
30
|
+
class RequireTrainTransport < UserError; end
|
|
31
|
+
|
|
32
|
+
default_config :install_strategy, "none"
|
|
33
|
+
default_config :sudo, true
|
|
34
|
+
|
|
35
|
+
def install_command; ""; end
|
|
36
|
+
def init_command; ""; end
|
|
37
|
+
def prepare_command; ""; end
|
|
38
|
+
|
|
39
|
+
def chef_args(client_rb_filename)
|
|
40
|
+
# Dummy execution to initialize and test remote connection
|
|
41
|
+
connection = instance.remote_exec("echo Connection established")
|
|
42
|
+
|
|
43
|
+
check_transport(connection)
|
|
44
|
+
check_local_cinc_client
|
|
45
|
+
|
|
46
|
+
instance_name = instance.name
|
|
47
|
+
credentials_file = File.join(kitchen_basepath, ".kitchen", instance_name + ".ini")
|
|
48
|
+
File.write(credentials_file, connection.credentials_file)
|
|
49
|
+
|
|
50
|
+
super.push(
|
|
51
|
+
"--target #{instance_name}",
|
|
52
|
+
"--credentials #{credentials_file}"
|
|
53
|
+
)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def check_transport(connection)
|
|
57
|
+
debug("Checking for active transport")
|
|
58
|
+
|
|
59
|
+
unless connection.respond_to? "train_uri"
|
|
60
|
+
error("Cinc Target Mode provisioner requires a Train-based transport like kitchen-transport-train")
|
|
61
|
+
raise RequireTrainTransport.new("No Train transport")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
debug("Kitchen transport responds to train_uri function call, as required")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def check_local_cinc_client
|
|
68
|
+
debug("Checking for cinc-client version")
|
|
69
|
+
|
|
70
|
+
begin
|
|
71
|
+
client_version = `cinc-client -v`.chop.split(":")[-1]
|
|
72
|
+
rescue Errno::ENOENT => e
|
|
73
|
+
error("Error determining Cinc Client version: #{e.exception.message}")
|
|
74
|
+
raise CincClientNotFound.new("Need cinc-client installed locally")
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
minimum_version = Gem::Version.new(MIN_VERSION_REQUIRED)
|
|
78
|
+
installed_version = Gem::Version.new(client_version)
|
|
79
|
+
|
|
80
|
+
if installed_version < minimum_version
|
|
81
|
+
error("Found Cinc Client version #{installed_version}, but require #{minimum_version} for Target Mode")
|
|
82
|
+
raise CincVersionTooLow.new("Need version #{MIN_VERSION_REQUIRED} or higher")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
debug("Cinc Client found and version constraints match")
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def kitchen_basepath
|
|
89
|
+
instance.driver.config[:kitchen_root]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def create_sandbox
|
|
93
|
+
super
|
|
94
|
+
|
|
95
|
+
# Change config.rb to point to the local sandbox path, not to /tmp/kitchen
|
|
96
|
+
config[:root_path] = sandbox_path
|
|
97
|
+
prepare_config_rb
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def call(state)
|
|
101
|
+
remote_connection = instance.transport.connection(state)
|
|
102
|
+
|
|
103
|
+
config[:uploads].to_h.each do |locals, remote|
|
|
104
|
+
debug("Uploading #{Array(locals).join(", ")} to #{remote}")
|
|
105
|
+
remote_connection.upload(locals.to_s, remote)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# no installation
|
|
109
|
+
create_sandbox
|
|
110
|
+
# no prepare command
|
|
111
|
+
|
|
112
|
+
# Stream output to logger
|
|
113
|
+
require "open3"
|
|
114
|
+
Open3.popen2e(run_command) do |_stdin, output, _thread|
|
|
115
|
+
output.each { |line| logger << line }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
info("Downloading files from #{instance.to_str}")
|
|
119
|
+
config[:downloads].to_h.each do |remotes, local|
|
|
120
|
+
debug("Downloading #{Array(remotes).join(", ")} to #{local}")
|
|
121
|
+
remote_connection.download(remotes, local)
|
|
122
|
+
end
|
|
123
|
+
debug("Download complete")
|
|
124
|
+
rescue Kitchen::Transport::TransportFailed => ex
|
|
125
|
+
raise ActionFailed, ex.message
|
|
126
|
+
ensure
|
|
127
|
+
cleanup_sandbox
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Deprecated - use CincInfra instead
|
|
2
|
+
require_relative "cinc_infra"
|
|
3
|
+
|
|
4
|
+
module Kitchen
|
|
5
|
+
module Provisioner
|
|
6
|
+
# Cinc Zero provisioner (deprecated, use CincInfra instead).
|
|
7
|
+
#
|
|
8
|
+
# This provisioner is maintained for backward compatibility and delegates
|
|
9
|
+
# to CincInfra.
|
|
10
|
+
#
|
|
11
|
+
# @author Cinc Project
|
|
12
|
+
class CincZero < CincInfra
|
|
13
|
+
kitchen_provisioner_api_version 2
|
|
14
|
+
|
|
15
|
+
plugin_version Kitchen::VERSION
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Handler to kill the run if any resource is updated
|
|
2
|
+
class UpdatedResources < ::Chef::Handler
|
|
3
|
+
def report
|
|
4
|
+
if updated_resources.size > 0
|
|
5
|
+
puts "First cinc run should have reached a converged state."
|
|
6
|
+
puts "Resources updated in a second cinc-client run:"
|
|
7
|
+
updated_resources.each do |r|
|
|
8
|
+
puts "- #{r}"
|
|
9
|
+
end
|
|
10
|
+
# exit 203 # chef handler catch Exception instead of StandardException
|
|
11
|
+
Process.kill("KILL", Process.pid)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
report_handlers << UpdatedResources.new
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Function Delete-AllDirs($dirs) {
|
|
2
|
+
$dirs | ForEach-Object {
|
|
3
|
+
if (Test-Path ($path = Unresolve-Path $_)) { Remove-Item $path -Recurse -Force }
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
Function Unresolve-Path($p) {
|
|
8
|
+
if ($p -eq $null) { return $null }
|
|
9
|
+
else { return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p) }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
Function Make-RootPath($p) {
|
|
13
|
+
$p = Unresolve-Path $p
|
|
14
|
+
if (-Not (Test-Path $p)) { New-Item $p -ItemType directory | Out-Null }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
Delete-AllDirs $dirs
|
|
18
|
+
Make-RootPath $root_path
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
$ErrorActionPreference = "stop"
|
|
2
|
+
|
|
3
|
+
Function Check-UpdateCinc($root, $version) {
|
|
4
|
+
if (-Not (Test-Path $root)) { return $true }
|
|
5
|
+
elseif ("$version" -eq "true") { return $false }
|
|
6
|
+
elseif ("$version" -eq "latest") { return $true }
|
|
7
|
+
Try { $cinc_version = (Get-Content $root\version-manifest.txt | select-object -first 1) }
|
|
8
|
+
Catch {
|
|
9
|
+
Try { $cinc_version = (& $root\bin\cinc-solo.bat -v) }
|
|
10
|
+
Catch { $cinc_version = " " }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if ($cinc_version.split(" ", 2)[1].StartsWith($version)) { return $false }
|
|
14
|
+
else { return $true }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
Function Get-CincMetadata($url) {
|
|
18
|
+
Try { $response = ($c = Make-WebClient).DownloadString($url) }
|
|
19
|
+
Finally { if ($c -ne $null) { $c.Dispose() } }
|
|
20
|
+
|
|
21
|
+
$md = ConvertFrom-StringData $response.Replace("`t", "=")
|
|
22
|
+
return @($md.url, $md.md5)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Function Get-MD5Sum($src) {
|
|
26
|
+
Try {
|
|
27
|
+
$c = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
|
|
28
|
+
$bytes = $c.ComputeHash(($in = (Get-Item $src).OpenRead()))
|
|
29
|
+
return ([System.BitConverter]::ToString($bytes)).Replace("-", "").ToLower()
|
|
30
|
+
} Finally { if (($c -ne $null) -and ($c.GetType().GetMethod("Dispose") -ne $null)) { $c.Dispose() }; if ($in -ne $null) { $in.Dispose() } }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
Function Download-Cinc($md_url, $dst) {
|
|
34
|
+
$url, $md5 = Get-CincMetadata $md_url
|
|
35
|
+
|
|
36
|
+
Try {
|
|
37
|
+
Log "Downloading package from $url"
|
|
38
|
+
($c = Make-WebClient).DownloadFile($url, $dst)
|
|
39
|
+
Log "Download complete."
|
|
40
|
+
} Finally { if ($c -ne $null) { $c.Dispose() } }
|
|
41
|
+
|
|
42
|
+
if (($dmd5 = Get-MD5Sum $dst) -eq $md5) { Log "Successfully verified $dst" }
|
|
43
|
+
else { throw "MD5 for $dst $dmd5 does not match $md5" }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
Function Install-Cinc($msi) {
|
|
47
|
+
Log "Installing Cinc Client package $msi"
|
|
48
|
+
$p = Start-Process -FilePath "msiexec.exe" -ArgumentList "/qn /i $msi" -Passthru -Wait
|
|
49
|
+
|
|
50
|
+
if ($p.ExitCode -ne 0) { throw "msiexec was not successful. Received exit code $($p.ExitCode)" }
|
|
51
|
+
|
|
52
|
+
Remove-Item $msi -Force
|
|
53
|
+
Log "Installation complete"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Function Log($m) { Write-Host " $m`n" }
|
|
57
|
+
|
|
58
|
+
Function Make-WebClient {
|
|
59
|
+
$proxy = New-Object -TypeName System.Net.WebProxy
|
|
60
|
+
$proxy.Address = $env:http_proxy
|
|
61
|
+
$client = New-Object -TypeName System.Net.WebClient
|
|
62
|
+
$client.Proxy = $proxy
|
|
63
|
+
return $client
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Function Unresolve-Path($p) {
|
|
67
|
+
if ($p -eq $null) { return $null }
|
|
68
|
+
else { return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p) }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
Try {
|
|
72
|
+
$chef_omnibus_root = Unresolve-Path $chef_omnibus_root
|
|
73
|
+
$msi = Unresolve-Path $msi
|
|
74
|
+
|
|
75
|
+
if (Check-UpdateCinc $chef_omnibus_root $version) {
|
|
76
|
+
Write-Host "-----> Installing Cinc Client package ($pretty_version)`n"
|
|
77
|
+
Download-Cinc "$chef_metadata_url" $msi
|
|
78
|
+
Install-Cinc $msi
|
|
79
|
+
} else {
|
|
80
|
+
Write-Host "-----> Cinc Client package installation detected ($pretty_version)`n"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
Catch {
|
|
84
|
+
Write-Error ($_ | ft -Property * | out-string) -ErrorAction Continue
|
|
85
|
+
exit 1
|
|
86
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
tmp_stderr="/tmp/stderr";
|
|
2
|
+
|
|
3
|
+
# capture_tmp_stderr SOURCE
|
|
4
|
+
capture_tmp_stderr() {
|
|
5
|
+
# spool up $tmp_stderr from all the commands we called
|
|
6
|
+
if test -f "$tmp_stderr"; then
|
|
7
|
+
output="`cat $tmp_stderr`";
|
|
8
|
+
stderr_results="${stderr_results}\nSTDERR from $1:\n\n${output}\n";
|
|
9
|
+
rm $tmp_stderr;
|
|
10
|
+
fi
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
# do_curl URL FILENAME
|
|
14
|
+
do_curl() {
|
|
15
|
+
echo "Trying curl...";
|
|
16
|
+
curl -sL -D "$tmp_stderr" "$1" > "$2";
|
|
17
|
+
ec=$?;
|
|
18
|
+
# check for 404
|
|
19
|
+
grep "404 Not Found" "$tmp_stderr" 2>&1 >/dev/null;
|
|
20
|
+
if test $? -eq 0; then
|
|
21
|
+
http_404_error "$1";
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# check for bad return status or empty output
|
|
25
|
+
if test $ec -ne 0 || test ! -s "$2"; then
|
|
26
|
+
capture_tmp_stderr "curl";
|
|
27
|
+
return 1;
|
|
28
|
+
else
|
|
29
|
+
echo "Download complete.";
|
|
30
|
+
return 0;
|
|
31
|
+
fi
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# do_download URL FILENAME
|
|
35
|
+
do_download() {
|
|
36
|
+
echo "Downloading ${1} to file ${2}";
|
|
37
|
+
|
|
38
|
+
exists wget;
|
|
39
|
+
if test $? -eq 0; then
|
|
40
|
+
do_wget "$1" "$2" && return 0;
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
exists curl;
|
|
44
|
+
if test $? -eq 0; then
|
|
45
|
+
do_curl "$1" "$2" && return 0;
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
exists fetch;
|
|
49
|
+
if test $? -eq 0; then
|
|
50
|
+
do_fetch "$1" "$2" && return 0;
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
exists python;
|
|
54
|
+
if test $? -eq 0; then
|
|
55
|
+
do_python "$1" "$2" && return 0;
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
exists perl;
|
|
59
|
+
if test $? -eq 0; then
|
|
60
|
+
do_perl "$1" "$2" && return 0;
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
unable_to_download "$1" "$2";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# do_fetch URL FILENAME
|
|
67
|
+
do_fetch() {
|
|
68
|
+
echo "Trying fetch...";
|
|
69
|
+
fetch -o "$2" "$1" 2>"$tmp_stderr";
|
|
70
|
+
ec=$?;
|
|
71
|
+
# check for 404
|
|
72
|
+
grep "Not Found" "$tmp_stderr" 2>&1 >/dev/null;
|
|
73
|
+
if test $? -eq 0; then
|
|
74
|
+
http_404_error "$1";
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# check for bad return status or empty output
|
|
78
|
+
if test $ec -ne 0 || test ! -s "$2"; then
|
|
79
|
+
capture_tmp_stderr "fetch";
|
|
80
|
+
return 1;
|
|
81
|
+
else
|
|
82
|
+
echo "Download complete.";
|
|
83
|
+
return 0;
|
|
84
|
+
fi
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# do_perl URL FILENAME
|
|
88
|
+
do_perl() {
|
|
89
|
+
echo "Trying perl...";
|
|
90
|
+
perl -e "use LWP::Simple; getprint(\$ARGV[0]);" "$1" > "$2" 2>"$tmp_stderr";
|
|
91
|
+
ec=$?;
|
|
92
|
+
# check for 404
|
|
93
|
+
grep "404 Not Found" "$tmp_stderr" 2>&1 >/dev/null;
|
|
94
|
+
if test $? -eq 0; then
|
|
95
|
+
http_404_error "$1";
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# check for bad return status or empty output
|
|
99
|
+
if test $ec -ne 0 || test ! -s "$2"; then
|
|
100
|
+
capture_tmp_stderr "perl";
|
|
101
|
+
return 1;
|
|
102
|
+
else
|
|
103
|
+
echo "Download complete.";
|
|
104
|
+
return 0;
|
|
105
|
+
fi
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# do_python URL FILENAME
|
|
109
|
+
do_python() {
|
|
110
|
+
echo "Trying python...";
|
|
111
|
+
python -c "import sys,urllib2 ; sys.stdout.write(urllib2.urlopen(sys.argv[1]).read())" "$1" > "$2" 2>"$tmp_stderr";
|
|
112
|
+
ec=$?;
|
|
113
|
+
# check for 404
|
|
114
|
+
grep "HTTP Error 404" "$tmp_stderr" 2>&1 >/dev/null;
|
|
115
|
+
if test $? -eq 0; then
|
|
116
|
+
http_404_error "$1";
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# check for bad return status or empty output
|
|
120
|
+
if test $ec -ne 0 || test ! -s "$2"; then
|
|
121
|
+
capture_tmp_stderr "python";
|
|
122
|
+
return 1;
|
|
123
|
+
else
|
|
124
|
+
echo "Download complete.";
|
|
125
|
+
return 0;
|
|
126
|
+
fi
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
# do_wget URL FILENAME
|
|
130
|
+
do_wget() {
|
|
131
|
+
echo "Trying wget...";
|
|
132
|
+
wget -O "$2" "$1" 2>"$tmp_stderr";
|
|
133
|
+
ec=$?;
|
|
134
|
+
# check for 404
|
|
135
|
+
grep "ERROR 404" "$tmp_stderr" 2>&1 >/dev/null;
|
|
136
|
+
if test $? -eq 0; then
|
|
137
|
+
http_404_error "$1";
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# check for bad return status or empty output
|
|
141
|
+
if test $ec -ne 0 || test ! -s "$2"; then
|
|
142
|
+
capture_tmp_stderr "wget";
|
|
143
|
+
return 1;
|
|
144
|
+
else
|
|
145
|
+
echo "Download complete.";
|
|
146
|
+
return 0;
|
|
147
|
+
fi
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# exists COMMAND
|
|
151
|
+
exists() {
|
|
152
|
+
if command -v "$1" >/dev/null 2>&1; then
|
|
153
|
+
return 0;
|
|
154
|
+
else
|
|
155
|
+
return 1;
|
|
156
|
+
fi
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# http_404_error URL
|
|
160
|
+
http_404_error() {
|
|
161
|
+
echo ">>>>>> Downloading ${1} resulted in an HTTP/404, aborting";
|
|
162
|
+
exit 40;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# should_update_cinc ROOT VERSION
|
|
166
|
+
should_update_cinc() {
|
|
167
|
+
if test ! -d "$1"; then
|
|
168
|
+
return 0;
|
|
169
|
+
elif test "$2" = "true"; then
|
|
170
|
+
return 1;
|
|
171
|
+
elif test "$2" = "latest"; then
|
|
172
|
+
return 0;
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
if test -f "${1}/version-manifest.txt"; then
|
|
176
|
+
cinc_version="`head -n 1 ${1}/version-manifest.txt | cut -d \" \" -f 2`";
|
|
177
|
+
else
|
|
178
|
+
cinc_version="`${1}/bin/cinc-solo -v | cut -d \" \" -f 2`";
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
echo "$cinc_version" | grep "^${2}" 2>&1 >/dev/null;
|
|
182
|
+
if test $? -eq 0; then
|
|
183
|
+
return 1;
|
|
184
|
+
else
|
|
185
|
+
echo "${2}" | grep "^$cinc_version" 2>&1 >/dev/null;
|
|
186
|
+
if test $? -eq 0; then
|
|
187
|
+
return 1;
|
|
188
|
+
else
|
|
189
|
+
return 0;
|
|
190
|
+
fi
|
|
191
|
+
fi
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
# unable_to_download URL FILE
|
|
195
|
+
unable_to_download() {
|
|
196
|
+
echo "Unable to download $1 to $2, aborting";
|
|
197
|
+
|
|
198
|
+
if test "x${stderr_results}" != "x"; then
|
|
199
|
+
echo "\nDEBUG OUTPUT FOLLOWS:\n${stderr_results}";
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
exit 10;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
# main
|
|
206
|
+
main() {
|
|
207
|
+
should_update_cinc "$chef_omnibus_root" "$version"
|
|
208
|
+
if test $? -eq 0; then
|
|
209
|
+
echo "-----> Installing Cinc Client package (${pretty_version})";
|
|
210
|
+
|
|
211
|
+
# solaris 10 lacks recent enough credentials, so http url is used
|
|
212
|
+
platform="`/usr/bin/uname -s 2>/dev/null`";
|
|
213
|
+
platform_version="`/usr/bin/uname -r 2>/dev/null`";
|
|
214
|
+
if test "x${platform}" = "xSunOS" && test "x${platform_version}" = "x5.10"; then
|
|
215
|
+
chef_omnibus_url=`echo "$chef_omnibus_url" | sed -e "s/https/http/"`;
|
|
216
|
+
fi
|
|
217
|
+
|
|
218
|
+
do_download "$chef_omnibus_url" /tmp/install.sh;
|
|
219
|
+
$sudo_sh /tmp/install.sh $install_flags;
|
|
220
|
+
else
|
|
221
|
+
echo "-----> Cinc Client package installation detected (${pretty_version})";
|
|
222
|
+
fi
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
# augment path in an attempt to find a download program
|
|
226
|
+
PATH="${PATH}:/opt/local/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/sfw/bin";
|
|
227
|
+
export PATH;
|
|
228
|
+
|
|
229
|
+
main
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Check whether a command exists - returns 0 if it does, 1 if it does not
|
|
2
|
+
exists() {
|
|
3
|
+
if command -v $1 >/dev/null 2>&1
|
|
4
|
+
then
|
|
5
|
+
return 0
|
|
6
|
+
else
|
|
7
|
+
return 1
|
|
8
|
+
fi
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
# do_wget URL FILENAME
|
|
12
|
+
do_wget() {
|
|
13
|
+
echo "trying wget..."
|
|
14
|
+
wget -O "$2" "$1" 2>/tmp/stderr
|
|
15
|
+
# check for bad return status
|
|
16
|
+
test $? -ne 0 && return 1
|
|
17
|
+
# check for 404 or empty file
|
|
18
|
+
grep "ERROR 404" /tmp/stderr 2>&1 >/dev/null
|
|
19
|
+
if test $? -eq 0 || test ! -s "$2"; then
|
|
20
|
+
return 1
|
|
21
|
+
fi
|
|
22
|
+
return 0
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# do_curl URL FILENAME
|
|
26
|
+
do_curl() {
|
|
27
|
+
echo "trying curl..."
|
|
28
|
+
curl -L "$1" > "$2"
|
|
29
|
+
# check for bad return status
|
|
30
|
+
[ $? -ne 0 ] && return 1
|
|
31
|
+
# check for bad output or empty file
|
|
32
|
+
grep "The specified key does not exist." "$2" 2>&1 >/dev/null
|
|
33
|
+
if test $? -eq 0 || test ! -s "$2"; then
|
|
34
|
+
return 1
|
|
35
|
+
fi
|
|
36
|
+
return 0
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# do_fetch URL FILENAME
|
|
40
|
+
do_fetch() {
|
|
41
|
+
echo "trying fetch..."
|
|
42
|
+
fetch -o "$2" "$1" 2>/tmp/stderr
|
|
43
|
+
# check for bad return status
|
|
44
|
+
test $? -ne 0 && return 1
|
|
45
|
+
return 0
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# do_perl URL FILENAME
|
|
49
|
+
do_perl() {
|
|
50
|
+
echo "trying perl..."
|
|
51
|
+
perl -e "use LWP::Simple; getprint($ARGV[0]);" "$1" > "$2"
|
|
52
|
+
# check for bad return status
|
|
53
|
+
test $? -ne 0 && return 1
|
|
54
|
+
return 0
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
# do_python URL FILENAME
|
|
58
|
+
do_python() {
|
|
59
|
+
echo "trying python..."
|
|
60
|
+
python -c "import sys,urllib2 ; sys.stdout.write(urllib2.urlopen(sys.argv[1]).read())" "$1" > "$2"
|
|
61
|
+
# check for bad return status
|
|
62
|
+
test $? -ne 0 && return 1
|
|
63
|
+
return 0
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# do_download URL FILENAME
|
|
67
|
+
do_download() {
|
|
68
|
+
PATH=/opt/local/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
|
69
|
+
export PATH
|
|
70
|
+
|
|
71
|
+
echo "downloading $1"
|
|
72
|
+
echo " to file $2"
|
|
73
|
+
|
|
74
|
+
# we try all of these until we get success.
|
|
75
|
+
# perl, in particular may be present but LWP::Simple may not be installed
|
|
76
|
+
|
|
77
|
+
if exists wget; then
|
|
78
|
+
do_wget $1 $2 && return 0
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
if exists curl; then
|
|
82
|
+
do_curl $1 $2 && return 0
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
if exists fetch; then
|
|
86
|
+
do_fetch $1 $2 && return 0
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
if exists perl; then
|
|
90
|
+
do_perl $1 $2 && return 0
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
if exists python; then
|
|
94
|
+
do_python $1 $2 && return 0
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
echo ">>>>>> wget, curl, fetch, perl or python not found on this instance."
|
|
98
|
+
return 16
|
|
99
|
+
}
|