Module: MiriamTech::GoCD::DSL

Defined in:
lib/miriamtech/gocd/paths.rb,
lib/miriamtech/gocd/tasks.rb,
lib/miriamtech/gocd/docker.rb,
lib/miriamtech/gocd/images.rb,
lib/miriamtech/gocd/lambda.rb,
lib/miriamtech/gocd/artifacts.rb

Constant Summary collapse

WORKER_IMAGE =
'debian:buster'.freeze

Instance Method Summary collapse

Instance Method Details

#build_counter(env = ENV) ⇒ Object



24
25
26
# File 'lib/miriamtech/gocd/docker.rb', line 24

def build_counter(env = ENV)
  @build_counter ||= generate_build_counter(env)
end

#build_tag(env = ENV) ⇒ Object



20
21
22
# File 'lib/miriamtech/gocd/docker.rb', line 20

def build_tag(env = ENV)
  @build_tag ||= generate_build_tag(env)
end

#capture_artifacts(prefix = project_name, workdir:, path:) ⇒ Object



6
7
8
9
10
11
12
# File 'lib/miriamtech/gocd/artifacts.rb', line 6

def capture_artifacts(prefix = project_name, workdir:, path:)
  with_artifacts_volume(prefix) do |volume_name|
      yield "-v #{volume_name}:#{workdir}/#{path}"
  ensure
    copy_artifacts_from_volume(volume_name, local_path: path)
  end
end

#cleanup_old_images(image_name, number_to_keep) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/miriamtech/gocd/images.rb', line 19

def cleanup_old_images(image_name, number_to_keep)
  images = `docker images --format '"{{.CreatedAt}}" id:{{.ID}}' #{image_name} | sort -r`.split("\n")
  images.collect { |each| each.split(':').last }.uniq.each_with_index do |image, index|
    next if index <= number_to_keep
    docker "image rm --force #{image}"
  end
end

#compose_fileObject



17
18
19
# File 'lib/miriamtech/gocd/paths.rb', line 17

def compose_file
  root_path / 'docker-compose.yml'
end

#copy_artifacts_from_volume(volume, local_path:) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/miriamtech/gocd/artifacts.rb', line 22

def copy_artifacts_from_volume(volume, local_path:)
  container_id = `docker create -v #{volume}:/artifacts #{WORKER_IMAGE} cp -a /artifacts /artifacts_tmp`.chomp
  begin
    docker "start -i #{container_id}"
    cd root_path do
      sh "docker cp #{container_id}:/artifacts_tmp/. #{local_path}"
    end
  ensure
    docker "rm -v #{container_id}"
  end
end

#define_gocd_tasks(image_name, revisions_to_keep: 10, build_args: {}) ⇒ Object

rubocop:disable Style/HashSyntax, Style/SymbolArray, Metrics/MethodLength



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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/miriamtech/gocd/tasks.rb', line 9

def define_gocd_tasks(
  image_name,
  revisions_to_keep: 10,
  build_args: {}
)

  task :default => [:test]
  task :full => [:destroy_containers, :build]

  task :environment do
    ENV['BUILD_TAG'] = build_tag
  end

  CLEAN.add("#{root_path}/test/reports")
  task :stop_containers => [:environment]
  task :destroy_containers => [:environment, :clean, :cleanup_old_images]

  # These are here for compatibility
  task :clean => :stop_containers
  task :clobber => :destroy_containers

  if compose_file.exist?
    task :stop_containers => [:environment] do
      docker_compose 'stop'
    end

    task :destroy_containers => [:stop_containers] do
      docker_compose 'rm -fv'
    end
  end

  task :cleanup_old_images do
    cleanup_old_images(image_name, revisions_to_keep)
  end

  task :build => :environment do
    docker "build #{docker_build_arguments(build_args: build_args).join(' ')} -t #{image_name}#{build_tag} -t #{image_name}#{build_counter} #{root_path}"
  end

  task :test => [:environment, :destroy_containers] do
    at_exit { Rake::Task[:destroy_containers].execute }
  end

  task :save, [:path] => :environment do | t, args |
    args.with_defaults(path: File.join(root_path, '.docker', 'image.tar'))
    FileUtils.mkdir_p File.dirname(args[:path])
    docker "save #{image_name}#{build_tag} -o #{args[:path]}"
  end

  task :load, :path do | t, args |
    args.with_defaults(path: File.join(root_path, '.docker', 'image.tar'))
    docker "load -i #{args[:path]}"
  end

  task :push do
    push(image_name)
    push(image_name, 'latest')
  end

  task :deploy do
    pull(image_name)
    push(image_name, 'deployed')
  end

  task :bash do
    docker("run -it --rm #{image_name} bash")
  end
