dapp 0.0.24 → 0.1.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.
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