dapp 0.0.24 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +13 -5
  2. data/bin/dapp +17 -1
  3. data/config/en/common.yml +23 -0
  4. data/config/en/net_status.yml +24 -0
  5. data/lib/dapp.rb +68 -12
  6. data/lib/dapp/application.rb +57 -0
  7. data/lib/dapp/application/git_artifact.rb +26 -0
  8. data/lib/dapp/application/logging.rb +120 -0
  9. data/lib/dapp/application/path.rb +31 -0
  10. data/lib/dapp/application/tags.rb +65 -0
  11. data/lib/dapp/build/stage/app_install.rb +19 -0
  12. data/lib/dapp/build/stage/app_setup.rb +19 -0
  13. data/lib/dapp/build/stage/base.rb +106 -0
  14. data/lib/dapp/build/stage/from.rb +40 -0
  15. data/lib/dapp/build/stage/infra_install.rb +23 -0
  16. data/lib/dapp/build/stage/infra_setup.rb +19 -0
  17. data/lib/dapp/build/stage/source_1.rb +31 -0
  18. data/lib/dapp/build/stage/source_1_archive.rb +31 -0
  19. data/lib/dapp/build/stage/source_2.rb +20 -0
  20. data/lib/dapp/build/stage/source_3.rb +27 -0
  21. data/lib/dapp/build/stage/source_4.rb +31 -0
  22. data/lib/dapp/build/stage/source_5.rb +51 -0
  23. data/lib/dapp/build/stage/source_base.rb +109 -0
  24. data/lib/dapp/builder/base.rb +44 -0
  25. data/lib/dapp/builder/chef.rb +242 -0
  26. data/lib/dapp/builder/chef/berksfile.rb +54 -0
  27. data/lib/dapp/builder/shell.rb +16 -0
  28. data/lib/dapp/cli.rb +10 -44
  29. data/lib/dapp/cli/base.rb +55 -0
  30. data/lib/dapp/cli/build.rb +6 -140
  31. data/lib/dapp/cli/flush.rb +19 -0
  32. data/lib/dapp/cli/flush/build_cache.rb +26 -0
  33. data/lib/dapp/cli/flush/stage_cache.rb +23 -0
  34. data/lib/dapp/cli/list.rb +19 -0
  35. data/lib/dapp/cli/push.rb +59 -0
  36. data/lib/dapp/cli/smartpush.rb +19 -0
  37. data/lib/dapp/config/application.rb +98 -0
  38. data/lib/dapp/config/chef.rb +20 -0
  39. data/lib/dapp/config/docker.rb +39 -0
  40. data/lib/dapp/config/git_artifact.rb +78 -0
  41. data/lib/dapp/config/main.rb +23 -0
  42. data/lib/dapp/config/shell.rb +40 -0
  43. data/lib/dapp/controller.rb +103 -0
  44. data/lib/dapp/docker_image.rb +51 -0
  45. data/lib/dapp/error/application.rb +6 -0
  46. data/lib/dapp/error/base.rb +10 -0
  47. data/lib/dapp/error/build.rb +6 -0
  48. data/lib/dapp/error/config.rb +6 -0
  49. data/lib/dapp/error/controller.rb +6 -0
  50. data/lib/dapp/error/shellout.rb +6 -0
  51. data/lib/dapp/filelock.rb +1 -1
  52. data/lib/dapp/git_artifact.rb +43 -272
  53. data/lib/dapp/git_repo/base.rb +10 -12
  54. data/lib/dapp/git_repo/own.rb +7 -3
  55. data/lib/dapp/git_repo/remote.rb +14 -20
  56. data/lib/dapp/helper/cli.rb +66 -0
  57. data/lib/dapp/helper/i18n.rb +20 -0
  58. data/lib/dapp/helper/log.rb +72 -0
  59. data/lib/dapp/helper/paint.rb +27 -0
  60. data/lib/dapp/helper/sha256.rb +14 -0
  61. data/lib/dapp/helper/shellout.rb +41 -0
  62. data/lib/dapp/helper/streaming.rb +49 -0
  63. data/lib/dapp/helper/trivia.rb +27 -0
  64. data/lib/dapp/stage_image.rb +98 -0
  65. data/lib/dapp/version.rb +3 -1
  66. metadata +207 -51
  67. data/lib/dapp/atomizer.rb +0 -56
  68. data/lib/dapp/builder.rb +0 -230
  69. data/lib/dapp/builder/cascade_tagging.rb +0 -48
  70. data/lib/dapp/builder/centos7.rb +0 -47
  71. data/lib/dapp/builder/chefify.rb +0 -107
  72. data/lib/dapp/builder/ci_tagging.rb +0 -53
  73. data/lib/dapp/builder/git_tagging.rb +0 -21
  74. data/lib/dapp/builder/manual_tagging.rb +0 -22
  75. data/lib/dapp/builder/ubuntu1404.rb +0 -20
  76. data/lib/dapp/builder/ubuntu1604.rb +0 -20
  77. data/lib/dapp/docker.rb +0 -207
  78. data/lib/dapp/git_repo/chronicler.rb +0 -44
