picsolve_docker_builder 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de22e1ddc1a2ea198d0c73b3d7666ff4478e1ebd
4
- data.tar.gz: 5081529443f27fc76d6cae03744a88b064129857
3
+ metadata.gz: ff6dc295b2b3965dc57e04b6939e98c6e39028f6
4
+ data.tar.gz: fa1feef27218916f7c8ea253b43495645089c0fc
5
5
  SHA512:
6
- metadata.gz: b8f4cc5d83cd5677610d743262e9a4751e8165a06d76af80c73b8932eb1ffc87f00a4cb46ad25f84ae18dc780f8b99c2e870776f0530dfc930fa44b6fc06aeee
7
- data.tar.gz: fbfa2a3eae645fea2af45289fa5e174817a4f157fac45de0cfd294d2e139a8b0207adac0e8a96383538960ac59767300762c087cc0d7eb09bd3c1ddd13967966
6
+ metadata.gz: 610fb9fd6451749f7c11aaf818ca6a39d578617a45a65e915e25d69266d3c40f2114d76df9e76387283478d5650c63c086c6e1b8488c8fa8439108b9c028e265
7
+ data.tar.gz: 731f2eeafe0e07ca9bc4cae992eda2022a3c9a9add0b499321f1f874c25e14fd6f796e5a269bc040d44799e86450f99742a831293a153db3de84049016b4395e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Change Log
2
2
 
3
+ ## [0.5.1] - 2016-03-07
4
+ ### Added
5
+ - Support for storing/updateing tag information within config file
6
+ - Support for multiple config files .docker-builder.*.yml
7
+
8
+ ### Fixes
9
+ - Fixes regressions with v2 registry
10
+
11
+ ## [0.5.0] - 2016-02-03
12
+ ### Added
13
+ - Support v2 registry
14
+
3
15
  ## [0.4.0] - 2016-01-11
4
16
  ### Added
5
17
  - Scala library build support
@@ -47,6 +47,13 @@ module PicsolveDockerBuilder
47
47
  File.join(base_dir, config_file)
48
48
  end
49
49
 
50
+ # This should replace config_path pretty soon
51
+ def config_paths
52
+ [config_path] + Dir.glob(
53
+ config_path[0, config_path.length - 3] + '*.yml'
54
+ )
55
+ end
56
+
50
57
  def default_config
51
58
  {}
52
59
  end
@@ -84,9 +84,9 @@ module PicsolveDockerBuilder
84
84
  return i
85
85
  end
86
86
 
87
- # new approach
87
+ # new approach to handle config
88
88
  c = PicsolveDockerBuilder::Helpers::ConfigManager.new(
89
- config_path,
89
+ config_paths,
90
90
  stage
91
91
  )
92
92
  c.containers(self)
@@ -2,8 +2,6 @@ require 'picsolve_docker_builder/base'
2
2
  require 'picsolve_docker_builder/helpers/registry'
3
3
  require 'picsolve_docker_builder/composer/requirements'
4
4
 
5
- Registry = PicsolveDockerBuilder::Helpers::Registry
6
-
7
5
  module PicsolveDockerBuilder
8
6
  module Composer
9
7
  # Represents an container in an namespace
@@ -17,10 +15,6 @@ module PicsolveDockerBuilder
17
15
  @composer = composer
18
16
  end
19
17
 
20
- def repo_tag
21
- config['image']
22
- end
23
-
24
18
  def rc(kubernetes)
25
19
  @rcs = {} if @rcs.nil?
26
20
  @rcs[kubernetes] = kubernetes.rc(self) \
@@ -117,16 +111,24 @@ module PicsolveDockerBuilder
117
111
  }
118
112
  end
119
113
 
120
- def repo_tag_hash_unique
121
- @repo_tag_hash_unique ||= Registry.repo_tag_unique(config['image'])
114
+ def image_name_tag
115
+ "#{config['image']}:#{repo_tag}"
122
116
  end
123
117
 
124
- def repo_tag_unique
125
- repo_tag_hash_unique[:tag_unique]
118
+ def repo_tag
119
+ return config['tag'] if config.key? 'tag'
120
+ repo_tag_unique
126
121
  end
127
122
 
128
- def hash
129
- repo_tag_hash_unique[:hash]
123
+ def repo_tag_unique(label = 'latest')
124
+ image = PicsolveDockerBuilder::Helpers::Repository.new config['image']
125
+ log.info "Parse image string: #{image}"
126
+ @registry ||= PicsolveDockerBuilder::Helpers::Registry.new(
127
+ "https://#{image.registry}"
128
+ )
129
+ tag = @registry.unique_tag(config['image'], label)
130
+ log.info "Evaluate unique tag '#{tag}' for '#{label}'"
131
+ tag
130
132
  end
