Calculate layers to keep only when necessary
[discourse_docker.git] / image / build.rb
index 44a9fb6d1c33981567718f819d29342a4074997b..2860293f60dca4b812709698eadace99530154c6 100644 (file)
@@ -1,19 +1,7 @@
 # simple build file to be used locally by Sam
 #
 require 'pty'
-
-$version = "1.3.6"
-
-$docker_squash = "https://github.com/jwilder/docker-squash/releases/download/v0.2.0/docker-squash-linux-amd64-v0.2.0.tar.gz"
-
-$base_image = "discourse/base:#{$version}"
-$image = "discourse/discourse:#{$version}"
-$test = "discourse/discourse_test:#{$version}"
-
-if ENV["USER"] != "root"
-  STDERR.puts "Build script must be ran as root due to docker-squash"
-  exit 1
-end
+require 'optparse'
 
 def run(command)
   lines = []
@@ -32,23 +20,71 @@ def run(command)
 end
 
 def ensure_docker_squash
-  return if File.exist?("docker-squash")
-  run ("wget #{$docker_squash}")
-  run ("tar -xzvf *.tar.gz")
-  run ("rm -f docker-squash-linux*")
+  docker_squash = "https://github.com/goldmann/docker-squash/archive/master.zip"
+  run ("pip install --user #{$docker_squash} --upgrade")
 end
 
-ensure_docker_squash
 
-def build(path, tag, is_base)
-  lines = run("cd #{path} && docker build .")
+def build(image, version)
+  lines = run("cd #{image[:name]} && docker build --build-arg version=#{version} .")
   img = lines[-1]["successfully built ".length..-1].strip
 
-  run("docker save #{img} | ./docker-squash -t #{tag} -verbose #{is_base && "-from root"} | docker load")
+  if image[:squash]
+
+    layers_to_squash = run("docker history #{img} | wc -l").first.to_i - (1 + image[:layers_to_keep]) if image[:layers_to_keep] != nil
+
+    if layers_to_keep != nil
+      run("docker-squash -t #{image[:tag]} --verbose -f #{layers_to_squash} #{img}")
+    else
+      run("docker-squash -t #{image[:tag]} --verbose #{img}")
+    end
+
+  else
+    run("docker tag #{img} #{image[:tag]}")
+  end
 end
 
-run "(cd base && ./download_phantomjs)"
+def bump(image, image_version)
+  run("sed -i '' -e 's/^\(# NAME:\).*$$/\1     discourse\/#{image_dir}/' #{image_dir}/Dockerfile")
+  run("sed -i '' -e 's/^\(# VERSION:\).*$$/\1  #{image_version}/' #{image_dir}/Dockerfile")
+  run("sed -i '' -e 's/^\(FROM discourse\/[^:]*:\).*/\1#{image_version}/' #{image_dir}/Dockerfile")
+end
 
-build("base",$base_image,true)
-build("discourse",$image,false)
-build("discourse_test",$test,false)
+options = {}
+OptionParser.new do |parser|
+  parser.on("-i", "--image image",
+            "Build the image. No parameter means [base discourse discourse_test].") do |i|
+    options[:image] = [i]
+  end
+  parser.on("-b", "--bump version",
+            "Bumps the version in the Dockerfiles specified by --image") do |v|
+    options[:version] = [v]
+  end
+end.parse!
+
+DEFAULT_IMAGES = %i[base discourse discourse_test discourse_dev discourse_bench]
+
+todo = options[:image] || DEFAULT_IMAGES
+version = options[:version] || '1.3.7'
+
+if ENV["USER"] != "root"
+  STDERR.puts "Build script must be ran as root due to docker-squash"
+  exit 1
+end
+
+ensure_docker_squash
+
+images = {
+  base: { name: 'base', tag: "discourse/base:#{version}", squash: true },
+  discourse: { name: 'discourse', tag: "discourse/discourse:#{version}", squash: true, layers_to_keep: 1 },
+  discourse_test: { name: 'discourse_test', tag: "discourse/discourse_test:#{version}", squash: true, layers_to_keep: 2 },
+  discourse_dev: { name: 'discourse_dev', tag: "discourse/discourse_dev:#{version}", squash: false },
+  discourse_bench: { name: 'discourse_bench', tag: "discourse/discourse_bench:#{version}", squash: false }
+}
+
+todo.each do |image|
+  puts images[image]
+  bump(images[image][:name], options[:version]) if options[:version]
+  run "(cd base && ./download_phantomjs)" if image == 'base'  
+  build(images[image], version)
+end