rbld 1.1.0 → 1.2.0

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: d227fefcee50eefa5f3d6bfa353ada39b2ca01af
4
- data.tar.gz: 8ac255f0c137b88e4ba6d38d43f3c6dd4d26ff7d
3
+ metadata.gz: ab06977050419017e9293fc7add885a3474ded72
4
+ data.tar.gz: 777845489d399990b3942c2d70df0fbf42bd32d3
5
5
  SHA512:
6
- metadata.gz: c6d267b8044f72f2fa02ab7768eca155bb9555945707858da17e884a76f46c0d32c1243f0774aac6448bcf8824a3b375390241dbfd88f1fdb73234a6a720ebeb
7
- data.tar.gz: e124388ec7544bb4c7fe5b5457db4faffa90f6fa4b914c49759b4e60452a59476d6821e1aef2dec22dde51e0e64df088f132c19b1cef996e69103bce7c1c9c15
6
+ metadata.gz: 36db91de99ee92c41d64b6f1b684edaa539c3e76c1ba0cec9fb91b50af40f074f57f2ff4c148b5ae71f785330412ebbbe1b96f54e1d484ed6508f4ed0950087e
7
+ data.tar.gz: 066ccf5ce3425c76784e4c2cca7bd90c5030076f106e56969a1444130955197d4341d5d00436969a6551be2ca6024406188ba1faef4ac12cca979a34cf95efde
data/cli/bin/rbld CHANGED
@@ -29,7 +29,8 @@ begin
29
29
 
30
30
  exit Rebuild::CLI::Commands.run( ARGV[0], ARGV.drop(1) ) || 0
31
31
 
32
- rescue RuntimeError => msg
33
- rbld_print.error(msg)
32
+ rescue StandardError => e
33
+ rbld_print.error(e.message)
34
+ e.backtrace.each { |l| rbld_log.fatal(l) }
34
35
  exit 1
35
36
  end
@@ -32,4 +32,7 @@ delete_user()
32
32
  if test "x${REBUILD_TRACE}" = "x1"; then
33
33
  set -x
34
34
  echo Bootstrap tracing enabled
35
+ DEBUG_TRACE=/dev/tty
36
+ else
37
+ DEBUG_TRACE=/dev/null
35
38
  fi
@@ -22,13 +22,13 @@ setup_users()
22
22
 
23
23
  if has_app useradd; then
24
24
 
25
- groupadd -o -g $REBUILD_GROUP_ID $REBUILD_GROUP_NAME
25
+ groupadd -o -g $REBUILD_GROUP_ID $REBUILD_GROUP_NAME 2>$DEBUG_TRACE
26
26
 
27
27
  useradd -o -M \
28
28
  -g $REBUILD_GROUP_ID \
29
29
  -u $REBUILD_USER_ID \
30
30
  --home-dir $REBUILD_USER_HOME \
31
- $REBUILD_USER_NAME
31
+ $REBUILD_USER_NAME 2>$DEBUG_TRACE
32
32
 
33
33
  else
34
34
 
@@ -70,6 +70,10 @@ fi
70
70
 
71
71
  RC=$?
72
72
 
73
+ if test -z "$*"; then
74
+ rebuild_banner ""
75
+ fi
76
+
73
77
  rebuild_banner "<<< rebuild env $HOSTNAME"
74
78
 
75
79
  exit $RC
