kube_deploy_tools 3.0.5
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/LICENSE.txt +177 -0
- data/README.md +142 -0
- data/bin/deploy +60 -0
- data/bin/generate +28 -0
- data/bin/kdt +17 -0
- data/bin/make_configmap +20 -0
- data/bin/publish +28 -0
- data/bin/push +57 -0
- data/bin/render_deploys_hook +18 -0
- data/bin/templater +34 -0
- data/bin/upgrade +23 -0
- data/lib/kube_deploy_tools.rb +17 -0
- data/lib/kube_deploy_tools/artifact_registry.rb +30 -0
- data/lib/kube_deploy_tools/artifact_registry/driver.rb +13 -0
- data/lib/kube_deploy_tools/artifact_registry/driver_artifactory.rb +155 -0
- data/lib/kube_deploy_tools/artifact_registry/driver_base.rb +37 -0
- data/lib/kube_deploy_tools/artifact_registry/driver_gcs.rb +120 -0
- data/lib/kube_deploy_tools/built_artifacts_file.rb +28 -0
- data/lib/kube_deploy_tools/concurrency.rb +18 -0
- data/lib/kube_deploy_tools/deferred_summary_logging.rb +69 -0
- data/lib/kube_deploy_tools/deploy.rb +215 -0
- data/lib/kube_deploy_tools/deploy/options.rb +114 -0
- data/lib/kube_deploy_tools/deploy_config_file.rb +286 -0
- data/lib/kube_deploy_tools/deploy_config_file/deep_merge.rb +38 -0
- data/lib/kube_deploy_tools/deploy_config_file/util.rb +39 -0
- data/lib/kube_deploy_tools/errors.rb +5 -0
- data/lib/kube_deploy_tools/file_filter.rb +43 -0
- data/lib/kube_deploy_tools/formatted_logger.rb +59 -0
- data/lib/kube_deploy_tools/generate.rb +145 -0
- data/lib/kube_deploy_tools/generate/options.rb +66 -0
- data/lib/kube_deploy_tools/image_registry.rb +30 -0
- data/lib/kube_deploy_tools/image_registry/driver.rb +18 -0
- data/lib/kube_deploy_tools/image_registry/driver/aws.rb +121 -0
- data/lib/kube_deploy_tools/image_registry/driver/base.rb +50 -0
- data/lib/kube_deploy_tools/image_registry/driver/gcp.rb +71 -0
- data/lib/kube_deploy_tools/image_registry/driver/login.rb +26 -0
- data/lib/kube_deploy_tools/image_registry/driver/noop.rb +15 -0
- data/lib/kube_deploy_tools/image_registry/image.rb +17 -0
- data/lib/kube_deploy_tools/kdt.rb +52 -0
- data/lib/kube_deploy_tools/kubectl.rb +25 -0
- data/lib/kube_deploy_tools/kubernetes_resource.rb +57 -0
- data/lib/kube_deploy_tools/kubernetes_resource/deployment.rb +56 -0
- data/lib/kube_deploy_tools/make_configmap.rb +51 -0
- data/lib/kube_deploy_tools/make_configmap/options.rb +39 -0
- data/lib/kube_deploy_tools/object.rb +11 -0
- data/lib/kube_deploy_tools/publish.rb +40 -0
- data/lib/kube_deploy_tools/publish/options.rb +34 -0
- data/lib/kube_deploy_tools/push.rb +129 -0
- data/lib/kube_deploy_tools/push/options.rb +46 -0
- data/lib/kube_deploy_tools/render_deploys_hook.rb +95 -0
- data/lib/kube_deploy_tools/shellrunner.rb +46 -0
- data/lib/kube_deploy_tools/tag.rb +33 -0
- data/lib/kube_deploy_tools/templater.rb +63 -0
- data/lib/kube_deploy_tools/templater/options.rb +74 -0
- data/lib/kube_deploy_tools/version.rb +3 -0
- metadata +191 -0
data/bin/publish
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
require 'kube_deploy_tools/publish'
|
6
|
+
require 'kube_deploy_tools/publish/options'
|
7
|
+
|
8
|
+
require 'kube_deploy_tools/formatted_logger'
|
9
|
+
require 'kube_deploy_tools/shellrunner'
|
10
|
+
|
11
|
+
def options
|
12
|
+
$options ||= begin
|
13
|
+
parser = KubeDeployTools::Publish::Optparser.new
|
14
|
+
parser.parse(ARGV)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
KubeDeployTools::Logger.logger = KubeDeployTools::FormattedLogger.build
|
19
|
+
KubeDeployTools::Shellrunner.shellrunner = KubeDeployTools::Shellrunner.new
|
20
|
+
|
21
|
+
config = KubeDeployTools::DeployConfigFile.new(options.manifest_file)
|
22
|
+
artifact_registry = config.artifact_registries[config.artifact_registry]
|
23
|
+
|
24
|
+
KubeDeployTools::Publish.new(
|
25
|
+
manifest: options.manifest_file,
|
26
|
+
artifact_registry: artifact_registry,
|
27
|
+
output_dir: options.output_path,
|
28
|
+
).publish
|
data/bin/push
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Utility for templating Kubernetes manifests with ERB.
|
3
|
+
#
|
4
|
+
# Example usage:
|
5
|
+
#
|
6
|
+
# push \
|
7
|
+
# --registry aws \
|
8
|
+
# --local-prefix local-registry/ \
|
9
|
+
# --tag my-custom-tag \
|
10
|
+
# image1 image2 image3
|
11
|
+
#
|
12
|
+
# Will tag local-registry/image1:latest, local-registry/image2:latest etc. as
|
13
|
+
# 123456.dkr.ecr.us-west-2.amazonaws.com/image1:my-custom-tag.
|
14
|
+
# Default values for every option are probably what you want to use most of the time.
|
15
|
+
|
16
|
+
require 'optparse'
|
17
|
+
|
18
|
+
require 'kube_deploy_tools/push'
|
19
|
+
require 'kube_deploy_tools/push/options'
|
20
|
+
|
21
|
+
require 'kube_deploy_tools/formatted_logger'
|
22
|
+
require 'kube_deploy_tools/shellrunner'
|
23
|
+
|
24
|
+
def options
|
25
|
+
$options ||= begin
|
26
|
+
parser = KubeDeployTools::Push::Optparser.new
|
27
|
+
parser.parse(ARGV)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def images
|
32
|
+
# Make sure options have been parsed
|
33
|
+
options
|
34
|
+
|
35
|
+
# The rest of ARGV is now the list of images to retag
|
36
|
+
if ARGV.empty?
|
37
|
+
msg = %q(Must supply at least one image
|
38
|
+
|
39
|
+
Example usage:
|
40
|
+
|
41
|
+
push \
|
42
|
+
--local-prefix local-registry/ \
|
43
|
+
--tag my-custom-tag \
|
44
|
+
image1 image2 image3
|
45
|
+
)
|
46
|
+
puts msg
|
47
|
+
exit(1)
|
48
|
+
end
|
49
|
+
|
50
|
+
ARGV
|
51
|
+
end
|
52
|
+
|
53
|
+
KubeDeployTools::Logger.logger = KubeDeployTools::FormattedLogger.build
|
54
|
+
KubeDeployTools::Shellrunner.shellrunner = KubeDeployTools::Shellrunner.new
|
55
|
+
config = KubeDeployTools::DeployConfigFile.new(options.manifest_file)
|
56
|
+
|
57
|
+
KubeDeployTools::Push.new(config, options.local_prefix, options.registries, images, options.tag).publish
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Default rendering hook. Uses built in `templater` to render out all files
|
3
|
+
# underneath kubernetes/ directory, recursively.
|
4
|
+
|
5
|
+
require 'kube_deploy_tools/formatted_logger'
|
6
|
+
require 'kube_deploy_tools/render_deploys_hook'
|
7
|
+
|
8
|
+
KubeDeployTools::Logger.logger = KubeDeployTools::FormattedLogger.build
|
9
|
+
KubeDeployTools::Logger.warn "This subcommand will be disappearing in kdt v3.0."
|
10
|
+
|
11
|
+
def main(argv)
|
12
|
+
config = argv[0]
|
13
|
+
input_dir = argv[1]
|
14
|
+
output_root = argv[2]
|
15
|
+
KubeDeployTools::RenderDeploysHook.render_deploys(config, input_dir, output_root)
|
16
|
+
end
|
17
|
+
|
18
|
+
main(ARGV)
|
data/bin/templater
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Utility for templating Kubernetes manifests with ERB.
|
3
|
+
#
|
4
|
+
# Example usage:
|
5
|
+
#
|
6
|
+
# templater \
|
7
|
+
# --template kubernetes/ds-datadog.yaml.erb \
|
8
|
+
# --set environment=staging \
|
9
|
+
# --set tag=$(git rev-parse --short=7 HEAD) \
|
10
|
+
# --values staging.yaml \
|
11
|
+
# > build/kubernetes/ds-datadog.yaml
|
12
|
+
#
|
13
|
+
# Values can be passed to templater to expose variables available in
|
14
|
+
# the ERB templates, such as a git tag or the environment name.
|
15
|
+
# Values can be passed with:
|
16
|
+
# * 1 or more key-value pairs e.g. --set git_tag=123456 --set environment=local
|
17
|
+
# * a YAML file e.g. --values production.yaml
|
18
|
+
|
19
|
+
require 'kube_deploy_tools/formatted_logger'
|
20
|
+
require 'kube_deploy_tools/templater'
|
21
|
+
require 'kube_deploy_tools/templater/options'
|
22
|
+
|
23
|
+
KubeDeployTools::Logger.logger = KubeDeployTools::FormattedLogger.build
|
24
|
+
KubeDeployTools::Logger.warn "This subcommand will be disappearing in kdt v3.0."
|
25
|
+
|
26
|
+
def options
|
27
|
+
parser = KubeDeployTools::Templater::Optparser.new
|
28
|
+
ops = parser.parse(ARGV)
|
29
|
+
ops.merge_values
|
30
|
+
ops
|
31
|
+
end
|
32
|
+
|
33
|
+
templater = KubeDeployTools::Templater.new
|
34
|
+
templater.template_to_file(options.template, options.values, options.output)
|
data/bin/upgrade
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
require 'kube_deploy_tools/formatted_logger'
|
6
|
+
require 'kube_deploy_tools/shellrunner'
|
7
|
+
require 'kube_deploy_tools/deploy_config_file'
|
8
|
+
|
9
|
+
KubeDeployTools::Logger.logger = KubeDeployTools::FormattedLogger.build
|
10
|
+
KubeDeployTools::Shellrunner.shellrunner = KubeDeployTools::Shellrunner.new
|
11
|
+
|
12
|
+
options = {
|
13
|
+
:file => 'deploy.yml',
|
14
|
+
}
|
15
|
+
OptionParser.new do |opts|
|
16
|
+
opts.on('-f', '--file file', 'Config file path') do |file|
|
17
|
+
options[:file] = file
|
18
|
+
end
|
19
|
+
end.parse!
|
20
|
+
|
21
|
+
config_file_path = options[:file] || ARGV[0]
|
22
|
+
|
23
|
+
KubeDeployTools::DeployConfigFile.new(config_file_path).upgrade!
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
require 'kube_deploy_tools/formatted_logger'
|
3
|
+
require 'kube_deploy_tools/kubectl'
|
4
|
+
require 'kube_deploy_tools/shellrunner'
|
5
|
+
|
6
|
+
require 'kube_deploy_tools/deploy'
|
7
|
+
require 'kube_deploy_tools/deploy/options'
|
8
|
+
|
9
|
+
require 'kube_deploy_tools/templater'
|
10
|
+
require 'kube_deploy_tools/templater/options'
|
11
|
+
|
12
|
+
require 'kube_deploy_tools/generate'
|
13
|
+
require 'kube_deploy_tools/generate/options'
|
14
|
+
|
15
|
+
module KubeDeployTools
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'kube_deploy_tools/artifact_registry/driver'
|
2
|
+
require 'kube_deploy_tools/formatted_logger'
|
3
|
+
|
4
|
+
module KubeDeployTools
|
5
|
+
# Read-only model for artifact_registries[] array element in KDT deploy.yaml
|
6
|
+
# configuration file.
|
7
|
+
class ArtifactRegistry
|
8
|
+
attr_accessor :name, :driver_name, :config, :driver
|
9
|
+
|
10
|
+
def initialize(h)
|
11
|
+
@name = h['name']
|
12
|
+
@driver_name = h['driver']
|
13
|
+
@config = h['config']
|
14
|
+
|
15
|
+
if !ArtifactRegistry::Driver::MAPPINGS.key?(@driver_name)
|
16
|
+
Logger.warn("Unsupported .artifact_registries.driver: #{@driver_name}")
|
17
|
+
else
|
18
|
+
@driver = ArtifactRegistry::Driver::MAPPINGS
|
19
|
+
.fetch(@driver_name)
|
20
|
+
.new(config: @config)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def ==(o)
|
25
|
+
@name == o.name
|
26
|
+
@driver == o.driver
|
27
|
+
@config == o.config
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require_relative 'driver_base'
|
2
|
+
|
3
|
+
require 'kube_deploy_tools/formatted_logger'
|
4
|
+
require 'kube_deploy_tools/shellrunner'
|
5
|
+
require 'kube_deploy_tools/object'
|
6
|
+
|
7
|
+
require 'artifactory'
|
8
|
+
require 'fileutils'
|
9
|
+
require 'uri'
|
10
|
+
|
11
|
+
|
12
|
+
EXT_TAR_GZ = ".tar.gz"
|
13
|
+
|
14
|
+
module KubeDeployTools
|
15
|
+
class ArtifactRegistry::Driver::Artifactory < ArtifactRegistry::Driver::Base
|
16
|
+
# Artifactory configuration is configurable by environment variables
|
17
|
+
# by default:
|
18
|
+
# export ARTIFACTORY_ENDPOINT=http://my.storage.server/artifactory
|
19
|
+
# export ARTIFACTORY_USERNAME=admin
|
20
|
+
# export ARTIFACTORY_PASSWORD=password
|
21
|
+
# See https://github.com/chef/artifactory-client#create-a-connection.
|
22
|
+
|
23
|
+
def initialize(config:)
|
24
|
+
@config = config
|
25
|
+
|
26
|
+
Artifactory.endpoint = @config.fetch('endpoint', '')
|
27
|
+
@repo = @config.fetch('repo', '')
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def get_local_artifact_path(name:, flavor:, local_dir:)
|
32
|
+
artifact_name = get_artifact_name(name: name, flavor: flavor)
|
33
|
+
|
34
|
+
local_artifact_path = File.join(local_dir, artifact_name)
|
35
|
+
|
36
|
+
local_artifact_path
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_registry_artifact_path(name:, flavor:, project:, build_number:)
|
40
|
+
# NOTE(joshk): If the naming format changes, it represents a breaking
|
41
|
+
# change where all past clients will not be able to download new builds and
|
42
|
+
# new clients will not be able to download old builds. Change with caution.
|
43
|
+
"#{project}/#{build_number}/#{get_artifact_name(name: name, flavor: flavor)}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def upload(local_dir:, name:, flavor:, project:, build_number:)
|
47
|
+
# Pack up contents of each flavor_dir to a correctly named artifact.
|
48
|
+
flavor_dir = File.join(local_dir, "#{name}_#{flavor}")
|
49
|
+
|
50
|
+
package(
|
51
|
+
name: name,
|
52
|
+
flavor: flavor,
|
53
|
+
input_dir: flavor_dir,
|
54
|
+
output_dir: local_dir,
|
55
|
+
)
|
56
|
+
|
57
|
+
local_artifact_path = get_local_artifact_path(
|
58
|
+
local_dir: local_dir,
|
59
|
+
name: name,
|
60
|
+
flavor: flavor,
|
61
|
+
)
|
62
|
+
|
63
|
+
registry_artifact_path = get_registry_artifact_path(
|
64
|
+
project: project,
|
65
|
+
name: name,
|
66
|
+
flavor: flavor,
|
67
|
+
build_number: build_number,
|
68
|
+
)
|
69
|
+
artifactory_url = "#{Artifactory.endpoint}/#{@repo}/#{registry_artifact_path}"
|
70
|
+
Logger.info("Uploading #{local_artifact_path} to #{artifactory_url}")
|
71
|
+
artifact = Artifactory::Resource::Artifact.new(local_path: local_artifact_path)
|
72
|
+
artifact.upload(@repo, registry_artifact_path)
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_artifact_name(name:, flavor:)
|
76
|
+
"manifests_#{name}_#{flavor}#{EXT_TAR_GZ}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def package(name:, flavor:, input_dir:, output_dir:)
|
80
|
+
local_artifact_path = get_local_artifact_path(name: name, flavor: flavor, local_dir: output_dir)
|
81
|
+
|
82
|
+
Shellrunner.check_call('tar', '-C', input_dir, '-czf', local_artifact_path, '.')
|
83
|
+
|
84
|
+
local_artifact_path
|
85
|
+
end
|
86
|
+
|
87
|
+
def download(project:, build_number:, flavor:, name:, pre_apply_hook:, output_dir:)
|
88
|
+
registry_artifact_path = get_registry_artifact_path(
|
89
|
+
name: name, flavor: flavor, project: project, build_number: build_number)
|
90
|
+
|
91
|
+
registry_artifact_full_path = [
|
92
|
+
Artifactory.endpoint,
|
93
|
+
@repo,
|
94
|
+
registry_artifact_path,
|
95
|
+
].join('/')
|
96
|
+
|
97
|
+
local_artifact_path = download_artifact(registry_artifact_full_path, output_dir)
|
98
|
+
local_artifact_path = uncompress_artifact(local_artifact_path, output_dir)
|
99
|
+
|
100
|
+
if pre_apply_hook
|
101
|
+
out, err, status = Shellrunner.run_call(pre_apply_hook, local_artifact_path)
|
102
|
+
if !status.success?
|
103
|
+
raise "Failed to run post download hook #{pre_apply_hook}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
local_artifact_path
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_latest_build_number(project)
|
111
|
+
project_url = [
|
112
|
+
Artifactory.endpoint,
|
113
|
+
@repo,
|
114
|
+
"#{project}/"
|
115
|
+
].join('/')
|
116
|
+
project_builds_html = Shellrunner.run_call('curl', project_url).first
|
117
|
+
# store build entries string from html into an array
|
118
|
+
build_links_pattern = /(?<=">).+(?=\s{4})/
|
119
|
+
build_entries = project_builds_html.scan(build_links_pattern) # example of element: 10/</a> 13-Nov-2017 13:51
|
120
|
+
build_number_pattern = /^\d+/
|
121
|
+
build_number = build_entries.
|
122
|
+
map { |x| x.match(build_number_pattern).to_s.to_i }.
|
123
|
+
max.
|
124
|
+
to_s
|
125
|
+
if build_number.empty?
|
126
|
+
raise "Failed to find a valid build number. Project URL: #{project_url}"
|
127
|
+
end
|
128
|
+
build_number
|
129
|
+
end
|
130
|
+
|
131
|
+
def download_artifact(input_path, output_dir_path)
|
132
|
+
uri = URI.parse(input_path)
|
133
|
+
filename = File.basename(uri.path)
|
134
|
+
output_path = File.join(output_dir_path, filename)
|
135
|
+
out, err, status = Shellrunner.run_call('curl', '-o', output_path, input_path, '--silent', '--fail')
|
136
|
+
if !status.success?
|
137
|
+
raise "Failed to download remote deploy artifact #{uri}"
|
138
|
+
end
|
139
|
+
|
140
|
+
output_path
|
141
|
+
end
|
142
|
+
|
143
|
+
def uncompress_artifact(input_path, output_dir_path)
|
144
|
+
dirname = File.basename(input_path).chomp(EXT_TAR_GZ)
|
145
|
+
output_path = File.join(output_dir_path, dirname)
|
146
|
+
FileUtils.mkdir_p(output_path)
|
147
|
+
out, err, status = Shellrunner.run_call('tar', '-xzf', input_path, '-C', output_path)
|
148
|
+
if !status.success?
|
149
|
+
raise "Failed to uncompress deploy artifact #{input_path}"
|
150
|
+
end
|
151
|
+
|
152
|
+
output_path
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'kube_deploy_tools/formatted_logger'
|
2
|
+
require 'kube_deploy_tools/shellrunner'
|
3
|
+
|
4
|
+
# Abstract Driver class that specific implementations inherit
|
5
|
+
module KubeDeployTools
|
6
|
+
class ArtifactRegistry
|
7
|
+
module Driver
|
8
|
+
class Base
|
9
|
+
def initialize(config:)
|
10
|
+
@config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
# upload should publish the artifact identified by the given name and flavor
|
14
|
+
# in the input directory to the corresponding location in the artifact
|
15
|
+
# registry. The project and build number should be included in the
|
16
|
+
# namespace of the artifact registry path for this artifact.
|
17
|
+
def upload(local_dir:, name:, flavor:, project:, build_number:)
|
18
|
+
raise "#{self.class}#publish not implemented"
|
19
|
+
end
|
20
|
+
|
21
|
+
# download should retrieve the artifact namespaced with the given
|
22
|
+
# project and build number and identified by the name and flavor.
|
23
|
+
# The artifact should be put into the output directory.
|
24
|
+
# An optional pre-apply hook will process each artifact at the end.
|
25
|
+
def download(project:, build_number:, flavor:, name:, pre_apply_hook:, output_dir:)
|
26
|
+
raise "#{self.class}#download not implemented"
|
27
|
+
end
|
28
|
+
|
29
|
+
# get_latest_build_number should find the artifact from the most recent
|
30
|
+
# build
|
31
|
+
def get_latest_build_number(project)
|
32
|
+
raise "#{self.class}#get_latest_build_number not implemented"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require_relative 'driver_base'
|
2
|
+
|
3
|
+
require 'kube_deploy_tools/formatted_logger'
|
4
|
+
require 'kube_deploy_tools/shellrunner'
|
5
|
+
require 'kube_deploy_tools/object'
|
6
|
+
|
7
|
+
require 'fileutils'
|
8
|
+
require 'uri'
|
9
|
+
require 'find'
|
10
|
+
|
11
|
+
|
12
|
+
module KubeDeployTools
|
13
|
+
class ArtifactRegistry::Driver::GCS < ArtifactRegistry::Driver::Base
|
14
|
+
def initialize(config:)
|
15
|
+
@config = config
|
16
|
+
|
17
|
+
@bucket = @config.fetch('bucket')
|
18
|
+
prefix = @config.fetch('prefix', '')
|
19
|
+
if !prefix.empty?
|
20
|
+
@bucket = "#{@bucket}/#{prefix}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_local_artifact_path(name:, flavor:, local_dir:)
|
25
|
+
artifact_name = get_artifact_name(name: name, flavor: flavor)
|
26
|
+
|
27
|
+
local_artifact_path = File.join(local_dir, artifact_name)
|
28
|
+
|
29
|
+
local_artifact_path
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_registry_artifact_path(name:, flavor:, project:, build_number:)
|
33
|
+
# NOTE(joshk): If the naming format changes, it represents a breaking
|
34
|
+
# change where all past clients will not be able to download new builds and
|
35
|
+
# new clients will not be able to download old builds. Change with caution.
|
36
|
+
#
|
37
|
+
"#{@bucket}/project/#{project}/build/#{build_number}/artifact/#{get_artifact_name(name: name, flavor: flavor)}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_artifact_name(name:, flavor:)
|
41
|
+
"manifests_#{name}_#{flavor}.yaml"
|
42
|
+
end
|
43
|
+
|
44
|
+
def package(name:, flavor:, input_dir:, output_dir:)
|
45
|
+
local_artifact_path = get_local_artifact_path(name: name, flavor: flavor, local_dir: output_dir)
|
46
|
+
File.open(local_artifact_path, 'w') do |merged|
|
47
|
+
Find.find(input_dir).
|
48
|
+
select { |path| path =~ /.*\.yaml$/ }.
|
49
|
+
each do |e|
|
50
|
+
contents = File.open(e, 'r').read
|
51
|
+
contents.each_line do |line|
|
52
|
+
merged << line
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
local_artifact_path
|
57
|
+
end
|
58
|
+
|
59
|
+
def download(project:, build_number:, flavor:, name:, pre_apply_hook:, output_dir:)
|
60
|
+
registry_artifact_path = get_registry_artifact_path(
|
61
|
+
name: name, flavor: flavor, project: project, build_number: build_number)
|
62
|
+
|
63
|
+
local_artifact_path = download_artifact(registry_artifact_path, output_dir)
|
64
|
+
|
65
|
+
if pre_apply_hook
|
66
|
+
out, err, status = Shellrunner.run_call(pre_apply_hook, local_artifact_path)
|
67
|
+
if !status.success?
|
68
|
+
raise "Failed to run post download hook #{pre_apply_hook}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
local_artifact_path
|
73
|
+
end
|
74
|
+
|
75
|
+
def download_artifact(input_path, output_dir_path)
|
76
|
+
filename = File.basename(input_path)
|
77
|
+
output_path = File.join(output_dir_path, filename)
|
78
|
+
out, err, status = Shellrunner.run_call('gsutil', 'cp', input_path, output_path)
|
79
|
+
|
80
|
+
if !status.success?
|
81
|
+
raise "Failed to download remote deploy artifact #{input_path}"
|
82
|
+
end
|
83
|
+
|
84
|
+
output_path
|
85
|
+
end
|
86
|
+
|
87
|
+
def upload(local_dir:, name:, flavor:, project:, build_number:)
|
88
|
+
# Pack up contents of each flavor_dir to a correctly named artifact.
|
89
|
+
flavor_dir = File.join(local_dir, "#{name}_#{flavor}")
|
90
|
+
|
91
|
+
package(
|
92
|
+
name: name,
|
93
|
+
flavor: flavor,
|
94
|
+
input_dir: flavor_dir,
|
95
|
+
output_dir: local_dir,
|
96
|
+
)
|
97
|
+
|
98
|
+
local_artifact_path = get_local_artifact_path(
|
99
|
+
local_dir: local_dir,
|
100
|
+
name: name,
|
101
|
+
flavor: flavor,
|
102
|
+
)
|
103
|
+
|
104
|
+
registry_artifact_path = get_registry_artifact_path(
|
105
|
+
project: project,
|
106
|
+
name: name,
|
107
|
+
flavor: flavor,
|
108
|
+
build_number: build_number,
|
109
|
+
)
|
110
|
+
|
111
|
+
Logger.info("Uploading #{local_artifact_path} to #{registry_artifact_path}")
|
112
|
+
out, err, status = Shellrunner.run_call('gsutil', '-m', 'cp', local_artifact_path, registry_artifact_path)
|
113
|
+
if !status.success?
|
114
|
+
raise "Failed to upload remote deploy artifact from #{local_artifact_path} to #{registry_artifact_path}"
|
115
|
+
end
|
116
|
+
|
117
|
+
registry_artifact_path
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|