@@ -0,0 +1,39 @@
1
+ module Dapp
2
+ module Config
3
+ # Docker
4
+ class Docker
5
+ attr_reader :_expose, :_workdir, :_env
6
+ attr_reader :_from_cache_version
7
+
8
+ def initialize
9
+ @_expose = []
10
+ @_env = []
11
+ end
12
+
13
+ def from(image_name, cache_version: nil)
14
+ @_from = image_name
15
+ @_from_cache_version = cache_version
16
+ end
17
+
18
+ def expose(*args)
19
+ @_expose.concat(args)
20
+ end
21
+
22
+ def workdir(path)
23
+ @_workdir = path
24
+ end
25
+
26
+ def env(*args)
27
+ @_env.concat(args)
28
+ end
29
+
30
+ def _from
31
+ @_from || fail(Error::Config, code: :docker_from_not_defined)
32
+ end
33
+
34
+ def clone
35
+ Marshal.load(Marshal.dump(self))
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,78 @@
1
+ module Dapp
2
+ module Config
3
+ # GitArtifact
4
+ class GitArtifact
5
+ attr_reader :_local
6
+ attr_reader :_remote
7
+
8
+ def initialize
9
+ @_local = []
10
+ @_remote = []
11
+ end
12
+
13
+ def local(*args)
14
+ @_local.tap { |local| local << Local.new(*args) unless args.empty? }
15
+ end
16
+
17
+ def remote(*args)
18
+ @_remote.tap { |remote| remote << Remote.new(*args) unless args.empty? }
19
+ end
20
+
21
+ def clone
22
+ Marshal.load(Marshal.dump(self))
23
+ end
24
+
25
+ # Local
26
+ class Local
27
+ attr_accessor :_where_to_add, :_cwd, :_paths, :_owner, :_group
28
+
29
+ def initialize(where_to_add, **options)
30
+ @_cwd = ''
31
+ @_where_to_add = where_to_add
32
+
33
+ options.each do |k, v|
34
+ respond_to?("_#{k}=") ? send(:"_#{k}=", v) : fail(Error::Config, code: :git_artifact_unexpected_attribute,
35
+ data: { type: object_name, attr: k })
36
+ end
37
+ end
38
+
39
+ def _artifact_options
40
+ {
41
+ where_to_add: _where_to_add,
42
+ cwd: _cwd,
43
+ paths: _paths,
44
+ owner: _owner,
45
+ group: _group
46
+ }
47
+ end
48
+
49
+ def clone
50
+ Marshal.load(Marshal.dump(self))
51
+ end
52
+
53
+ protected
54
+
55
+ def object_name
56
+ self.class.to_s.split('::').last
57
+ end
58
+ end
59
+
60
+ # Remote
61
+ class Remote < Local
62
+ attr_accessor :_url, :_name, :_branch, :_ssh_key_path
63
+
64
+ def initialize(url, where_to_add, **options)
65
+ @_url = url
66
+ @_name = url.gsub(%r{.*?([^\/ ]+)\.git}, '\\1')
67
+ @_branch = options.delete(:branch)
68
+ @_ssg_key_path = options.delete(:ssg_key_path)
69
+ super(where_to_add, **options)
70
+ end
71
+
72
+ def _artifact_options
73
+ super.merge(name: _name, branch: _branch)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,23 @@
1
+ module Dapp
2
+ module Config
3
+ # Main
4
+ class Main < Application
5
+ def initialize(**options)
6
+ @_home_path = Pathname.new(options[:dappfile_path]).parent.expand_path.to_s
7
+ @_name = Pathname.new(@_home_path).basename.to_s
8
+ @_builder = Pathname.new(@_home_path).join('Berksfile').exist? ? :chef : :shell
9
+
10
+ @_docker = Docker.new
11
+ @_git_artifact = GitArtifact.new
12
+ @_shell = Shell.new
13
+ @_chef = Chef.new
14
+
15
+ super(nil)
16
+ end
17
+
18
+ def name(value)
19
+ @_name = value
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,40 @@
1
+ module Dapp
2
+ module Config
3
+ # Shell
4
+ class Shell
5
+ attr_reader :_infra_install, :_infra_setup, :_app_install, :_app_setup
6
+ attr_reader :_infra_install_cache_version, :_infra_setup_cache_version, :_app_install_cache_version, :_app_setup_cache_version
7
+
8
+ def initialize
9
+ @_infra_install = []
10
+ @_infra_setup = []
11
+ @_app_install = []
12
+ @_app_setup = []
13
+ end
14
+
15
+ def infra_install(*args, cache_version: nil)
16
+ @_infra_install.concat(args)
17
+ @_infra_install_cache_version = cache_version
18
+ end
19
+
20
+ def infra_setup(*args, cache_version: nil)
21
+ @_infra_setup.concat(args)
22
+ @_infra_setup_cache_version = cache_version
23
+ end
24
+
25
+ def app_install(*args, cache_version: nil)
26
+ _app_install.concat(args)
27
+ @_app_install_cache_version = cache_version
28
+ end
29
+
30
+ def app_setup(*args, cache_version: nil)
31
+ _app_setup.concat(args)
32
+ @_app_setup_cache_version = cache_version
33
+ end
34
+
35
+ def clone
36
+ Marshal.load(Marshal.dump(self))
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,103 @@
1
+ module Dapp
2
+ # Controller
3
+ class Controller
4
+ include Helper::Log
5
+ include Helper::Shellout
6
+
7
+ attr_reader :cli_options, :patterns
8
+
9
+ def initialize(cli_options:, patterns: nil)
10
+ @cli_options = cli_options
11
+ @cli_options[:log_indent] = 0
12
+
13
+ @patterns = patterns || []
14
+ @patterns << '*' unless @patterns.any?
15
+
16
+ paint_initialize
17
+ Helper::I18n.initialize
18
+ build_confs
19
+ end
20
+
21
+ def build
22
+ @build_confs.each do |build_conf|
23
+ log_step(build_conf._name)
24
+ with_log_indent { Application.new(config: build_conf, cli_options: cli_options).build! }
25
+ end
26
+ end
27
+
28
+ def list
29
+ @build_confs.each do |build_conf|
30
+ log(build_conf._name)
31
+ end
32
+ end
33
+
34
+ def push(repo)
35
+ fail Error::Controller, code: :push_command_unexpected_apps unless @build_confs.one?
36
+ Application.new(config: @build_confs.first, cli_options: cli_options, ignore_git_fetch: true).export!(repo)
37
+ end
38
+
39
+ def smartpush(repo_prefix)
40
+ @build_confs.each do |build_conf|
41
+ log_step(build_conf._name)
42
+ repo = File.join(repo_prefix, build_conf._name)
43
+ with_log_indent { Application.new(config: build_conf, cli_options: cli_options, ignore_git_fetch: true).export!(repo) }
44
+ end
45
+ end
46
+
47
+ def flush_build_cache
48
+ @build_confs.each do |build_conf|
49
+ log(build_conf._name)
50
+ app = Application.new(config: build_conf, cli_options: cli_options, ignore_git_fetch: true)
51
+ FileUtils.rm_rf app.build_cache_path
52
+ end
53
+ end
54
+
55
+ def self.flush_stage_cache
56
+ shellout('docker rmi $(docker images --format="{{.Repository}}:{{.Tag}}" dapp)')
57
+ shellout('docker rmi $(docker images -f "dangling=true" -q)')
58
+ end
59
+
60
+ private
61
+
62
+ def build_confs
63
+ @build_confs ||= begin
64
+ dappfiles = []
65
+ if File.exist? dappfile_path
66
+ dappfiles << dappfile_path
67
+ elsif File.exist? dapps_path
68
+ dappfiles += Dir.glob(File.join([dapps_path, '*', 'Dappfile'].compact))
69
+ else
70
+ fail Error::Controller, code: :dappfile_not_found
71
+ end
72
+ dappfiles.flatten.uniq!
73
+ dappfiles.map { |dappfile| apps(dappfile, app_filters: patterns) }.flatten.tap do |apps|
74
+ fail Error::Controller, code: :no_such_app, data: { path: dappfile_path, patterns: patterns.join(', ') } if apps.empty?
75
+ end
76
+ end
77
+ end
78
+
79
+ def apps(dappfile_path, app_filters:)
80
+ config = Config::Main.new(dappfile_path: dappfile_path) do |conf|
81
+ conf.instance_eval File.read(dappfile_path), dappfile_path
82
+ end
83
+ config._apps.select { |app| app_filters.any? { |pattern| File.fnmatch(pattern, app._name) } }
84
+ end
85
+
86
+ def dappfile_path
87
+ @dappfile_path ||= File.join [cli_options[:dir], 'Dappfile'].compact
88
+ end
89
+
90
+ def dapps_path
91
+ @dapps_path ||= File.join [cli_options[:dir], '.dapps'].compact
92
+ end
93
+
94
+ def paint_initialize
95
+ Paint.mode = case cli_options[:log_color]
96
+ when 'auto' then STDOUT.tty? ? 8 : 0
97
+ when 'on' then 8
98
+ when 'off' then 0
99
+ else fail
100
+ end
101
+ end
102
+ end # Controller
103
+ end # Dapp
@@ -0,0 +1,51 @@
1
+ module Dapp
2
+ # DockerImage
3
+ class DockerImage
4
+ include Helper::Shellout
5
+
6
+ attr_reader :from
7
+ attr_reader :name
8
+
9
+ def initialize(name:, from: nil)
10
+ @from = from
11
+ @name = name
12
+ end
13
+
14
+ def id
15
+ @id || begin
16
+ unless (output = shellout!("docker images -q --no-trunc=true #{name}").stdout.strip).empty?
17
+ output
18
+ end
19
+ end
20
+ end
21
+
22
+ def untag!
23
+ fail Error::Build, code: :image_already_untagged, data: { name: name } unless tagged?
24
+ shellout!("docker rmi #{name}")
25
+ end
26
+
27
+ def push!(log_verbose: false, log_time: false)
28
+ fail Error::Build, code: :image_not_exist, data: { name: name } unless tagged?
29
+ shellout!("docker push #{name}", log_verbose: log_verbose, log_time: log_time)
30
+ end
31
+
32
+ def pull!(log_verbose: false, log_time: false)
33
+ return if tagged?
34
+ shellout!("docker pull #{name}", log_verbose: log_verbose, log_time: log_time)
35
+ @pulled = true
36
+ end
37
+
38
+ def tagged?
39
+ !!id
40
+ end
41
+
42
+ def pulled?
43
+ !!@pulled
44
+ end
45
+
46
+ def info
47
+ fail Error::Build, code: :image_not_exist, data: { name: name } unless tagged?
48
+ shellout!("docker inspect --format='{{.Created}} {{.Size}}' #{name}").stdout.strip.split
49
+ end
50
+ end # DockerImage
51
+ end # Dapp
@@ -0,0 +1,6 @@
1
+ module Dapp
2
+ module Error
3
+ # Application
4
+ class Application < Base; end
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module Dapp
2
+ module Error
3
+ # Base
4
+ class Base < NetStatus::Exception
5
+ def initialize(net_status = {})
6
+ super(net_status.merge(context: self.class.to_s.split('::').last.downcase))
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ module Dapp
2
+ module Error
3
+ # Build
4
+ class Build < Base; end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Dapp
2
+ module Error
3
+ # Config
4
+ class Config < Base; end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Dapp
2
+ module Error
3
+ # Controller
4
+ class Controller < Base; end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Dapp
2
+ module Error
3
+ # Shellout
4
+ class Shellout < Base; end
5
+ end
6
+ end
data/lib/dapp/filelock.rb CHANGED
@@ -28,7 +28,7 @@ module Dapp
28
28
  protected