data/cli/lib/data/version CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.2.0
@@ -0,0 +1,133 @@
1
+ require 'docker_registry2'
2
+ require_relative 'rbld_log'
3
+ require_relative 'rbld_utils'
4
+ require 'fancy_gets'
5
+
6
+ module Rebuild
7
+ module Registry
8
+ module Docker
9
+ extend Rebuild::Utils::Errors
10
+
11
+ rebuild_errors \
12
+ RegistryOperationError: nil,
13
+ RegistryNotAuthenticatedError: nil
14
+
15
+ class EnvironmentImage
16
+ include FancyGets
17
+
18
+ def initialize(api_module = ::Docker)
19
+ @api_module = api_module
20
+ end
21
+
22
+ def publish(img, target_url)
23
+ try_with_login { try_publish( img, target_url ) }
24
+ end
25
+
26
+ def deploy(source_url)
27
+ try_with_login do
28
+ try_deploy( source_url ) { |img| yield img }
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def try_with_login
35
+ begin
36
+ yield
37
+ rescue RegistryNotAuthenticatedError
38
+ do_login
39
+ yield
40
+ end
41
+ end
42
+
43
+ def get_credential(name, is_secret = false)
44
+ print "#{name}: "
45
+ predefined = ENV["RBLD_CREDENTIAL_#{name.upcase}"]
46
+ if predefined
47
+ puts "<environment>"
48
+ predefined
49
+ else
50
+ is_secret ? gets_password : STDIN.gets.chomp
51
+ end
52
+ end
53
+
54
+ def get_secret_credential(name)
55
+ get_credential( name, true )
56
+ end
57
+
58
+ def do_login
59
+ puts
60
+ puts "Login required"
61
+ puts
62
+ user = get_credential('Username')
63
+ email = get_credential('Email')
64
+ pwd = get_secret_credential('Password')
65
+ @api_module.creds = { 'username' => user,
66
+ 'password' => pwd,
67
+ 'email' => email }
68
+ end
69
+
70
+ def try_publish(img, target_url)
71
+ api_obj = img.api_obj
72
+ api_obj.tag( repo: target_url.repo, tag: target_url.tag )
73
+
74
+ begin
75
+ rbld_log.info( "Pushing #{target_url.full}" )
76
+ @last_error = nil
77
+ api_obj.push(nil, :repo_tag => target_url.full) do |log|
78
+ process_log( log )
79
+ end
80
+ raise_last_error
81
+ ensure
82
+ api_obj.remove( :name => target_url.full )
83
+ end
84
+ end
85
+
86
+ def try_deploy(source_url)
87
+ begin
88
+ rbld_log.info( "Pulling #{source_url.full}" )
89
+ @last_error = nil
90
+ img = @api_module::Image.create(:fromImage => source_url.full) do |log|
91
+ process_log( log )
92
+ end
93
+ raise_last_error
94
+ yield img
95
+ ensure
96
+ img.remove( :name => source_url.full ) if img
97
+ end
98
+ end
99
+
100
+ def process_log(log_item)
101
+ begin
102
+ json = JSON.parse( log_item )
103
+ rescue
104
+ else
105
+ trace_progress( json['progress'] )
106
+ save_last_error( json['errorDetail'] )
107
+ end
108
+ end
109
+
110
+ def trace_progress(line)
111
+ rbld_print.inplace_trace( line ) if line
112
+ end
113
+
114
+ def save_last_error(line)
115
+ @last_error = line['message'] if line
116
+ end
117
+
118
+ def raise_last_error
119
+ case @last_error
120
+ when nil
121
+ # No error
122
+ when /authentication required/, /unauthorized/
123
+ raise RegistryNotAuthenticatedError, @last_error
124
+ else
125
+ raise RegistryOperationError, @last_error
126
+ end
127
+
128
+ end
129
+
130
+ end
131
+ end
132
+ end
133
+ end
@@ -8,6 +8,7 @@ require_relative 'rbld_config'
8
8
  require_relative 'rbld_utils'
9
9
  require_relative 'rbld_print'
10
10
  require_relative 'rbld_reg_docker'
11
+ require_relative 'rbld_reg_dockerhub'
11
12
  require_relative 'rbld_reg_fs'
12
13
  require_relative 'rbld_fileops'
13
14
 
@@ -270,6 +271,7 @@ module Rebuild::Engine
270
271
 
271
272
  rebuild_errors \
272
273
  UnsupportedDockerService: 'Unsupported docker service: %s',
274
+ InaccessibleDockerService: 'Unable to reach the docker engine',
273
275
  EnvironmentIsModified: 'Environment is modified, commit or checkout first',
274
276
  EnvironmentNotKnown: 'Unknown environment %s',
275
277
  NoChangesToCommit: 'No changes to commit for %s',
@@ -285,7 +287,7 @@ module Rebuild::Engine
285
287
  def self.from_file(file)
286
288
  base = %Q{
287
289
  FROM scratch
288
- ADD #{file} /
290
+ ADD #{File.basename( file )} /
289
291
  }
290
292
 
291
293
  new( base, file )
@@ -604,12 +606,15 @@ module Rebuild::Engine
604
606
  end
605
607
 
606
608
  def check_connectivity
607
- begin
608
- @docker_api.validate_version!
609
+ @docker_api.validate_version!
610
+
609
611
  rescue Docker::Error::VersionError => msg
612
+ rbld_log.fatal( msg )
610
613
  raise UnsupportedDockerService, msg
611
- end
612
- end
614
+ rescue => msg
615
+ rbld_log.fatal( msg )
616
+ raise InaccessibleDockerService
617
+ end
613
618
 