131
133
  end
132
134
  end
@@ -5,8 +5,6 @@ require 'docker'
5
5
  require 'logger'
6
6
  require 'psych'
7
7
 
8
- Registry = PicsolveDockerBuilder::Helpers::Registry
9
-
10
8
  module PicsolveDockerBuilder
11
9
  # Docker image building template
12
10
  # rubocop:disable Metrics/ClassLength
@@ -107,7 +105,7 @@ module PicsolveDockerBuilder
107
105
  repotag = "#{dest_image_name}:#{tag}"
108
106
  log.info "pushing image with #{repotag}"
109
107
  @docker_build.push(
110
- Registry.creds,
108
+ PicsolveDockerBuilder::Helpers::Registry.creds,
111
109
  tag: tag
112
110
  ) do |resp|
113
111
  resp = JSON.parse resp
@@ -380,7 +378,7 @@ module PicsolveDockerBuilder
380
378
  log.debug "pulling image '#{image_name}' from registry"
381
379
  Docker::Image.create(
382
380
  { 'fromImage' => image_name },
383
- Registry.creds
381
+ PicsolveDockerBuilder::Helpers::Registry.creds
384
382
  )
385
383
  log.debug "building asset image from '#{image_name}'"
386
384
  asset_image_build
@@ -7,8 +7,13 @@ module PicsolveDockerBuilder
7
7
  # Parses the config file
8
8
  class ConfigManager
9
9
  include PicsolveDockerBuilder::Base
10
- def initialize(path, stage)
11
- @path = path
10
+ def initialize(paths, stage)
11
+ if paths.is_a?(Array)
12
+ @paths = paths
13
+ else
14
+ @paths = [paths]
15
+ end
16
+
12
17
  # TODO: Do this properly, this is a very very dirty hack