29
29
 
30
30
  def filelock_lockfile(filelock, error_message: 'Already in use!', timeout: 10)
31
- File.open(build_path(filelock), File::RDWR | File::CREAT, 0644) do |file|
31
+ File.open(build_path(filelock), File::RDWR | File::CREAT, 0o644) do |file|
32
32
  Timeout.timeout(timeout) do
33
33
  file.flock(File::LOCK_EX)
34
34
  end
@@ -1,233 +1,83 @@
1
1
  module Dapp
2
2
  # Artifact from Git repo
3
3
  class GitArtifact
4
- # rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
5
- def initialize(builder, repo, where_to_add, name: nil, branch: 'master', cwd: nil, paths: nil, owner: nil, group: nil,
6
- interlayer_period: 7 * 24 * 3600, build_path: nil, flush_cache: false)
7
- @builder = builder
4
+ attr_reader :repo
5
+ attr_reader :name
6
+
7
+ # rubocop:disable Metrics/ParameterLists
8
+ def initialize(repo, where_to_add:, name: nil, branch: nil, commit: nil,
9
+ cwd: nil, paths: nil, owner: nil, group: nil)
8
10
  @repo = repo
9
11
  @name = name
10
12
 
11
13
  @where_to_add = where_to_add
12
- @branch = branch
14
+
15
+ @branch = branch || repo.application.cli_options[:git_artifact_branch] || repo.branch
16
+ @commit = commit
17
+
13
18
  @cwd = cwd
