Class: Dapp::Dimg::Dimg

Inherits:
Object
  • Object
show all
Includes:
GitArtifact, Path, Stages, Tags, Helper::Sha256, Helper::Trivia
Defined in:
lib/dapp/dimg/dimg.rb,
lib/dapp/dimg/dimg/path.rb,
lib/dapp/dimg/dimg/tags.rb,
lib/dapp/dimg/dimg/stages.rb,
lib/dapp/dimg/dimg/git_artifact.rb

Direct Known Subclasses

Artifact

Defined Under Namespace

Modules: GitArtifact, Path, Stages, Tags

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helper::Trivia

class_to_lowercase, #class_to_lowercase, #delete_file, #kwargs, #make_path, #search_file_upward

Methods included from Helper::Sha256

#hashsum, #paths_content_hashsum, #sha256

Methods included from Stages

#all_images, #all_stages, #signature, #stage_by_name, #stage_cache_format, #stage_dapp_label, #tagged_images

Methods included from Path

#build_path, #container_dapp_path, #container_tmp_path, #home_path, #tmp_path

Methods included from GitArtifact

#git_artifacts, #local_git_artifacts, #remote_git_artifacts

Constructor Details

#initialize(config:, dapp:, should_be_built: false, ignore_git_fetch: false) ⇒ Dimg

Returns a new instance of Dimg.

Raises:



17
18
19
20
21
22
23
24
25
# File 'lib/dapp/dimg/dimg.rb', line 17

def initialize(config:, dapp:, should_be_built: false, ignore_git_fetch: false)
  @config = config
  @dapp = dapp

  @ignore_git_fetch = ignore_git_fetch
  @should_be_built = should_be_built

  raise Error::Dimg, code: :dimg_not_built if should_be_built?
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



12
13
14
# File 'lib/dapp/dimg/dimg.rb', line 12

def config
  @config
end

#dappObject (readonly)

Returns the value of attribute dapp.



15
16
17
# File 'lib/dapp/dimg/dimg.rb', line 15

def dapp
  @dapp
end

#ignore_git_fetchObject (readonly)

Returns the value of attribute ignore_git_fetch.



13
14
15
# File 'lib/dapp/dimg/dimg.rb', line 13

def ignore_git_fetch
  @ignore_git_fetch
end

#should_be_builtObject (readonly)

Returns the value of attribute should_be_built.



14
15
16
# File 'lib/dapp/dimg/dimg.rb', line 14

def should_be_built
  @should_be_built
end

Instance Method Details

#after_stages_build!Object



44
45
46
47
48
# File 'lib/dapp/dimg/dimg.rb', line 44

def after_stages_build!
  return unless last_stage.image.built? || dev_mode?
  last_stage.save_in_cache!
  artifacts.each { |artifact| artifact.last_stage.save_in_cache! }
end

#artifact?Boolean

Returns:

  • (Boolean)


143
144
145
# File 'lib/dapp/dimg/dimg.rb', line 143

def artifact?
  false
end

#artifactsObject



139
140
141
# File 'lib/dapp/dimg/dimg.rb', line 139

def artifacts
  @artifacts ||= artifacts_stages.map { |stage| stage.artifacts.map { |artifact| artifact[:dimg] } }.flatten
end

#build!Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/dapp/dimg/dimg.rb', line 27

def build!
  with_introspection do
    dapp.lock("#{dapp.name}.images", readonly: true) do
      last_stage.build_lock! do
        begin
          builder.before_build_check
          last_stage.build!
        ensure
          after_stages_build!
        end
      end
    end
  end
ensure
  cleanup_tmp
end

#build_cache_versionObject



155
156
157
# File 'lib/dapp/dimg/dimg.rb', line 155

def build_cache_version
  [::Dapp::BUILD_CACHE_VERSION, dev_mode? ? 1 : 0]
end

#builderObject



135
136
137
# File 'lib/dapp/dimg/dimg.rb', line 135

def builder
  @builder ||= Builder.const_get(config._builder.capitalize).new(self)
end

#cleanup_tmpObject



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/dapp/dimg/dimg.rb', line 164

def cleanup_tmp
  # В tmp-директории могли остаться файлы, владельцами которых мы не являемся.
  # Такие файлы могут попасть туда при экспорте файлов артефакта.
  # Чтобы от них избавиться — запускаем docker-контейнер под root-пользователем
  # и удаляем примонтированную tmp-директорию.
  cmd = "".tap do |cmd|
    cmd << "#{dapp.host_docker_bin} run --rm"
    cmd << " --volume #{dapp.tmp_base_dir}:#{dapp.tmp_base_dir}"
    cmd << " alpine:3.6"
    cmd << " rm -rf #{tmp_path}"
  end
  dapp.shellout! cmd

  artifacts.each(&:cleanup_tmp)