13
18
  stage = (
14
19
  !ENV['STAGE'].nil? &&
@@ -86,11 +91,14 @@ module PicsolveDockerBuilder
86
91
 
87
92
  def read
88
93
  @config = default
89
- begin
90
- yaml = Psych.load_file @path
91
- @config = @config.deep_merge(yaml)
92
- rescue Errno::ENOENT
93
- raise "cannot find config at '#{path}'"
94
+ @paths.each do |file|
95
+ puts "my file is '#{@paths}'"
96
+ begin
97
+ yaml = Psych.load_file file
98
+ @config = @config.deep_merge(yaml)
99
+ rescue Errno::ENOENT
100
+ raise "cannot find config at '#{file}'"
101
+ end
94
102
  end
95
103
  end
96
104
  end
@@ -0,0 +1,145 @@
1
+ require 'picsolve_docker_builder/base'
2
+ require 'psych'
3
+ require 'git'
4
+
5
+ module PicsolveDockerBuilder
6
+ module Helpers
7
+ # Parses the config file
8
+ class ConfigVersionUpdate
9
+ include PicsolveDockerBuilder::Base
10
+
11
+ def self.update_task
12
+ log = Logger.new(STDOUT)
13
+
14
+ if ENV['service_name'].nil? || ENV['service_tag'].nil?
15
+ log.info 'No update needed as environment variables service_name '\
16
+ 'and service_tag are not in place'
17
+
18
+ return
19
+ end
20
+
21
+ cvu = new
22
+ cvu.update_commit_push(
23
+ ENV['service_name'],
24
+ ENV['service_tag'],
25
+ ENV['service_commit'],
26
+ ENV['service_url']
27
+ )
28
+ end
29
+
30
+ def initialize(path = nil)
31
+ @path = path || config_file
32
+ end
33
+
34
+ def check_for_uncommitted
35
+ return unless git.status.changed.keys.include? config_path
36
+
37
+ log.error "Uncommited changes to '#{config_path}'. Can't continue ..."
38
+ exit(1)
39
+ end
40
+
41
+ def commit_and_push(
42
+ container_name,
43
+ tag,
44
+ git_commit,
45
+ git_url
46
+ )
47
+ git.add config_path
48
+ message = "Upgrades version of '#{container_name}'"\
49
+ " to tag '#{tag}'"
50
+
51
+ message += "\n git_commit=#{git_commit}" if git_commit
52
+ message += "\n git_url=#{git_url}" if git_url
53
+ git.commit message
54
+ git.push(git_remote, git_branch)
55
+ rescue Git::GitExecuteError => exception
56
+ log.warn "Problem during commiting: #{exception}"
57
+ end
58
+
59
+ def git_remote_branch
60
+ ENV['GIT_BRANCH'] || 'origin/develop'
61
+ end
62
+
63
+ def git_remote
64
+ git_remote_branch.split('/')[0]
65
+ end
66
+
67
+ def git_branch
68
+ git_remote_branch.split('/')[1]
69
+ end
70
+
71
+ def config_file
72
+ unless File.file?(config_path)
73
+ File.open(config_path, 'w') do |file|
74
+ file.write('')
75
+ end
76
+ end
77
+ File.new config_path
78
+ end
79
+
80
+ def config_path
81
+ '.docker-builder.version.yml'
82
+ end
83
+
84
+ def git
85
+ @git ||= Git.open('.')
86
+ end
87
+
88
+ def update_commit_push(*args)
89
+ check_for_uncommitted
90
+ update(*args)
91
+ commit_and_push(*args)
92
+ end
93
+
94
+ def update(
95
+ container_name,
96
+ tag,
97
+ git_commit,
98
+ git_url
99
+ )
100
+ read
101
+ config = {
102
+ 'compose' => {
103
+ 'containers' => {
104
+ container_name => {
105
+ 'tag' => tag
106
+ }
107
+ }
108
+ }
109
+ }
110
+ c = config['compose']['containers'][container_name]
111
+
112
+ c['git_commit'] = git_commit unless git_commit.nil?
113
+ c['git_url'] = git_url unless git_url.nil?
114
+
115
+ @config = @config.deep_merge(config)
116
+ write
117
+ end
118
+
119
+ def write
120
+ File.open(@path, 'w') do |file|
121
+ file.write(Psych.dump(config))
122
+ end
123
+ end
124
+
125
+ def default
126
+ {}
127
+ end
128
+
129
+ def config
130
+ return @config unless @config.nil?
131
+ read
132
+ end
133
+
134
+ def read
135
+ @config = default
136
+ begin
137
+ yaml = Psych.load_file @path
138
+ @config = @config.deep_merge(yaml) if yaml
139
+ rescue Errno::ENOENT
140
+ raise "cannot find config at '#{path}'"
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -43,7 +43,7 @@ module PicsolveDockerBuilder
43
43
  def containers
44
44
  c = {
45
45
  'name' => @image.name,
46
- 'image' => @image.repo_tag_unique,
46
+ 'image' => @image.image_name_tag,
47
47
  'ports' => @image.ports_rc
48
48
  }
49
49
  # append environment variables if in place
@@ -2,6 +2,7 @@ require 'picsolve_docker_builder/base'
2
2
  require 'excon'
3
3
  require 'json'
4
4
  require 'base64'
5
+ require 'picsolve_docker_builder/helpers/repository'
5
6
 
6
7
  module PicsolveDockerBuilder
7
8
  module Helpers
@@ -12,6 +13,15 @@ module PicsolveDockerBuilder
12
13
 
13
14
  attr_reader :config
14
15
 
16
+ def self.creds(image = nil)
17
+ if image.nil?
18
+ registry = 'https://docker.picsolve.net'
19
+ else
20
+ registry = "https://#{image.split('/')[0]}"
21
+ end
22
+ new(registry).creds
23
+ end
24
+
15
25
  def initialize(registry)
16
26
  @registry = registry
17
27
  end
@@ -34,17 +44,19 @@ module PicsolveDockerBuilder
34
44
  end
35
45
 
36
46
  def list_tags_v1(image)
37
- endpoint = "/v1/repositories/#{image}/tags"
47
+ base_url = "/v1/repositories/#{image.user}/#{image.repo}"
48
+ endpoint = "#{base_url}/tags"
38
49
  r = connection.get(path: endpoint)
39
50
  JSON.parse(r.body)
40
51
  end
41
52
 
42
53
  def list_tags_v2(image)
43
- endpoint = "/v2/#{image}/tags/list"
54
+ base_url = "/v2/#{image.user}/#{image.repo}"
55
+ endpoint = "#{base_url}/tags/list"
44
56
  r = connection.get(path: endpoint)
45
57
  o = {}
46
58
  JSON.parse(r.body)['tags'].each do |tag|
47
- endpoint = "/v2/#{image}/manifests/#{tag}"
59
+ endpoint = "#{base_url}/manifests/#{tag}"
48
60
  r = connection.get(path: endpoint)
49
61
  digest = Digest::SHA2.new(256)
50
62
  JSON.parse(r.body)['fsLayers'].each do |fs_hash|
@@ -70,6 +82,7 @@ module PicsolveDockerBuilder
70
82
  end
71
83
 
72
84
  def list_tags(image)
85
+ image = Repository.new image
73
86
  if api_version == :v1
74
87
  list_tags_v1(image)
75
88
  elsif api_version == :v2
@@ -85,7 +98,8 @@ module PicsolveDockerBuilder
85
98
 
86
99
  def headers
87
100
  {
88
- 'Host' => http_host
101
+ 'Host' => http_host,
102
+ 'Authorization' => "Basic #{login_basic}"
89
103
  }
90
104
  end
91
105
 
@@ -96,11 +110,11 @@ module PicsolveDockerBuilder
96
110
  )
