Class: Appril::CLI::Docker::Build

Inherits:
Appril::CLI::Docker show all
Defined in:
lib/appril-cli/docker/build.rb

Constant Summary

Constants inherited from Appril::CLI::Docker

BUILD_FILE, CLEANUP_FILE, CONFIG_FILE, PREPARE_BUILD_FILE, START_FILE

Instance Method Summary collapse

Methods inherited from Appril::CLI::Docker

#paths

Methods included from Assertions

#assert_config_file_exists, #assert_directory_does_not_exists, #assert_directory_exists, #assert_empty_directory, #assert_installable_path, #assert_is_app_dir

Methods included from Helpers

#create_dirname_for, #expanded_path, #extract_namespace, #fatal_error!, #format_error, #make_executable

Constructor Details

#initialize(path, update_runner_only: false, push_opted: false) ⇒ Build

Returns a new instance of Build.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/appril-cli/docker/build.rb', line 7

def initialize path, update_runner_only: false, push_opted: false
  src, dst = paths(path)

  assert_directory_exists(dst)
  assert_config_file_exists(dst)

  Dir.chdir dst do

    config = load_config()
    validate_config(config)

    build_dir = dst / '__tmpbuildir__'

    prepare_build_dir(build_dir)

    install_files(build_dir)

    app_dir = dst / config['APP_DIR']

    if update_runner_only
      puts "Skipping image building"
    else
      prepare_build(build_dir, app_dir)

      image_built = build_image(build_dir, config['IMAGE_NAME'], config['BUILD_OPTS'])

      if image_built && push_opted
        push_image(config['IMAGE_NAME'])
      end
    end

    puts "Installing run script"
    install_run_script(app_dir, *config.values_at('IMAGE_NAME', 'CONTAINER_NAME', 'RUN_SCRIPT', 'RUN_OPTS'))

    FileUtils.rm_rf(build_dir)
  end
end

Instance Method Details

#build_image(path, image_name, build_opts) ⇒ Object



115
116
117
118
# File 'lib/appril-cli/docker/build.rb', line 115

def build_image path, image_name, build_opts
  CLI.run "docker build -t #{image_name} #{build_opts} '#{path}'"
  $? && $?.success?
end

#container_definitions(container_name) ⇒ Object



142
143
144
145
146
# File 'lib/appril-cli/docker/build.rb', line 142

def container_definitions container_name
  container_name.map do |kv|
    '[ "$APP_ENV" = "%s" ] && CONTAINER_NAME="%s"' % kv
  end.join("\n")
end

#install_build_files(path) ⇒ Object



99
100
101
102
# File 'lib/appril-cli/docker/build.rb', line 99

def install_build_files path
  FileUtils.cp(PREPARE_BUILD_FILE, path / 'build')
  FileUtils.cp(BUILD_FILE, path / 'build/build')
end

#install_cleanup_file(path) ⇒ Object



104
105
106
# File 'lib/appril-cli/docker/build.rb', line 104

def install_cleanup_file path
  FileUtils.cp(CLEANUP_FILE, path / 'build/cleanup')
end

#install_dockerfile(path) ⇒ Object



89
90
91
# File 'lib/appril-cli/docker/build.rb', line 89

def install_dockerfile path
  FileUtils.cp(DOCKER_DIR / 'Dockerfile', path)
end

#install_files(path) ⇒ Object



82
83
84
85
86
87
# File 'lib/appril-cli/docker/build.rb', line 82

def install_files path
  install_dockerfile(path)
  install_start_file(path)
  install_build_files(path)
  install_cleanup_file(path)
end

#install_run_script(app_dir, image_name, container_name, run_script, run_opts) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/appril-cli/docker/build.rb', line 125

def install_run_script app_dir, image_name, container_name, run_script, run_opts
  FileUtils.mkdir_p(app_dir / File.dirname(run_script))

  script_path = app_dir / run_script

  File.open script_path, 'w' do |f|
    f << File.read(DOCKER_DIR / 'run').
      gsub('{image}', image_name).
      gsub('{script_path_traversal}', script_path_traversal(run_script)).
      gsub('{run_opts}', run_opts).
      gsub('{environments}', container_name.keys.join(' ')).
      gsub('{container_definitions}', container_definitions(container_name))
  end

  FileUtils.chmod('+x', script_path)
end

#install_start_file(path) ⇒ Object



93
94
95
96
97
# File 'lib/appril-cli/docker/build.rb', line 93

def install_start_file path
  File.open path / 'start', 'w' do |f|
    f << File.read(DOCKER_DIR / 'start').sub('{start}', File.read(START_FILE))
  end
end

#load_configObject



45
46
47
# File 'lib/appril-cli/docker/build.rb', line 45

def load_config
  YAML.load(File.read(CONFIG_FILE))
end

#prepare_build(path, app_dir) ⇒ Object



108
109
110
111
112
113
# File 'lib/appril-cli/docker/build.rb', line 108

def prepare_build path, app_dir
  Dir.chdir path / 'build' do
    CLI.run "APP_DIR=#{app_dir} #{PREPARE_BUILD_FILE}"
    exit 1 unless $? && $?.success?
  end
end

#prepare_build_dir(path) ⇒ Object



77
78
79
80
# File 'lib/appril-cli/docker/build.rb', line 77

def prepare_build_dir path
  FileUtils.rm_rf(path)
  FileUtils.mkdir_p(path / 'build')
end

#push_image(image_name) ⇒ Object



120
121
122
123
# File 'lib/appril-cli/docker/build.rb', line 120

def push_image image_name
  CLI.run "docker push #{image_name}"
  $? && $?.success?
end

#script_path_traversal(run_script) ⇒ Object



148
149
150
# File 'lib/appril-cli/docker/build.rb', line 148

def script_path_traversal run_script
  run_script.gsub(/\A\/+|\/+\Z/, '').scan(/\/+/).map {'..'}*'/'
end

#validate_config(config) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/appril-cli/docker/build.rb', line 49

def validate_config config
  {
    'IMAGE_NAME' => :validate_config__image_name,
    'CONTAINER_NAME' => :validate_config__container_name,
    'APP_DIR' => :validate_config__app_dir,
    'RUN_SCRIPT' => :validate_config__run_script,
  }.each_pair do |key,validator|
    next if send(validator, config[key])
    fatal_error!("Please set #{key} in config.yml")
  end
end

#validate_config__app_dir(value) ⇒ Object



69
70
71
# File 'lib/appril-cli/docker/build.rb', line 69

def validate_config__app_dir value
  !value.nil? && !value.empty?
end

#validate_config__container_name(value) ⇒ Object



65
66
67
# File 'lib/appril-cli/docker/build.rb', line 65

def validate_config__container_name value
  !value.nil? && !value.empty? && value.values.any?
end

#validate_config__image_name(value) ⇒ Object



61
62
63
# File 'lib/appril-cli/docker/build.rb', line 61

def validate_config__image_name value
  !value.nil? && !value.empty?
end

#validate_config__run_script(value) ⇒ Object



73
74
75
# File 'lib/appril-cli/docker/build.rb', line 73

def validate_config__run_script value
  !value.nil? && !value.empty?
end