614
619
  def registry
615
620
  return @registry if @registry
@@ -617,6 +622,8 @@ module Rebuild::Engine
617
622
  case @cfg.remote!.type
618
623
  when 'docker'
619
624
  reg_module = Rebuild::Registry::Docker
625
+ when 'dockerhub'
626
+ reg_module = Rebuild::Registry::DockerHub
620
627
  when 'rebuild'
621
628
  reg_module = Rebuild::Registry::FS
622
629
  else
@@ -1,6 +1,7 @@
1
1
  require 'docker_registry2'
2
2
  require_relative 'rbld_log'
3
3
  require_relative 'rbld_utils'
4
+ require_relative 'rbld_dockerops'
4
5
 
5
6
  module Rebuild
6
7
  module Registry
@@ -36,7 +37,7 @@ module Rebuild
36
37
  end
37
38
 
38
39
  class API
39
- def initialize(remote, api_accessor = DockerRegistry)
40
+ def initialize(remote, api_accessor = DockerRegistry2)
40
41
  @remote = remote
41
42
  rbld_log.info( "Connecting to registry #{@remote}" )
42
43
  begin
@@ -57,32 +58,12 @@ module Rebuild
57
58
 
58
59
  def publish(name, tag, img)
59
60
  url = Entry.new( name, tag, @remote ).url
60
- api_obj = img.api_obj
61
-
62
- api_obj.tag( repo: url.repo, tag: url.tag )
63
-
64
- begin
65
- rbld_log.info( "Pushing #{url.full}" )
66
- api_obj.push(nil, :repo_tag => url.full) do |log|
67
- trace_progress( log )
68
- end
69
- ensure
70
- api_obj.remove( :name => url.full )
71
- end
61
+ EnvironmentImage.new.publish( img, url )
72
62
  end
73
63
 
74
- def deploy(name, tag, api_class = ::Docker::Image)
64
+ def deploy(name, tag, api_module = ::Docker)
75
65
  url = Entry.new( name, tag, @remote ).url
76
-
77
- begin
78
- rbld_log.info( "Pulling #{url.full}" )
79
- img = api_class.create(:fromImage => url.full) do |log|
80
- trace_progress( log )
81
- end
82
- yield img
83
- ensure
84
- img.remove( :name => url.full ) if img
85
- end
66
+ EnvironmentImage.new(api_module).deploy( url ) { |img| yield img }
86
67
  end
87
68
 
88
69
  private
