dapp 0.2.8 → 0.3.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 +8 -8
- data/config/en/common.yml +3 -1
- data/config/en/net_status.yml +5 -2
- data/lib/dapp.rb +9 -6
- data/lib/dapp/application.rb +30 -5
- data/lib/dapp/application/logging.rb +2 -2
- data/lib/dapp/application/path.rb +10 -6
- data/lib/dapp/build/stage/base.rb +77 -9
- data/lib/dapp/build/stage/chef_cookbooks.rb +1 -1
- data/lib/dapp/build/stage/from.rb +2 -1
- data/lib/dapp/build/stage/infra_install.rb +1 -1
- data/lib/dapp/build/stage/source_1.rb +1 -1
- data/lib/dapp/build/stage/source_1_archive.rb +0 -4
- data/lib/dapp/build/stage/source_2.rb +1 -1
- data/lib/dapp/build/stage/source_3.rb +1 -1
- data/lib/dapp/build/stage/source_base.rb +3 -3
- data/lib/dapp/builder/chef.rb +160 -140
- data/lib/dapp/cli.rb +2 -1
- data/lib/dapp/cli/base.rb +1 -1
- data/lib/dapp/cli/build.rb +7 -7
- data/lib/dapp/cli/flush.rb +3 -3
- data/lib/dapp/cli/flush/{build_cache.rb → metadata.rb} +7 -7
- data/lib/dapp/cli/flush/{stage_cache.rb → stages.rb} +4 -4
- data/lib/dapp/cli/push.rb +3 -3
- data/lib/dapp/cli/run.rb +59 -0
- data/lib/dapp/config/application.rb +20 -2
- data/lib/dapp/config/artifact.rb +69 -0
- data/lib/dapp/config/chef.rb +27 -0
- data/lib/dapp/config/docker.rb +1 -1
- data/lib/dapp/config/git_artifact.rb +3 -29
- data/lib/dapp/config/shell.rb +20 -0
- data/lib/dapp/controller.rb +21 -22
- data/lib/dapp/exception/base.rb +1 -5
- data/lib/dapp/filelock.rb +1 -1
- data/lib/dapp/git_artifact.rb +2 -2
- data/lib/dapp/git_repo/base.rb +5 -5
- data/lib/dapp/git_repo/own.rb +6 -2
- data/lib/dapp/git_repo/remote.rb +5 -3
- data/lib/dapp/helper/cli.rb +7 -1
- data/lib/dapp/helper/log.rb +2 -2
- data/lib/dapp/helper/shellout.rb +1 -1
- data/lib/dapp/helper/trivia.rb +0 -4
- data/lib/dapp/image/arguments.rb +115 -0
- data/lib/dapp/image/docker.rb +76 -0
- data/lib/dapp/image/stage.rb +74 -0
- data/lib/dapp/version.rb +1 -1
- metadata +9 -6
- data/lib/dapp/docker_image.rb +0 -51
- data/lib/dapp/stage_image.rb +0 -160
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NTM1NTkwNWNjMzM0YTkzYTdlOGMzODY4MzE4ZGQ5YWZmNjI0YmU5Zg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YjM5ODYyYzIzNDA3YjkyODFkYThjYjE2NTFhNDA4MGQxM2IyZGE2Mg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OThjNmU0YmUyODZlODdkNzI2YjdiM2MyZDA4YmZkOWY2NTdmM2Y4MGJkYWM1
|
10
|
+
MTliMzkyMjcwMThiMGMzNTE2MGQyMGI0NGMyMTNlMDdkM2M5NDMzYjcxZTc0
|
11
|
+
YzM3YmMzZTkyNGYwZTM4YmJjMjY5YmFkN2U3YmVmMTgwODA5ZWY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OWRiZGIzNzY0MTQzYzk3OTJlMDYxNDA4ZjI2OWEwZGQzNDQ2NTQ3NjQ4MGUx
|
14
|
+
N2Y4NTVmY2UyNTNhMGUzNmUwMTI1Zjg3ODJjZDhlYmIwZDIyZDgxZTFiZmRm
|
15
|
+
YWUwNGU0ZmY1MzJlNmU2ZDNhYmRmYTg1ZWFmODU1ZTYxMWFjZDQ=
|
data/config/en/common.yml
CHANGED
@@ -5,10 +5,12 @@ en:
|
|
5
5
|
info: "date: %{date}\nsize: %{size} MB"
|
6
6
|
commands: "commands:"
|
7
7
|
process:
|
8
|
+
artifact_copy: "copying artifact '%{name}'"
|
8
9
|
git_artifact_loading: 'loading git_artifact'
|
10
|
+
git_artifact_clone: "cloning remote git_artifact '%{name}'"
|
11
|
+
git_artifact_fetch: "fetching remote git_artifact '%{name}'"
|
9
12
|
chefdk_loading: 'loading chefdk'
|
10
13
|
berks_vendor: 'berks_vendor'
|
11
|
-
git_artifact_fetch: "fetching remote git_artifact '%{name}'"
|
12
14
|
status:
|
13
15
|
process:
|
14
16
|
pushing: '[PUSHING]'
|
data/config/en/net_status.yml
CHANGED
@@ -5,6 +5,7 @@ en:
|
|
5
5
|
shell_command_failed: ">>> START STREAM\n%{stream}\n>>> END STREAM"
|
6
6
|
application:
|
7
7
|
application_not_built: "Application hasn't been built yet!"
|
8
|
+
application_not_run: "Application run failed!"
|
8
9
|
git_branch_without_name: "Application has specific revision that isn't associated with a branch name!"
|
9
10
|
ci_environment_required: 'CI environment required (Travis or GitLab CI)!'
|
10
11
|
build:
|
@@ -14,11 +15,13 @@ en:
|
|
14
15
|
another_image_already_tagged: 'Image with other id already tagged!'
|
15
16
|
built_id_not_defined: '`from.built_id` not defined!'
|
16
17
|
controller:
|
17
|
-
|
18
|
+
push_command_unexpected_apps_number: "Push command can process only one application!"
|
19
|
+
run_command_unexpected_apps_number: "Run command can process only one application!"
|
18
20
|
no_such_app: "No such app: '%{patterns}' in '%{path}'!"
|
19
21
|
dappfile_not_found: "Dappfile not found!"
|
20
22
|
config:
|
21
23
|
builder_type_conflict: 'Conflict between builder types!'
|
22
24
|
builder_type_unsupported: "Defined unsupported builder type `%{type}`!"
|
23
25
|
docker_from_not_defined: "Docker `from` not defined!"
|
24
|
-
|
26
|
+
artifact_unexpected_attribute: "Artifact doesn't have attribute '%{attr}'!"
|
27
|
+
git_artifact_unexpected_attribute: "'%{type}' git artifact doesn't have attribute '%{attr}'!"
|
data/lib/dapp.rb
CHANGED
@@ -32,13 +32,15 @@ require 'dapp/cli/push'
|
|
32
32
|
require 'dapp/cli/smartpush'
|
33
33
|
require 'dapp/cli/list'
|
34
34
|
require 'dapp/cli/flush'
|
35
|
-
require 'dapp/cli/flush/
|
36
|
-
require 'dapp/cli/flush/
|
35
|
+
require 'dapp/cli/flush/stages'
|
36
|
+
require 'dapp/cli/flush/metadata'
|
37
|
+
require 'dapp/cli/run'
|
37
38
|
require 'dapp/filelock'
|
38
39
|
require 'dapp/config/application'
|
39
40
|
require 'dapp/config/main'
|
40
41
|
require 'dapp/config/chef'
|
41
42
|
require 'dapp/config/shell'
|
43
|
+
require 'dapp/config/artifact'
|
42
44
|
require 'dapp/config/git_artifact'
|
43
45
|
require 'dapp/config/docker'
|
44
46
|
require 'dapp/builder/base'
|
@@ -66,20 +68,21 @@ require 'dapp/application/logging'
|
|
66
68
|
require 'dapp/application/path'
|
67
69
|
require 'dapp/application/tags'
|
68
70
|
require 'dapp/application'
|
69
|
-
require 'dapp/
|
70
|
-
require 'dapp/
|
71
|
+
require 'dapp/image/arguments'
|
72
|
+
require 'dapp/image/docker'
|
73
|
+
require 'dapp/image/stage'
|
71
74
|
require 'dapp/git_repo/base'
|
72
75
|
require 'dapp/git_repo/own'
|
73
76
|
require 'dapp/git_repo/remote'
|
74
77
|
require 'dapp/git_artifact'
|
75
|
-
require 'dapp/exception/base'
|
76
|
-
require 'dapp/exception/introspect_image'
|
77
78
|
require 'dapp/error/base'
|
78
79
|
require 'dapp/error/application'
|
79
80
|
require 'dapp/error/build'
|
80
81
|
require 'dapp/error/config'
|
81
82
|
require 'dapp/error/controller'
|
82
83
|
require 'dapp/error/shellout'
|
84
|
+
require 'dapp/exception/base'
|
85
|
+
require 'dapp/exception/introspect_image'
|
83
86
|
|
84
87
|
# Dapp
|
85
88
|
module Dapp
|
data/lib/dapp/application.rb
CHANGED
@@ -14,21 +14,28 @@ module Dapp
|
|
14
14
|
attr_reader :config
|
15
15
|
attr_reader :cli_options
|
16
16
|
attr_reader :ignore_git_fetch
|
17
|
+
attr_reader :is_artifact
|
17
18
|
|
18
|
-
def initialize(config:, cli_options:, ignore_git_fetch: false)
|
19
|
+
def initialize(config:, cli_options:, ignore_git_fetch: false, is_artifact: false)
|
19
20
|
@config = config
|
20
21
|
@cli_options = cli_options
|
21
22
|
|
22
|
-
@
|
23
|
-
@
|
23
|
+
@tmp_path = Dir.mktmpdir(cli_options[:tmp_dir_prefix] || 'dapp-')
|
24
|
+
@metadata_path = cli_options[:metadata_dir] || home_path('.dapps-metadata')
|
24
25
|
|
25
26
|
@last_stage = Build::Stage::Source5.new(self)
|
26
27
|
@ignore_git_fetch = ignore_git_fetch
|
28
|
+
@is_artifact = is_artifact
|
27
29
|
end
|
28
30
|
|
29
31
|
def build!
|
30
|
-
|
31
|
-
|
32
|
+
log_step(config._name)
|
33
|
+
with_log_indent do
|
34
|
+
last_stage.build!
|
35
|
+
last_stage.save_in_cache!
|
36
|
+
end
|
37
|
+
ensure
|
38
|
+
FileUtils.rm_rf(tmp_path)
|
32
39
|
end
|
33
40
|
|
34
41
|
def export!(repo)
|
@@ -46,10 +53,28 @@ module Dapp
|
|
46
53
|
end
|
47
54
|
end
|
48
55
|
|
56
|
+
def run(docker_options, command)
|
57
|
+
raise Error::Application, code: :application_not_built unless last_stage.image.tagged?
|
58
|
+
cmd = "docker run #{[docker_options, last_stage.image.name, command].flatten.compact.join(' ')}"
|
59
|
+
if dry_run?
|
60
|
+
log_info(cmd)
|
61
|
+
else
|
62
|
+
system(cmd) || raise(Error::Application, code: :application_not_run)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def signature
|
67
|
+
last_stage.send(:signature)
|
68
|
+
end
|
69
|
+
|
49
70
|
def builder
|
50
71
|
@builder ||= Builder.const_get(config._builder.capitalize).new(self)
|
51
72
|
end
|
52
73
|
|
74
|
+
def meta_options
|
75
|
+
{ cli_options: cli_options, ignore_git_fetch: ignore_git_fetch }
|
76
|
+
end
|
77
|
+
|
53
78
|
protected
|
54
79
|
|
55
80
|
attr_reader :last_stage
|
@@ -58,8 +58,8 @@ module Dapp
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
def log_secondary_process(message, **
|
62
|
-
log_process(message, **
|
61
|
+
def log_secondary_process(message, **kwargs, &blk)
|
62
|
+
log_process(message, **kwargs.merge(style: { message: :secondary, success: :secondary }), &blk)
|
63
63
|
end
|
64
64
|
|
65
65
|
def log_process_verbose(message, process:, style: {}, &blk)
|
@@ -7,16 +7,20 @@ module Dapp
|
|
7
7
|
make_path(config._home_path, *path).expand_path
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
make_path(@
|
10
|
+
def tmp_path(*path)
|
11
|
+
make_path(@tmp_path, *path).expand_path.tap { |p| FileUtils.mkdir_p p.parent }
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
make_path(@
|
14
|
+
def metadata_path(*path)
|
15
|
+
make_path(@metadata_path, home_path.basename, *path).expand_path.tap { |p| FileUtils.mkdir_p p.parent }
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
make_path('/.
|
18
|
+
def container_dapp_path(*path)
|
19
|
+
make_path('/.dapp', *path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def container_tmp_path(*path)
|
23
|
+
container_dapp_path('tmp', *path)
|
20
24
|
end
|
21
25
|
|
22
26
|
private
|
@@ -46,14 +46,16 @@ module Dapp
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def signature
|
49
|
-
hashsum prev_stage.signature
|
49
|
+
hashsum [prev_stage.signature, artifacts_signatures]
|
50
50
|
end
|
51
51
|
|
52
52
|
def image
|
53
53
|
@image ||= begin
|
54
|
-
|
55
|
-
image.add_volume "#{application.
|
54
|
+
Image::Stage.new(name: image_name, from: from_image).tap do |image|
|
55
|
+
image.add_volume "#{application.tmp_path}:#{application.container_tmp_path}"
|
56
|
+
before_artifacts.each { |artifact| apply_artifact(artifact, image) }
|
56
57
|
yield image if block_given?
|
58
|
+
after_artifacts.each { |artifact| apply_artifact(artifact, image) }
|
57
59
|
end
|
58
60
|
end
|
59
61
|
end
|
@@ -73,7 +75,7 @@ module Dapp
|
|
73
75
|
end
|
74
76
|
|
75
77
|
def should_be_introspected?
|
76
|
-
application.cli_options[:introspect_stage] == name && !application.dry_run?
|
78
|
+
application.cli_options[:introspect_stage] == name && !application.dry_run? && !application.is_artifact
|
77
79
|
end
|
78
80
|
|
79
81
|
def image_build!
|
@@ -94,14 +96,14 @@ module Dapp
|
|
94
96
|
end
|
95
97
|
|
96
98
|
def image_info
|
97
|
-
date,
|
98
|
-
_date,
|
99
|
-
[date, (
|
99
|
+
date, size = image.info
|
100
|
+
_date, from_size = from_image.info
|
101
|
+
[date, (from_size.to_f - size.to_f).abs]
|
100
102
|
end
|
101
103
|
|
102
104
|
def format_image_info
|
103
|
-
date,
|
104
|
-
application.t(code: 'image.info', data: { date: Time.parse(date).localtime, size:
|
105
|
+
date, size = image_info
|
106
|
+
application.t(code: 'image.info', data: { date: Time.parse(date).localtime, size: size.to_f.round(2) })
|
105
107
|
end
|
106
108
|
|
107
109
|
# rubocop:disable Metrics/AbcSize
|
@@ -115,6 +117,72 @@ module Dapp
|
|
115
117
|
end
|
116
118
|
end if application.log? && application.log_verbose?
|
117
119
|
end
|
120
|
+
# rubocop:enable Metrics/AbcSize
|
121
|
+
|
122
|
+
def before_artifacts
|
123
|
+
@before_artifacts ||= do_artifacts(application.config._artifact.select { |artifact| artifact._before == name })
|
124
|
+
end
|
125
|
+
|
126
|
+
def after_artifacts
|
127
|
+
@after_artifacts ||= do_artifacts(application.config._artifact.select { |artifact| artifact._after == name })
|
128
|
+
end
|
129
|
+
|
130
|
+
def do_artifacts(artifacts)
|
131
|
+
artifacts.map do |artifact|
|
132
|
+
{
|
133
|
+
name: artifact._config._name,
|
134
|
+
options: artifact._artifact_options,
|
135
|
+
app: Application.new(config: artifact._config, is_artifact: true, **application.meta_options).tap(&:build!)
|
136
|
+
}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def artifacts_signatures
|
141
|
+
(before_artifacts + after_artifacts).map { |artifact| hashsum [artifact[:app].signature, artifact[:options]] }
|
142
|
+
end
|
143
|
+
|
144
|
+
def apply_artifact(artifact, image)
|
145
|
+
return if application.dry_run?
|
146
|
+
|
147
|
+
artifact_name = artifact[:name]
|
148
|
+
app = artifact[:app]
|
149
|
+
cwd = artifact[:options][:cwd]
|
150
|
+
paths = artifact[:options][:paths]
|
151
|
+
owner = artifact[:options][:owner]
|
152
|
+
group = artifact[:options][:group]
|
153
|
+
where_to_add = artifact[:options][:where_to_add]
|
154
|
+
|
155
|
+
docker_options = ['--rm',
|
156
|
+
"--volume #{application.tmp_path('artifact', artifact_name)}:#{app.container_tmp_path(artifact_name)}",
|
157
|
+
'--entrypoint /bin/sh']
|
158
|
+
commands = safe_cp(where_to_add, app.container_tmp_path(artifact_name), Process.uid, Process.gid)
|
159
|
+
application.log_secondary_process(application.t(code: 'process.artifact_copy', data: { name: artifact_name }), short: true) do
|
160
|
+
app.run(docker_options, Array(application.shellout_pack(commands)))
|
161
|
+
end
|
162
|
+
|
163
|
+
commands = safe_cp(application.container_tmp_path('artifact', artifact_name), where_to_add, owner, group, cwd, paths)
|
164
|
+
image.add_commands commands
|
165
|
+
end
|
166
|
+
|
167
|
+
# rubocop:disable Metrics/ParameterLists
|
168
|
+
def safe_cp(from, to, owner, group, cwd = '', paths = [])
|
169
|
+
credentials = ''
|
170
|
+
credentials += "-o #{owner} " if owner
|
171
|
+
credentials += "-g #{group} " if group
|
172
|
+
|
173
|
+
commands = []
|
174
|
+
commands << ['install', credentials, '-d', to].join(' ')
|
175
|
+
|
176
|
+
copy_files = lambda do |from_, cwd_, path_ = ''|
|
177
|
+
"find #{File.join(from_, cwd_, path_)} -type f -exec bash -ec 'install -D #{credentials} {} " \
|
178
|
+
"#{File.join(to, "$(echo {} | sed -e \"s/#{File.join(from_, cwd_).gsub('/', '\\/')}//g\")")}' \\;"
|
179
|
+
end
|
180
|
+
|
181
|
+
commands.concat(paths.empty? ? Array(copy_files.call(from, cwd)) : paths.map { |path| copy_files.call(from, cwd, path) })
|
182
|
+
commands << "find #{to} -type d -exec bash -ec 'install -d #{credentials} {}' \\;"
|
183
|
+
commands.join(' && ')
|
184
|
+
end
|
185
|
+
# rubocop:enable Metrics/ParameterLists
|
118
186
|
end # Base
|
119
187
|
end # Stage
|
120
188
|
end # Build
|
@@ -5,6 +5,7 @@ module Dapp
|
|
5
5
|
class From < Base
|
6
6
|
def signature
|
7
7
|
hashsum [from_image_name,
|
8
|
+
artifacts_signatures,
|
8
9
|
application.config._docker._from_cache_version,
|
9
10
|
Dapp::BUILD_CACHE_VERSION]
|
10
11
|
end
|
@@ -28,7 +29,7 @@ module Dapp
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def from_image
|
31
|
-
@from_image ||=
|
32
|
+
@from_image ||= Image::Stage.new(name: from_image_name)
|
32
33
|
end
|
33
34
|
|
34
35
|
def image_info
|
@@ -29,7 +29,7 @@ module Dapp
|
|
29
29
|
bash_commands = []
|
30
30
|
volumes = []
|
31
31
|
application.git_artifacts.each do |git_artifact|
|
32
|
-
volumes << "#{git_artifact.repo.
|
32
|
+
volumes << "#{git_artifact.repo.path}:#{git_artifact.repo.container_path}"
|
33
33
|
bash_commands.concat(git_artifact.send(apply_command_method, self))
|
34
34
|
end
|
35
35
|
|
@@ -43,7 +43,7 @@ module Dapp
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def dependencies_checksum
|
46
|
-
hashsum [prev_stage.signature]
|
46
|
+
hashsum [prev_stage.signature, artifacts_signatures]
|
47
47
|
end
|
48
48
|
|
49
49
|
def layer_commit(git_artifact)
|
@@ -94,7 +94,7 @@ module Dapp
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def layer_commit_file_path(git_artifact)
|
97
|
-
application.
|
97
|
+
application.metadata_path git_artifact.filename ".#{name}.#{git_artifact.paramshash}.#{dependencies_checksum}.commit"
|
98
98
|
end
|
99
99
|
|
100
100
|
def dependency_files_checksum(regs)
|
data/lib/dapp/builder/chef.rb
CHANGED
@@ -2,34 +2,23 @@ module Dapp
|
|
2
2
|
module Builder
|
3
3
|
# Chef
|
4
4
|
class Chef < Base
|
5
|
-
|
5
|
+
LOCAL_COOKBOOK_CHECKSUM_PATTERNS = %w(
|
6
6
|
recipes/**/*
|
7
7
|
files/**/*
|
8
8
|
templates/**/*
|
9
9
|
).freeze
|
10
10
|
|
11
|
-
STAGE_LOCAL_COOKBOOK_PATTERNS = %w(
|
12
|
-
metadata.json
|
13
|
-
recipes/%{stage}.rb
|
14
|
-
recipes/*_%{stage}.rb
|
15
|
-
files/default/%{stage}/*
|
16
|
-
templates/default/%{stage}/*
|
17
|
-
).freeze
|
18
|
-
|
19
11
|
DEFAULT_CHEFDK_IMAGE = 'dappdeps/chefdk:0.17.3-1'.freeze # TODO: config, DSL, DEFAULT_CHEFDK_IMAGE
|
20
12
|
|
21
13
|
[:infra_install, :infra_setup, :app_install, :app_setup].each do |stage|
|
22
14
|
define_method(:"#{stage}_checksum") { stage_cookbooks_checksum(stage) }
|
23
15
|
|
24
16
|
define_method(:"#{stage}") do |image|
|
25
|
-
install_stage_cookbooks(stage)
|
26
|
-
install_chef_solo_stage_config(stage)
|
27
|
-
|
28
17
|
unless stage_empty?(stage)
|
29
18
|
image.add_volumes_from(chefdk_container)
|
30
19
|
image.add_commands 'export PATH=/.dapp/deps/chefdk/bin:$PATH'
|
31
20
|
|
32
|
-
image.add_volume "#{
|
21
|
+
image.add_volume "#{stage_tmp_path(stage)}:#{container_stage_tmp_path(stage)}"
|
33
22
|
image.add_commands ['chef-solo',
|
34
23
|
"-c #{container_stage_config_path(stage)}",
|
35
24
|
"-o #{stage_cookbooks_runlist(stage).join(',')}"].join(' ')
|
@@ -42,9 +31,11 @@ module Dapp
|
|
42
31
|
end
|
43
32
|
|
44
33
|
def chef_cookbooks(image)
|
34
|
+
image.add_volume "#{cookbooks_vendor_path}:#{application.container_dapp_path('chef_vendored_cookbooks')}"
|
45
35
|
image.add_commands(
|
46
|
-
|
47
|
-
"cp -a #{
|
36
|
+
'mkdir -p /usr/share/dapp/chef_repo',
|
37
|
+
["cp -a #{application.container_dapp_path('chef_vendored_cookbooks')} ",
|
38
|
+
'/usr/share/dapp/chef_repo/cookbooks'].join
|
48
39
|
)
|
49
40
|
end
|
50
41
|
|
@@ -74,76 +65,40 @@ module Dapp
|
|
74
65
|
@cookbook_metadata ||= CookbookMetadata.new(cookbook_metadata_path)
|
75
66
|
end
|
76
67
|
|
68
|
+
|
77
69
|
def berksfile_lock_checksum
|
78
70
|
application.hashsum berksfile_lock_path.read if berksfile_lock_path.exist?
|
79
71
|
end
|
80
72
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
"#{name}::#{entrypoint}"
|
89
|
-
end
|
90
|
-
|
91
|
-
res.concat(application.config._chef._modules.map do |name|
|
92
|
-
to_runlist_entrypoint[name, stage]
|
93
|
-
end.compact)
|
94
|
-
|
95
|
-
project_main_entry = to_runlist_entrypoint[project_name, stage]
|
96
|
-
res << project_main_entry if project_main_entry
|
97
|
-
|
98
|
-
res.concat(application.config._app_runlist.map do |app_component|
|
99
|
-
to_runlist_entrypoint[project_name, [app_component, stage].join('_')]
|
100
|
-
end.compact)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
# rubocop:enable Metrics/AbcSize
|
104
|
-
|
105
|
-
def local_cookbook_paths
|
106
|
-
@local_cookbook_paths ||= berksfile.local_cookbooks
|
107
|
-
.values
|
108
|
-
.map { |cookbook| cookbook[:path] }
|
109
|
-
.product(LOCAL_COOKBOOK_PATTERNS)
|
110
|
-
.map { |cb, dir| Dir[cb.join(dir)] }
|
111
|
-
.flatten
|
112
|
-
.map(&Pathname.method(:new))
|
113
|
-
end
|
114
|
-
|
115
|
-
def stage_cookbooks_vendored_paths(stage, with_files: false)
|
116
|
-
Dir[cookbooks_vendor_path('*')]
|
117
|
-
.map do |cookbook_path|
|
118
|
-
if ['mdapp-*', project_name].any? { |pattern| File.fnmatch(pattern, File.basename(cookbook_path)) }
|
119
|
-
STAGE_LOCAL_COOKBOOK_PATTERNS.map do |pattern|
|
120
|
-
Dir[File.join(cookbook_path, pattern % { stage: stage })]
|
121
|
-
end
|
122
|
-
elsif with_files
|
123
|
-
Dir[File.join(cookbook_path, '**/*')]
|
124
|
-
else
|
125
|
-
cookbook_path
|
126
|
-
end
|
127
|
-
end
|
73
|
+
def local_cookbook_paths_for_checksum
|
74
|
+
@local_cookbook_paths_for_checksum ||= berksfile
|
75
|
+
.local_cookbooks
|
76
|
+
.values
|
77
|
+
.map { |cookbook| cookbook[:path] }
|
78
|
+
.product(LOCAL_COOKBOOK_CHECKSUM_PATTERNS)
|
79
|
+
.map { |cb, dir| Dir[cb.join(dir)] }
|
128
80
|
.flatten
|
129
81
|
.map(&Pathname.method(:new))
|
130
82
|
end
|
131
83
|
|
84
|
+
def stage_cookbooks_paths_for_checksum(stage)
|
85
|
+
install_stage_cookbooks(stage)
|
86
|
+
Dir[stage_cookbooks_path(stage, '**/*')].map(&Pathname.method(:new))
|
87
|
+
end
|
88
|
+
|
132
89
|
def stage_cookbooks_checksum_path(stage)
|
133
|
-
application.
|
90
|
+
application.metadata_path("#{cookbooks_checksum}.#{stage}.checksum")
|
134
91
|
end
|
135
92
|
|
136
93
|
def stage_cookbooks_checksum(stage)
|
137
94
|
if stage_cookbooks_checksum_path(stage).exist?
|
138
95
|
stage_cookbooks_checksum_path(stage).read.strip
|
139
96
|
else
|
140
|
-
|
141
|
-
|
142
|
-
if stage == :chef_cookbooks
|
143
|
-
checksum = cookbooks_checksum
|
97
|
+
checksum = if stage == :chef_cookbooks
|
98
|
+
cookbooks_checksum
|
144
99
|
else
|
145
|
-
|
146
|
-
_paths_checksum(
|
100
|
+
application.hashsum [
|
101
|
+
_paths_checksum(stage_cookbooks_paths_for_checksum(stage)),
|
147
102
|
*application.config._chef._modules,
|
148
103
|
stage == :infra_install ? chefdk_image : nil
|
149
104
|
].compact
|
@@ -157,11 +112,12 @@ module Dapp
|
|
157
112
|
def cookbooks_checksum
|
158
113
|
@cookbooks_checksum ||= application.hashsum [
|
159
114
|
berksfile_lock_checksum,
|
160
|
-
_paths_checksum(
|
115
|
+
_paths_checksum(local_cookbook_paths_for_checksum),
|
161
116
|
*application.config._chef._modules
|
162
117
|
]
|
163
118
|
end
|
164
119
|
|
120
|
+
|
165
121
|
def chefdk_image
|
166
122
|
DEFAULT_CHEFDK_IMAGE # TODO: config, DSL, DEFAULT_CHEFDK_IMAGE
|
167
123
|
end
|
@@ -187,101 +143,165 @@ module Dapp
|
|
187
143
|
end
|
188
144
|
end
|
189
145
|
|
146
|
+
|
190
147
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
191
148
|
def install_cookbooks
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
true
|
230
|
-
end
|
149
|
+
volumes_from = chefdk_container
|
150
|
+
application.log_secondary_process(application.t(code: 'process.berks_vendor')) do
|
151
|
+
ssh_auth_socket_path = nil
|
152
|
+
ssh_auth_socket_path = Pathname.new(ENV['SSH_AUTH_SOCK']).expand_path if ENV['SSH_AUTH_SOCK'] && File.exist?(ENV['SSH_AUTH_SOCK'])
|
153
|
+
|
154
|
+
vendor_commands = [
|
155
|
+
'mkdir -p ~/.ssh',
|
156
|
+
'echo "Host *" >> ~/.ssh/config',
|
157
|
+
'echo " StrictHostKeyChecking no" >> ~/.ssh/config',
|
158
|
+
'if [ ! -f Berksfile.lock ] ; then echo "Berksfile.lock not found" 1>&2 ; exit 1 ; fi',
|
159
|
+
'cp -a Berksfile.lock /tmp/Berksfile.lock.orig',
|
160
|
+
'/.dapp/deps/chefdk/bin/berks vendor /tmp/vendored_cookbooks',
|
161
|
+
'export LOCKDIFF=$(diff -u0 Berksfile.lock /tmp/Berksfile.lock.orig)',
|
162
|
+
['if [ "$LOCKDIFF" != "" ] ; then ',
|
163
|
+
'cp -a /tmp/Berksfile.lock.orig Berksfile.lock ; ',
|
164
|
+
'echo -e "Bad Berksfile.lock\n$LOCKDIFF" 1>&2 ; exit 1 ; fi'].join,
|
165
|
+
["find /tmp/vendored_cookbooks -type f -exec bash -ec '",
|
166
|
+
"install -D -o #{Process.uid} -g #{Process.gid} --mode $(stat -c %a {}) {} ",
|
167
|
+
"#{_cookbooks_vendor_path}/$(echo {} | sed -e \"s/\\/tmp\\/vendored_cookbooks\\///g\")' \\;"].join
|
168
|
+
]
|
169
|
+
|
170
|
+
application.shellout!(
|
171
|
+
['docker run --rm',
|
172
|
+
("--volume #{ssh_auth_socket_path}:#{ssh_auth_socket_path}" if ssh_auth_socket_path),
|
173
|
+
"--volume #{_cookbooks_vendor_path.tap(&:mkpath)}:#{_cookbooks_vendor_path}",
|
174
|
+
*berksfile.local_cookbooks
|
175
|
+
.values
|
176
|
+
.map { |cookbook| "--volume #{cookbook[:path]}:#{cookbook[:path]}" },
|
177
|
+
"--volumes-from #{volumes_from}",
|
178
|
+
"--workdir #{berksfile_path.parent}",
|
179
|
+
("--env SSH_AUTH_SOCK=#{ssh_auth_socket_path}" if ssh_auth_socket_path),
|
180
|
+
"dappdeps/berksdeps:0.1.0 bash #{application.shellout_pack(vendor_commands.join(' && '))}"].compact.join(' '),
|
181
|
+
log_verbose: application.log_verbose?
|
182
|
+
)
|
183
|
+
|
184
|
+
true
|
231
185
|
end
|
232
186
|
end
|
233
187
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
234
188
|
|
235
|
-
def
|
236
|
-
|
237
|
-
stage_cookbooks_vendored_paths(stage).each do |path|
|
238
|
-
new_path = stage_cookbooks_path(stage, path.relative_path_from(cookbooks_vendor_path))
|
239
|
-
new_path.parent.mkpath
|
240
|
-
FileUtils.cp_r path, new_path
|
241
|
-
end
|
189
|
+
def _cookbooks_vendor_path
|
190
|
+
application.metadata_path("cookbooks.#{cookbooks_checksum}")
|
242
191
|
end
|
243
192
|
|
244
|
-
def
|
245
|
-
|
193
|
+
def cookbooks_vendor_path(*path)
|
194
|
+
_cookbooks_vendor_path.tap do |cookbooks_path|
|
195
|
+
install_cookbooks unless cookbooks_path.exist?
|
196
|
+
end.join(*path)
|
246
197
|
end
|
247
198
|
|
248
|
-
def install_chef_solo_stage_config(stage)
|
249
|
-
stage_config_path(stage).write [
|
250
|
-
"file_cache_path \"/var/cache/dapp/chef\"\n",
|
251
|
-
"cookbook_path \"#{container_stage_cookbooks_path(stage)}\"\n"
|
252
|
-
].join
|
253
|
-
end
|
254
199
|
|
255
|
-
|
256
|
-
|
257
|
-
|
200
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
201
|
+
def install_stage_cookbooks(stage)
|
202
|
+
@install_stage_cookbooks ||= {}
|
203
|
+
@install_stage_cookbooks[stage] ||= true.tap do
|
204
|
+
common_paths = proc do |cookbook_path|
|
205
|
+
[['metadata.json', 'metadata.json'],
|
206
|
+
["files/#{stage}", 'files/default'],
|
207
|
+
["templates/#{stage}", 'templates/default']
|
208
|
+
].select { |from, _| cookbook_path.join(from).exist? }
|
209
|
+
end
|
258
210
|
|
259
|
-
|
260
|
-
|
211
|
+
install_paths = Dir[cookbooks_vendor_path('*')]
|
212
|
+
.map(&Pathname.method(:new))
|
213
|
+
.map { |cookbook_path|
|
214
|
+
cookbook_name = File.basename cookbook_path
|
215
|
+
is_project = (cookbook_name == project_name)
|
216
|
+
is_mdapp = cookbook_name.start_with? 'mdapp-'
|
217
|
+
mdapp_enabled = is_mdapp && application.config._chef._modules.include?(cookbook_name)
|
218
|
+
|
219
|
+
paths = if is_project
|
220
|
+
recipe_paths = application.config._chef._recipes
|
221
|
+
.map { |recipe| ["recipes/#{stage}/#{recipe}.rb", "recipes/#{recipe}.rb"] }
|
222
|
+
.select { |from, _| cookbook_path.join(from).exist? }
|
223
|
+
|
224
|
+
(recipe_paths + common_paths[cookbook_path]) if recipe_paths.any?
|
225
|
+
elsif is_mdapp and mdapp_enabled
|
226
|
+
recipe_path = "recipes/#{stage}.rb"
|
227
|
+
if cookbook_path.join(recipe_path).exist?
|
228
|
+
[[recipe_path, recipe_path]] + common_paths[cookbook_path]
|
229
|
+
end
|
230
|
+
else
|
231
|
+
[['.', '.']]
|
232
|
+
end
|
233
|
+
|
234
|
+
[cookbook_path, paths] if paths and paths.any?
|
235
|
+
}
|
236
|
+
.compact
|
237
|
+
|
238
|
+
stage_cookbooks_path(stage).mkpath
|
239
|
+
install_paths.each do |cookbook_path, paths|
|
240
|
+
paths.each do |from, to|
|
241
|
+
from_path = cookbook_path.join(from)
|
242
|
+
to_path = stage_cookbooks_path(stage, cookbook_path.basename, to)
|
243
|
+
to_path.parent.mkpath
|
244
|
+
FileUtils.cp_r from_path, to_path
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
261
248
|
end
|
249
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
250
|
+
|
251
|
+
# rubocop:disable Metrics/AbcSize
|
252
|
+
def stage_cookbooks_runlist(stage)
|
253
|
+
install_stage_cookbooks(stage)
|
254
|
+
|
255
|
+
@stage_cookbooks_runlist ||= {}
|
256
|
+
@stage_cookbooks_runlist[stage] ||= [].tap do |res|
|
257
|
+
to_runlist_entrypoint = proc do |cookbook, entrypoint|
|
258
|
+
entrypoint_file = stage_cookbooks_path(stage, cookbook, 'recipes', "#{entrypoint}.rb")
|
259
|
+
next unless entrypoint_file.exist?
|
260
|
+
"#{cookbook}::#{entrypoint}"
|
261
|
+
end
|
262
|
+
|
263
|
+
res.concat(application.config._chef._recipes.map do |recipe|
|
264
|
+
to_runlist_entrypoint[project_name, recipe]
|
265
|
+
end.flatten.compact)
|
262
266
|
|
263
|
-
|
264
|
-
|
267
|
+
res.concat(application.config._chef._modules.map do |mod|
|
268
|
+
to_runlist_entrypoint[mod, stage]
|
269
|
+
end.flatten.compact)
|
270
|
+
end
|
265
271
|
end
|
272
|
+
# rubocop:enable Metrics/AbcSize
|
266
273
|
|
267
|
-
def
|
268
|
-
|
274
|
+
def stage_empty?(stage)
|
275
|
+
stage_cookbooks_runlist(stage).empty?
|
269
276
|
end
|
270
277
|
|
271
278
|
def stage_cookbooks_path(stage, *path)
|
272
|
-
|
279
|
+
stage_tmp_path(stage, 'cookbooks', *path)
|
273
280
|
end
|
274
281
|
|
275
|
-
def container_stage_cookbooks_path(stage, *path)
|
276
|
-
container_stage_build_path(stage, 'cookbooks', *path)
|
277
|
-
end
|
278
282
|
|
279
|
-
def
|
280
|
-
|
283
|
+
def install_chef_solo_stage_config(stage)
|
284
|
+
@install_chef_solo_stage_config ||= {}
|
285
|
+
@install_chef_solo_stage_config[stage] ||= true.tap do
|
286
|
+
stage_tmp_path(stage, 'config.rb').write [
|
287
|
+
"file_cache_path \"/var/cache/dapp/chef\"\n",
|
288
|
+
"cookbook_path \"#{container_stage_tmp_path(stage, 'cookbooks')}\"\n"
|
289
|
+
].join
|
290
|
+
end
|
281
291
|
end
|
282
292
|
|
283
293
|
def container_stage_config_path(stage, *path)
|
284
|
-
|
294
|
+
install_chef_solo_stage_config(stage)
|
295
|
+
container_stage_tmp_path(stage, 'config.rb', *path)
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
def stage_tmp_path(stage, *path)
|
300
|
+
application.tmp_path(application.config._name, stage).join(*path)
|
301
|
+
end
|
302
|
+
|
303
|
+
def container_stage_tmp_path(_stage, *path)
|
304
|
+
path.compact.map(&:to_s).inject(Pathname.new('/chef_build'), &:+)
|
285
305
|
end
|
286
306
|
|
287
307
|
def _paths_checksum(paths)
|