end

#dev_mode?Boolean

Returns:

  • (Boolean)


151
152
153
# File 'lib/dapp/dimg/dimg.rb', line 151

def dev_mode?
  dapp.dev_mode?
end

#export!(repo, format:) ⇒ Object



63
64
65
66
67
68
69
70
# File 'lib/dapp/dimg/dimg.rb', line 63

def export!(repo, format:)
  dapp.lock("#{dapp.name}.images", readonly: true) do
    tags.each do |tag|
      image_name = format(format, repo: repo, dimg_name: config._name, tag: tag)
      export_base!(last_stage.image, image_name)
    end
  end
end

#export_base!(image, image_name) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/dapp/dimg/dimg.rb', line 81

def export_base!(image, image_name)
  if dapp.dry_run?
    dapp.log_state(image_name, state: dapp.t(code: 'state.push'), styles: { status: :success })
  else
    dapp.lock("image.#{hashsum image_name}") do
      ::Dapp::Dimg::Image::Stage.cache_reset(image_name)
      dapp.log_process(image_name, process: dapp.t(code: 'status.process.pushing')) do
        image.export!(image_name)
      end
    end
  end
end

#export_stages!(repo, format:) ⇒ Object



72
73
74
75
76
77
78
79
# File 'lib/dapp/dimg/dimg.rb', line 72

def export_stages!(repo, format:)
  dapp.lock("#{dapp.name}.images", readonly: true) do
    export_images.each do |image|
      image_name = format(format, repo: repo, signature: image.name.split(':').last)
      export_base!(image, image_name)
    end
  end
end

#import_base!(image, image_name) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/dapp/dimg/dimg.rb', line 108

def import_base!(image, image_name)
  if dapp.dry_run?
    dapp.log_state(image_name, state: dapp.t(code: 'state.pull'), styles: { status: :success })
  else
    dapp.lock("image.#{hashsum image_name}") do
      dapp.log_process(image_name, process: dapp.t(code: 'status.process.pulling'),
                                   status: { failed: dapp.t(code: 'status.failed.not_pulled') },
                                   style: { failed: :secondary }) do
        image.import!(image_name)
      end
    end
  end
end

#import_stages!(repo, format:) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/dapp/dimg/dimg.rb', line 94

def import_stages!(repo, format:)
  dapp.lock("#{dapp.name}.images", readonly: true) do
    import_images.each do |image|
      begin
        image_name = format(format, repo: repo, signature: image.name.split(':').last)
        import_base!(image, image_name)
      rescue ::Dapp::Error::Shellout
        next
      end
      break unless dapp.pull_all_stages?
    end
  end
end

#introspect_image!(image:, options:) ⇒ Object



159
160
161
162
# File 'lib/dapp/dimg/dimg.rb', line 159

def introspect_image!(image:, options:)
  cmd = "#{dapp.host_docker_bin} run -ti --rm --entrypoint #{dapp.bash_bin} #{options} #{image}"
  system(cmd)
end

#run(docker_options, command) ⇒ Object



122
123
124
125
126
127
128
129
# File 'lib/dapp/dimg/dimg.rb', line 122

def run(docker_options, command)
  cmd = "#{dapp.host_docker_bin} run #{[docker_options, last_stage.image.built_id, command].flatten.compact.join(' ')}"
  if dapp.dry_run?
    dapp.log(cmd)
  else
    system(cmd) || raise(Error::Dimg, code: :dimg_not_run)
  end
end

#scratch?Boolean

Returns:

  • (Boolean)


147
148
149
# File 'lib/dapp/dimg/dimg.rb', line 147

def scratch?
  config._docker._from.nil?
end

#stage_image_name(stage_name) ⇒ Object



131
132
133
# File 'lib/dapp/dimg/dimg.rb', line 131

def stage_image_name(stage_name)
  stages.find { |stage| stage.name == stage_name }.image.name
end

#stage_should_be_introspected?(name) ⇒ Boolean

Returns:

  • (Boolean)


180
181
182
# File 'lib/dapp/dimg/dimg.rb', line 180

def stage_should_be_introspected?(name)
  dapp.options[:introspect_stage] == name
end

#tag!(tag) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/dapp/dimg/dimg.rb', line 50

def tag!(tag)
  dapp.lock("#{dapp.name}.images", readonly: true) do
    dimg_name = config._name
    if dapp.dry_run?
      dapp.log_state(dimg_name, state: dapp.t(code: 'state.tag'), styles: { status: :success })
    else
      dapp.log_process(dimg_name, process: dapp.t(code: 'status.process.tagging')) do
        last_stage.image.tag!(tag)
      end
    end
  end
end