picsolve_docker_builder 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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