14
19
  @paths = paths
15
20
  @owner = owner
16
21
  @group = group
17
-
18
- @interlayer_period = interlayer_period
19
-
20
- @build_path = build_path || []
21
-
22
- @atomizer = Atomizer.new builder, build_path(filename('.atomizer'))
23
-
24
- # check params hash
25
- lock do
26
- cleanup! unless !flush_cache && File.exist?(paramshash_path) && File.read(paramshash_path) == paramshash
27
- File.write paramshash_path, paramshash
28
- end
29
- end
30
- # rubocop:enable Metrics/ParameterLists, Metrics/MethodLength
31
-
32
- def build_path(*paths)
33
- builder.build_path(*@build_path, *paths)
34
22
  end
23
+ # rubocop:enable Metrics/ParameterLists
35
24
 
36
- def add_multilayer!
37
- lock_with_repo do
38
- # create and add archive
39
- create_and_add_archive
40
- return if archive_commit == repo_latest_commit
25
+ def archive_apply_command(stage)
26
+ credentials = [:owner, :group].map { |attr| "--#{attr}=#{send(attr)}" unless send(attr).nil? }.compact
41
27
 
42
- # add layer patches
43
- latest_layer = add_layer_patches
44
- if latest_layer
45
- latest_layer_commit = layer_commit(latest_layer)
46
- return if latest_layer_commit == repo_latest_commit
47
- end
28
+ ["install #{credentials.join(' ')} -d #{where_to_add}",
29
+ ["git --git-dir=#{repo.container_build_dir_path} archive #{stage.layer_commit(self)}:#{cwd} #{paths}",
30
+ "#{sudo}tar -x -C #{where_to_add}"].join(' | ')]
31
+ end
48
32
 
