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

Inherits:
Object
  • Object
show all
Defined in:
lib/appril-cli/docker/build.rb

Instance Method Summary collapse

Constructor Details

#initialize(dir, 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
# File 'lib/appril-cli/docker/build.rb', line 7

def initialize dir, update_runner_only: false, push_opted: false
  Dir.chdir dir do

    config = load_config
    validate_config(config)

    build_dir = Pathname.new(File.expand_path('__tmpbuildir__'))

    prepare_build_dir(build_dir)

    install_files(build_dir)

    app_dir = Pathname.new(File.expand_path(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(dir, image_name, build_opts) ⇒ Object



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

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

#container_definitions(container_name) ⇒ Object



138
139
140
141
142
# File 'lib/appril-cli/docker/build.rb', line 138

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

#install_build_files(dir) ⇒ Object



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

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

#install_cleanup_file(dir) ⇒ Object



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

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

#install_dockerfile(dir) ⇒ Object



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

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

#install_files(dir) ⇒ Object



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

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

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



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/appril-cli/docker/build.rb', line 121

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(dir) ⇒ Object



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

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

#load_configObject



40
41
42
# File 'lib/appril-cli/docker/build.rb', line 40

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

#prepare_build(dir, app_dir) ⇒ Object



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

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

#prepare_build_dir(dir) ⇒ Object



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

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

#push_image(image_name) ⇒ Object



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

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

#script_path_traversal(run_script) ⇒ Object



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

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

#validate_config(config) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/appril-cli/docker/build.rb', line 44

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])
    puts "", "\t::: Please set #{key} in config.yml :::", ""
    exit 1
  end
end

#validate_config__app_dir(value) ⇒ Object



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

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

#validate_config__container_name(value) ⇒ Object



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

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

#validate_config__image_name(value) ⇒ Object



57
58
59
# File 'lib/appril-cli/docker/build.rb', line 57

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

#validate_config__run_script(value) ⇒ Object



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

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