@@ -0,0 +1,96 @@
1
+ require 'docker_registry'
2
+ require_relative 'rbld_log'
3
+ require_relative 'rbld_utils'
4
+ require_relative 'rbld_dockerops'
5
+
6
+ module Rebuild
7
+ module Registry
8
+ module DockerHub
9
+ extend Rebuild::Utils::Errors
10
+
11
+ rebuild_errors \
12
+ IndexConnectionError: 'Failed to access registry at %s',
13
+ InternalNameParsingError: 'Failed to parse internal name'
14
+
15
+ class Entry
16
+ REGISTRY_ENDPOINT = 'docker.io'
17
+ NAME_PFX = 'rbe-'
18
+ TAG_PFX = '-rt-'
19
+ private_constant :NAME_PFX, :TAG_PFX, :REGISTRY_ENDPOINT
20
+
21
+ def initialize(name, tag, path = nil)
22
+ @name, @tag = name, tag
23
+ @url = Rebuild::Utils::FullImageName.new( "#{REGISTRY_ENDPOINT}/#{path}",
24
+ "#{NAME_PFX}#{@name}#{TAG_PFX}#{@tag}" ) if path
25
+ end
26
+
27
+ def self.by_internal_name( int_name )
28
+ m = int_name.match(/^#{NAME_PFX}(.*)#{TAG_PFX}(.*)/)
29
+ raise InternalNameParsingError, int_name unless m
30
+ new( *m.captures )
31
+ end
32
+
33
+ def match( name, tag )
34
+ name, tag = name.to_s, tag.to_s
35
+ return tag.empty? ? @name.start_with?( name )
36
+ : (@name == name && @tag.start_with?( tag ))
37
+ end
38
+
39
+ attr_reader :name, :tag, :url
40
+ end
41
+
42
+ class API
43
+ INDEX_ENDPOINT = 'index.docker.io'
44
+ private_constant :INDEX_ENDPOINT
45
+
46
+ def initialize(path)
47
+ @path = path
48
+ rbld_log.info( "Connecting to DockerHub #{@path}" )
49
+ begin
50
+ endpoint = ENV['RBLD_OVERRIDE_INDEX_ENDPOINT'] || INDEX_ENDPOINT
51
+ @index = DockerRegistry::Registry.new("https://#{endpoint}")
52
+ @index.ping
53
+ rescue StandardError
54
+ raise IndexConnectionError, endpoint
55
+ end
56
+ end
57
+
58
+ def search(name = nil, tag = nil)
59
+ rbld_log.info( "Searching for #{name}:#{tag}" )
60
+
61
+ repo = @index.search(@path).detect { |e| e.name == @path }
62
+
63
+ return [] unless repo
64
+
65
+ repo.tags.map do |e|
66
+ parse_entry( e.name['name'] )
67
+ end.compact.find_all do |e|
68
+ e.match( name, tag )
69
+ end
70
+ end
71
+
72
+ def publish(name, tag, img)
73
+ url = Entry.new( name, tag, @path ).url
74
+ Docker::EnvironmentImage.new.publish( img, url )
75
+ end
76
+
77
+ def deploy(name, tag, api_module = ::Docker)
78
+ url = Entry.new( name, tag, @path ).url
79
+ Docker::EnvironmentImage.new(api_module).deploy( url ) { |img| yield img }
80
+ end
81
+
82
+ private
83
+
84
+ def parse_entry(internal_name)
85
+ rbld_log.debug( "Parsing internal name '#{internal_name}'" )
86
+ begin
87
+ Entry.by_internal_name( internal_name )
88
+ rescue InternalNameParsingError => msg
89
+ rbld_log.warn( msg )
90
+ return nil
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbld
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Fleytman
8
8
  autorequire:
9
9
  bindir: cli/bin
10
10
  cert_chain: []
11
- date: 2017-02-02 00:00:00.000000000 Z
11
+ date: 2017-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -58,20 +58,34 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: 1.32.1
61
+ - !ruby/object:Gem::Dependency
62
+ name: docker_registry
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.0.3
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.0.3
61
75
  - !ruby/object:Gem::Dependency
62
76
  name: docker_registry2
63
77
  requirement: !ruby/object:Gem::Requirement
64
78
  requirements:
65
79
  - - "~>"
66
80
  - !ruby/object:Gem::Version
67
- version: 0.3.0
81
+ version: 0.4.0
68
82
  type: :runtime
69
83
  prerelease: false
70
84
  version_requirements: !ruby/object:Gem::Requirement
71
85
  requirements:
72
86
  - - "~>"
73
87
  - !ruby/object:Gem::Version
74
- version: 0.3.0
88
+ version: 0.4.0
75
89
  - !ruby/object:Gem::Dependency
76
90
  name: parseconfig
77
91
  requirement: !ruby/object:Gem::Requirement
@@ -132,6 +146,26 @@ dependencies:
132
146
  - - ">="
133
147
  - !ruby/object:Gem::Version
134
148
  version: 0.9.6
149
+ - !ruby/object:Gem::Dependency
150
+ name: fancy_gets_ex
151
+ requirement: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - "~>"
154
+ - !ruby/object:Gem::Version
155
+ version: '0.1'
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: 0.1.6
159
+ type: :runtime
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '0.1'
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: 0.1.6
135
169
  - !ruby/object:Gem::Dependency
136
170
  name: rake
137
171
  requirement: !ruby/object:Gem::Requirement
@@ -282,11 +316,13 @@ files:
282
316
  - cli/lib/data/version
283
317
  - cli/lib/rbld_commands.rb
284
318
  - cli/lib/rbld_config.rb
319
+ - cli/lib/rbld_dockerops.rb
285
320
  - cli/lib/rbld_engine.rb
286
321
  - cli/lib/rbld_fileops.rb
287
322
  - cli/lib/rbld_log.rb
288
323
  - cli/lib/rbld_print.rb
289
324
  - cli/lib/rbld_reg_docker.rb
325
+ - cli/lib/rbld_reg_dockerhub.rb
290
326
  - cli/lib/rbld_reg_fs.rb
291
327
  - cli/lib/rbld_utils.rb
292
328
  - cli/lib/rbld_verinfo.rb
@@ -314,5 +350,5 @@ rubyforge_project:
314
350
  rubygems_version: 2.4.8
315
351
  signing_key:
316
352
  specification_version: 4
317
- summary: rbld-1.1.0
353
+ summary: rbld-1.2.0
318
354
  test_files: []