49
- # empty changes
50
- unless any_changes?(latest_layer_commit || archive_commit)
51
- remove_latest!
52
- return
53
- end
33
+ def apply_patch_command(stage)
34
+ current_commit = stage.layer_commit(self)
35
+ prev_commit = stage.prev_source_stage.layer_commit(self)
54
36
 
55
- # create and add last patch
56
- create_and_add_last_patch(latest_layer, latest_layer_commit)
37
+ if prev_commit != current_commit || any_changes?(prev_commit, current_commit)
38
+ [["git --git-dir=#{repo.container_build_dir_path} #{diff_command(prev_commit, current_commit)}",
39
+ "#{sudo}git apply --whitespace=nowarn --directory=#{where_to_add} " \
40
+ '$(if [[ "$(git --version)" != "git version 1."* ]]; then echo "--unsafe-paths"; fi)'].join(' | ')] # FIXME
41
+ else
42
+ []
57
43
  end
58
44
  end
59
45
 
60
- def cleanup!
61
- lock do
62
- FileUtils.rm_f [
63
- paramshash_path,
64
- archive_path,
65
- archive_commitfile_path,
66
- Dir.glob(layer_patch_path('*')),
67
- Dir.glob(layer_commitfile_path('*')),
68
- latest_patch_path,
69
- latest_commitfile_path
70
- ].flatten
71
- end
46
+ def any_changes?(from, to = latest_commit)
47
+ !repo.git_bare(diff_command(from, to, quiet: true), returns: [0, 1]).status.success?
72
48
  end