end

#docker(string) ⇒ Object



28
29
30
# File 'lib/miriamtech/gocd/docker.rb', line 28

def docker(string)
  sh "docker #{string}"
end

#docker_build_arguments(env = ENV, build_args: {}) ⇒ Object



32
33
34
35
36
37
38
39
40
# File 'lib/miriamtech/gocd/docker.rb', line 32

def docker_build_arguments(env = ENV, build_args: {})
  args = ['--force-rm']
  no_cache_arg = env['DOCKER_BUILD_NO_CACHE']
  args << '--no-cache' if no_cache_arg && !FALSY_ENV_VALUES.include?(no_cache_arg)
  build_args.each do |key, value|
    args << "--build-arg #{key}=#{value}"
  end
  args
end

#docker_compose(string) ⇒ Object



42
43
44
45
46
# File 'lib/miriamtech/gocd/docker.rb', line 42

def docker_compose(string)
  cd root_path do
    sh "docker-compose -p #{project_name} -f docker-compose.yml #{string}"
  end
end

#invoke_lambda(lambda) ⇒ Object



6
7
8
9
10
11
# File 'lib/miriamtech/gocd/lambda.rb', line 6

def invoke_lambda(lambda)
  Tempfile.open(lambda) do |temp|
    sh "aws lambda invoke --function-name #{lambda} #{temp.path}"
    puts temp.read
  end
end

#project_name(env = ENV) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/miriamtech/gocd/docker.rb', line 5

def project_name(env = ENV)
  pipeline_name = env['GO_PIPELINE_NAME']
  stage_name = env['GO_STAGE_NAME']
  job_name = env['GO_JOB_NAME']
  name = root_path.basename.to_s

  if pipeline_name
    name = pipeline_name
    name += "-#{stage_name}" if stage_name
    name += "-#{job_name}" if job_name
  end

  name.downcase
end

#pull(image_name) ⇒ Object



6
7
8
# File 'lib/miriamtech/gocd/images.rb', line 6

def pull(image_name)
  docker "pull #{image_name}#{build_tag}"
end

#push(image_name, tag = nil) ⇒ Object



10
11
12
13
14
15
16
17
# File 'lib/miriamtech/gocd/images.rb', line 10

def push(image_name, tag = nil)
  if tag
    docker "tag #{image_name}#{build_tag} #{image_name}:#{tag}"
    docker "push #{image_name}:#{tag}"
  else
    docker "push #{image_name}#{build_tag}"
  end
end

#root_pathObject



6
7
8
9
10
11
12
13
14
15
# File 'lib/miriamtech/gocd/paths.rb', line 6

def root_path
  cwd = Pathname.new(File.expand_path('.'))
  path = Pathname.new(cwd)
  loop do
    break if path.root?
    return path if path.join('Dockerfile').exist?
    path = path.parent
  end
  cwd
end

#with_artifacts_volume(prefix = project_name) ⇒ Object



14
15
16
17
18
19
20
# File 'lib/miriamtech/gocd/artifacts.rb', line 14

def with_artifacts_volume(prefix = project_name)
  artifacts_volume = sanitized_volume_name("#{prefix}_#{random_hex}")
  docker "volume create #{artifacts_volume}"
  yield artifacts_volume
ensure
  docker "volume rm #{artifacts_volume}"
end