97
111
  end
98
112
 
99
- def self.dockercfg_path
113
+ def dockercfg_path
100
114
  File.expand_path '~/.dockercfg'
101
115
  end
102
116
 
103
- def self.dockercfg
117
+ def dockercfg
104
118
  JSON.parse(
105
119
  File.open(
106
120
  dockercfg_path
@@ -108,58 +122,19 @@ module PicsolveDockerBuilder
108
122
  )
109
123
  end
110
124
 
111
- def self.creds(*args)
112
- auth = Base64.decode64(
113
- get_login_basic(
114
- *args
115
- )
116
- ).split(':')
125
+ def creds
126
+ auth = Base64.decode64(login_basic).split(':')
117
127
  {
118
128
  'username' => auth[0],
119
129
  'password' => auth[1]
120
130
  }
121
131
  end
122
132
 
123
- def self.get_login_basic(registry = 'docker.picsolve.net')
124
- dockercfg[registry]['auth']
133
+ def login_basic
134
+ dockercfg[http_host]['auth']
125
135
  rescue StandardError
126
136
  nil
127
137
  end
128
-
129
- def self.repo_tag_unique(image_name)
130
- repo_tag = image_name.split(%r{/})[1..-1].join('/')
131
- repo_tag_split = repo_tag.split(/:/)
132
- repo = repo_tag_split[0]
133
- tag = repo_tag_split[1] || 'latest'
134
-
135
- headers = {}
136
- login_basic = get_login_basic
137
- headers['Authorization'] = "Basic #{login_basic}" \
138
- unless login_basic.nil?
139
-
140
- connection = Excon.new(
141
- 'https://docker.picsolve.net',
142
- headers: headers,
143
- persistent: true
144
- )
145
- response = connection.get(path: "/v1/repositories/#{repo}/tags")
146
-
147
- tags = JSON.parse(response.body)
148
-
149
- hash = tags[tag]
150
-
151
- tags.each do |t, h|
152
- next if h != hash
153
- next if t == tag
154
- next unless t.match(/jenkins-[0-9]+/)
155
- return {
156
- tag_unique: "#{image_name.split(':').first}:#{t}",
157
- hash: hash
158
- }
159
- end
160
-
161
- fail "Can not find a uniqe tag for #{image_name}"
162
- end
163
138
  end
164
139
  end
165
140
  end
@@ -1,4 +1,4 @@
1
1
  # version
2
2
  module PicsolveDockerBuilder
3
- VERSION = '0.5.0'
3
+ VERSION = '0.5.1'
4
4
  end
@@ -24,4 +24,10 @@ namespace :compose do
24
24
  @docker_compose.stage = stage
25
25
  @docker_compose.deploy
26
26
  end
27
+
28
+ desc 'Update version of container'
29
+ task :update do
30
+ require 'picsolve_docker_builder/helpers/config_version_update'
31
+ PicsolveDockerBuilder::Helpers::ConfigVersionUpdate.update_task
32
+ end
27
33
  end
@@ -34,4 +34,5 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency 'docker-api'
35
35
  spec.add_dependency 'net-ssh'
36
36
  spec.add_dependency 'pg'
37
+ spec.add_dependency 'git'
37
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picsolve_docker_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Simon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-03 00:00:00.000000000 Z
11
+ date: 2016-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -192,6 +192,20 @@ dependencies:
192
192
  - - ">="
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: git
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
195
209
  description:
196
210
  email:
197
211
  - christian.simon@picsolve.com
@@ -268,6 +282,7 @@ files:
268
282
  - lib/picsolve_docker_builder/helpers/config/secret.rb
269
283
  - lib/picsolve_docker_builder/helpers/config/variable_object.rb
270
284
  - lib/picsolve_docker_builder/helpers/config_manager.rb
285
+ - lib/picsolve_docker_builder/helpers/config_version_update.rb
271
286
  - lib/picsolve_docker_builder/helpers/kubeclient.rb
272
287
  - lib/picsolve_docker_builder/helpers/kubernetes/pod.rb
273
288
  - lib/picsolve_docker_builder/helpers/kubernetes/rc.rb