73
49
 
74
- def exist_in_step?(path, step)
75
- repo.exist_in_commit?(path, commit_by_step(step))
50
+ def patch_size(from, to)
51
+ repo.git_bare("#{diff_command(from, to)} | wc -c").stdout.strip.to_i
76
52
  end
77
53
 
78
- def prepare_step_commit
79
- archive_commit
54
+ def latest_commit
55
+ @latest_commit ||= commit || repo.latest_commit(branch)
80
56
  end
81
57
 
82
- def build_step_commit
83
- layer_commit(layers.last) || archive_commit
58
+ def paramshash
59
+ Digest::SHA256.hexdigest [cwd, paths, owner, group].map(&:to_s).join(':::')
84
60
  end
85
61
 
86
- def setup_step_commit
87
- latest_commit || layer_commit(layers.last) || archive_commit
62
+ def paths(with_cwd = false)
63
+ [@paths].flatten.compact.map { |path| (with_cwd && cwd ? "#{cwd}/#{path}" : path).gsub(%r{^\/*|\/*$}, '') }.join(' ') if @paths
88
64
  end
89
65
 
90
- def commit_by_step(step)
91
- send :"#{step}_step_commit"
66
+ def filename(ending)
67
+ "#{repo.name}#{name ? "_#{name}" : nil}#{ending}"
92
68
  end
93
69
 
94
- def any_changes?(from)
95
- !repo.git_bare("diff --quiet #{from}..#{repo_latest_commit}#{" --relative=#{cwd}" if cwd} -- #{paths(true)}", returns: [0, 1]).status.success?
96
- end
70
+ protected
97
71
 
98
- attr_reader :repo
99
- attr_reader :name
100
72
  attr_reader :where_to_add
73
+ attr_reader :commit
101
74
  attr_reader :branch
102
75
  attr_reader :cwd
103
76
  attr_reader :owner
104
77
  attr_reader :group
105
- attr_reader :interlayer_period
106
-
107
- protected
108
-
109
- attr_reader :builder
110
- attr_reader :atomizer
111
-
112
- def lock_with_repo(&blk)
113
- lock do
114
- repo.lock(&blk)
115
- end
116
- end
117
-
118
- def create_and_add_archive
119
- create_archive! unless archive_exist?
120
- add_archive
121
- end
122
-
123
- def add_layer_patches
124
- latest_layer = nil
125
- layers.each do |layer|
126
- add_layer_patch layer
127
- latest_layer = layer
128
- end
129
-
130
- latest_layer
131
- end
132
-
133
- def create_and_add_last_patch_as_layer_patch(latest_layer, latest_layer_commit)
134
- remove_latest!
135
- layer = latest_layer.to_i + 1
136
- create_layer_patch!(latest_layer_commit || archive_commit, layer)
137
- add_layer_patch layer
138
- end
139
-
140
- def create_and_add_last_patch_as_latest_patch(_latest_layer, latest_layer_commit)
141
- if latest_commit != repo_latest_commit
142
- create_latest_patch!(latest_layer_commit || archive_commit)
143
- end
144
- add_latest_patch
145
- end
146
-
147
- def create_and_add_last_patch(latest_layer, latest_layer_commit)
148
- if (Time.now - repo.commit_at(latest_layer_commit || archive_commit)) > interlayer_period
149
- create_and_add_last_patch_as_layer_patch(latest_layer, latest_layer_commit)
150
- else
151
- create_and_add_last_patch_as_latest_patch(latest_layer, latest_layer_commit)
152
- end
153
- end
154
-
155
- def paths(with_cwd = false)
156
- [@paths].flatten.compact.map { |path| (with_cwd && cwd ? "#{cwd}/#{path}" : path).gsub(%r{^\/*|\/*$}, '') }.join(' ') if @paths
157
- end
158
-
159
- def repo_latest_commit
160
- repo.latest_commit(branch)
161
- end
162
-
163
- def filename(ending)
164
- "#{repo.name}#{name ? "_#{name}" : nil}.#{branch}#{ending}"
165
- end
166
-
167
- def paramshash_filename
168
- filename '.paramshash'
169
- end
170
-
171
- def paramshash_path
172
- build_path paramshash_filename
173
- end
174
-
175
- def paramshash
176
- Digest::SHA256.hexdigest [cwd, paths, owner, group].map(&:to_s).join(':::')
177
- end
178
-
179
- def archive_filename
180
- filename '.tar.gz'
181
- end
182
-
183
- def archive_path
184
- build_path archive_filename
185
- end
186
-
187
- def archive_commitfile_path
188
- build_path filename '.commit'
189
- end
190
-
191
- def archive_commit
192
- File.read archive_commitfile_path
193
- end
194
-
195
- def create_arhive_with_owner_substitution!
196
- Dir.mktmpdir('dapp_change_archive_owner') do |tmpdir_path|
197
- atomizer << tmpdir_path
198
- repo.git_bare "archive #{repo_latest_commit}:#{cwd} #{paths} | /bin/tar --extract --directory #{tmpdir_path}"
199
- builder.shellout("/usr/bin/find #{tmpdir_path} -maxdepth 1 -mindepth 1 -printf '%P\\n' | /bin/tar -czf #{archive_path} -C #{tmpdir_path}" \
200
- " -T - --owner=#{owner || 'root'} --group=#{group || 'root'}")
201
- end
202
- end
203
-
204
- def create_simple_archive!
205
- repo.git_bare "archive --format tar.gz #{repo_latest_commit}:#{cwd} -o #{archive_path} #{paths}"
206
- end
207
-
208
- def create_archive!
209
- atomizer << archive_path
210
- atomizer << archive_commitfile_path
211
-
212
- if owner || group
213
- create_arhive_with_owner_substitution!
214
- else
215
- create_simple_archive!
216
- end
217
-
218
- File.write archive_commitfile_path, repo_latest_commit
219
- end
220
-
221
- def archive_exist?
222
- File.exist? archive_commitfile_path
223
- end
224
-
225
- def add_archive
226
- builder.docker.add_artifact archive_path, archive_filename, where_to_add, step: :prepare
227
- end
228
78
 
229
79
  def sudo_format_user(user)
230
- user.to_i.to_s == user.to_s ? "\\##{user}" : user
80
+ user.to_s.to_i.to_s == user ? "\\\##{user}" : user
231
81
  end
232
82
 
233
83
  def sudo
@@ -242,87 +92,8 @@ module Dapp
242
92
  sudo
243
93
  end
244
94
 
245
- def add_patch(filename, step:)
246
- builder.docker.add_artifact(build_path(filename), filename, '/tmp', step: step)
247
-
248
- builder.docker.run(
249
- "zcat /tmp/#{filename} | #{sudo}git apply --whitespace=nowarn --directory=#{where_to_add}",
250
- "rm /tmp/#{filename}",
251
- step: step
252
- )
253
- end
254
-
255
- def create_patch!(from, filename, commitfile_path)
256
- atomizer << build_path(filename)
257
- atomizer << commitfile_path
258
-
259
- repo.git_bare "diff --binary #{from}..#{repo_latest_commit}#{" --relative=#{cwd}" if cwd} -- #{paths(true)} | gzip > #{build_path filename}"
260
- File.write commitfile_path, repo_latest_commit
261
- end
262
-
263
- def layer_filename(layer, ending)
264
- filename "_layer_#{layer.is_a?(Fixnum) ? format('%04d', layer) : layer}#{ending}"
265
- end
266
-
267
- def layer_patch_filename(layer)
268
- layer_filename(layer, '.patch.gz')
269
- end
270
-
271
- def layer_patch_path(layer)
272
- build_path layer_patch_filename(layer)
273
- end
274
-
275
- def layer_commitfile_path(layer)
276
- build_path layer_filename(layer, '.commit')
277
- end
278
-
279
- def layer_commit(layer)
280
- File.read layer_commitfile_path(layer) if File.exist? layer_commitfile_path(layer)
281
- end
282
-
283
- def layers
284
- Dir.glob(layer_commitfile_path('*')).map { |path| path.gsub(/.*_(\d+)\.commit$/, '\\1').to_i }.sort
285
- end
286
-
287
- def create_layer_patch!(from, layer)
288
- create_patch! from, layer_patch_filename(layer), layer_commitfile_path(layer)
289
- end
290
-
291
- def add_layer_patch(layer)
292
- add_patch layer_patch_filename(layer), step: :build
293
- end
294
-
295
- def latest_patch_filename
296
- filename '_latest.patch.gz'
297
- end
298
-
299
- def latest_patch_path
300
- build_path latest_patch_filename
301
- end
302
-
303
- def latest_commitfile_path
304
- build_path filename '_latest.commit'
305
- end
306
-
307
- def latest_commit
308
- File.read latest_commitfile_path if File.exist? latest_commitfile_path
309
- end
310
-
311
- def create_latest_patch!(from)
312
- create_patch! from, latest_patch_filename, latest_commitfile_path
313
- end
314
-
315
- def add_latest_patch
316
- add_patch latest_patch_filename, step: :setup
317
- end
318
-
319
- def remove_latest!
320
- FileUtils.rm_f [latest_patch_path, latest_commitfile_path]
321
- end
322
-
323
- def lock(**kwargs, &block)
324
- builder.filelock(build_path(filename('.lock')), error_message: "Branch #{branch} of artifact #{name ? " #{name}" : nil} #{repo.name}" \
325
- " (#{repo.dir_path}) in use! Try again later.", **kwargs, &block)
95
+ def diff_command(from, to, quiet: false)
96
+ "diff #{'--quiet' if quiet} #{from}..#{to} #{"--relative=#{cwd}" if cwd} -- #{paths(true)}"
326
97
  end
327
98
  end
328
99
  end