dapp 0.0.24 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/bin/dapp +17 -1
- data/config/en/common.yml +23 -0
- data/config/en/net_status.yml +24 -0
- data/lib/dapp.rb +68 -12
- data/lib/dapp/application.rb +57 -0
- data/lib/dapp/application/git_artifact.rb +26 -0
- data/lib/dapp/application/logging.rb +120 -0
- data/lib/dapp/application/path.rb +31 -0
- data/lib/dapp/application/tags.rb +65 -0
- data/lib/dapp/build/stage/app_install.rb +19 -0
- data/lib/dapp/build/stage/app_setup.rb +19 -0
- data/lib/dapp/build/stage/base.rb +106 -0
- data/lib/dapp/build/stage/from.rb +40 -0
- data/lib/dapp/build/stage/infra_install.rb +23 -0
- data/lib/dapp/build/stage/infra_setup.rb +19 -0
- data/lib/dapp/build/stage/source_1.rb +31 -0
- data/lib/dapp/build/stage/source_1_archive.rb +31 -0
- data/lib/dapp/build/stage/source_2.rb +20 -0
- data/lib/dapp/build/stage/source_3.rb +27 -0
- data/lib/dapp/build/stage/source_4.rb +31 -0
- data/lib/dapp/build/stage/source_5.rb +51 -0
- data/lib/dapp/build/stage/source_base.rb +109 -0
- data/lib/dapp/builder/base.rb +44 -0
- data/lib/dapp/builder/chef.rb +242 -0
- data/lib/dapp/builder/chef/berksfile.rb +54 -0
- data/lib/dapp/builder/shell.rb +16 -0
- data/lib/dapp/cli.rb +10 -44
- data/lib/dapp/cli/base.rb +55 -0
- data/lib/dapp/cli/build.rb +6 -140
- data/lib/dapp/cli/flush.rb +19 -0
- data/lib/dapp/cli/flush/build_cache.rb +26 -0
- data/lib/dapp/cli/flush/stage_cache.rb +23 -0
- data/lib/dapp/cli/list.rb +19 -0
- data/lib/dapp/cli/push.rb +59 -0
- data/lib/dapp/cli/smartpush.rb +19 -0
- data/lib/dapp/config/application.rb +98 -0
- data/lib/dapp/config/chef.rb +20 -0
- data/lib/dapp/config/docker.rb +39 -0
- data/lib/dapp/config/git_artifact.rb +78 -0
- data/lib/dapp/config/main.rb +23 -0
- data/lib/dapp/config/shell.rb +40 -0
- data/lib/dapp/controller.rb +103 -0
- data/lib/dapp/docker_image.rb +51 -0
- data/lib/dapp/error/application.rb +6 -0
- data/lib/dapp/error/base.rb +10 -0
- data/lib/dapp/error/build.rb +6 -0
- data/lib/dapp/error/config.rb +6 -0
- data/lib/dapp/error/controller.rb +6 -0
- data/lib/dapp/error/shellout.rb +6 -0
- data/lib/dapp/filelock.rb +1 -1
- data/lib/dapp/git_artifact.rb +43 -272
- data/lib/dapp/git_repo/base.rb +10 -12
- data/lib/dapp/git_repo/own.rb +7 -3
- data/lib/dapp/git_repo/remote.rb +14 -20
- data/lib/dapp/helper/cli.rb +66 -0
- data/lib/dapp/helper/i18n.rb +20 -0
- data/lib/dapp/helper/log.rb +72 -0
- data/lib/dapp/helper/paint.rb +27 -0
- data/lib/dapp/helper/sha256.rb +14 -0
- data/lib/dapp/helper/shellout.rb +41 -0
- data/lib/dapp/helper/streaming.rb +49 -0
- data/lib/dapp/helper/trivia.rb +27 -0
- data/lib/dapp/stage_image.rb +98 -0
- data/lib/dapp/version.rb +3 -1
- metadata +207 -51
- data/lib/dapp/atomizer.rb +0 -56
- data/lib/dapp/builder.rb +0 -230
- data/lib/dapp/builder/cascade_tagging.rb +0 -48
- data/lib/dapp/builder/centos7.rb +0 -47
- data/lib/dapp/builder/chefify.rb +0 -107
- data/lib/dapp/builder/ci_tagging.rb +0 -53
- data/lib/dapp/builder/git_tagging.rb +0 -21
- data/lib/dapp/builder/manual_tagging.rb +0 -22
- data/lib/dapp/builder/ubuntu1404.rb +0 -20
- data/lib/dapp/builder/ubuntu1604.rb +0 -20
- data/lib/dapp/docker.rb +0 -207
- 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
|
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,
|
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
|
data/lib/dapp/git_artifact.rb
CHANGED
@@ -1,233 +1,83 @@
|
|
1
1
|
module Dapp
|
2
2
|
# Artifact from Git repo
|
3
3
|
class GitArtifact
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
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
|
37
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
56
|
-
|
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
|
61
|
-
|
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
|
75
|
-
repo.
|
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
|
79
|
-
|
54
|
+
def latest_commit
|
55
|
+
@latest_commit ||= commit || repo.latest_commit(branch)
|
80
56
|
end
|
81
57
|
|
82
|
-
def
|
83
|
-
|
58
|
+
def paramshash
|
59
|
+
Digest::SHA256.hexdigest [cwd, paths, owner, group].map(&:to_s).join(':::')
|
84
60
|
end
|
85
61
|
|
86
|
-
def
|
87
|
-
|
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
|
91
|
-
|
66
|
+
def filename(ending)
|
67
|
+
"#{repo.name}#{name ? "_#{name}" : nil}#{ending}"
|
92
68
|
end
|
93
69
|
|
94
|
-
|
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
|
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
|
246
|
-
|
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
|