bosh-director 1.2641.0 → 1.2652.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: 970adfc1d8041fe7624fc4adf1cad86917730920
4
- data.tar.gz: 6fb6b4ac83b53114782683c85ba45c9ec667ab8e
3
+ metadata.gz: e23095b6bfae1e8e3ef95c3ed35d673812f7ff06
4
+ data.tar.gz: 45d0ef37a600837a982c75cf2c76a012886938a2
5
5
  SHA512:
6
- metadata.gz: 36949611acd25fdcebab2740ad414ea358633c7e0971d477e43775e58330855d52a39faf04c9669ef34842c1b6e2f2b716d265d09903d52a23602458538e81c7
7
- data.tar.gz: fcea68e23b7695ede27826510374db24524032376eeb8ede6e6afdf2a10218777b00c31d9de8250744f9d3a7cd0084e4514290c05c6979d94d594d21f6993d87
6
+ metadata.gz: c98835abd2840e2d857cf7b24207bc26b765a90846170eb760f028b169977202b394da3aeaa5f94f6c74349fd7d76a1f7174004491fc4a74021316434ca9a7e0
7
+ data.tar.gz: 42802d742f68e2539451f63e6b55590c91ee2cf3f98fd7e4a54f58131bba993ee17304ad64c6ba2dbe05adfda9d1baf25b28ca001219fa862996910c38b96f93
@@ -78,4 +78,4 @@ module Bosh::Director
78
78
  end
79
79
  end
80
80
  end
81
- end
81
+ end
@@ -0,0 +1,17 @@
1
+ require 'securerandom'
2
+
3
+ module Bosh::Director
4
+ module Api
5
+ class CompiledPackageGroupManager
6
+ include ApiHelper
7
+
8
+ def create_from_file_path(user, path)
9
+ unless File.exists?(path)
10
+ raise DirectorError, "Failed to import compiled packages: file not found - #{path}"
11
+ end
12
+
13
+ JobQueue.new.enqueue(user, Jobs::ImportCompiledPackages, 'import compiled packages', [path])
14
+ end
15
+ end
16
+ end
17
+ end
@@ -26,14 +26,18 @@ module Bosh::Director
26
26
  @logger = Config.logger
27
27
  end
28
28
 
29
- mime_type :tgz, 'application/x-compressed'
29
+ mime_type :tgz, 'application/x-compressed'
30
+ mime_type :multipart, 'multipart/form-data'
30
31
 
31
32
  def self.consumes(*types)
32
33
  types = Set.new(types)
33
34
  types.map! { |t| mime_type(t) }
34
35
 
35
36
  condition do
36
- types.include?(request.content_type)
37
+ # Content-Type header may include charset or boundry info
38
+ content_type = request.content_type || ''
39
+ mime_type = content_type.split(';')[0]
40
+ types.include?(mime_type)
37
41
  end
38
42
  end
39
43
 
@@ -1,5 +1,6 @@
1
1
  require 'json'
2
2
  require 'tempfile'
3
+ require 'bosh/director/api/compiled_package_group_manager'
3
4
  require 'bosh/director/api/controllers/base_controller'
4
5
  require 'bosh/director/api/stemcell_manager'
5
6
  require 'bosh/director/compiled_package_group'
@@ -10,7 +11,12 @@ require 'bosh/director/jobs/import_compiled_packages'
10
11
  module Bosh::Director
11
12
  module Api::Controllers
12
13
  class CompiledPackagesController < BaseController
13
- post '/compiled_package_groups/export', consumes: [:json] do
14
+ def initialize(*args)
15
+ super
16
+ @compiled_package_group_manager = Api::CompiledPackageGroupManager.new
17
+ end
18
+
19
+ post '/compiled_package_groups/export', consumes: :json do
14
20
  stemcell = find_stemcell_by_name_and_version
15
21
  release_version = find_release_version_by_name_and_version
16
22
 
@@ -30,20 +36,13 @@ module Bosh::Director
30
36
  send_file(output_path, type: :tgz)
31
37
  end
32
38
 
33
- post '/compiled_package_groups/import', consumes: [:tgz] do
34
- tempdir = Dir.mktmpdir
35
- export_path = File.join(tempdir, 'compiled_packages_export.tgz')
36
- # the job is responsible for cleaning this up
37
- File.open(export_path, 'w') do |f|
38
- while buf = request.body.read(4096)
39
- f.write(buf)
40
- end
41
- end
42
-
43
- task = JobQueue.new.enqueue(@user, Jobs::ImportCompiledPackages, 'import compiled packages', [tempdir])
39
+ post '/compiled_package_groups/import', consumes: :multipart do
40
+ task = @compiled_package_group_manager.create_from_file_path(@user, params[:nginx_upload_path])
44
41
  redirect "/tasks/#{task.id}"
45
42
  end
46
43
 
44
+ private
45
+
47
46
  def find_stemcell_by_name_and_version
48
47
  stemcell_manager = Api::StemcellManager.new
49
48
  stemcell_manager.find_by_name_and_version(
@@ -3,37 +3,35 @@ require 'bosh/director/api/controllers/base_controller'
3
3
  module Bosh::Director
4
4
  module Api::Controllers
5
5
  class ReleasesController < BaseController
6
- post '/releases', :consumes => :tgz do
7
- options = {}
8
- options['remote'] = false
9
- options['rebase'] = true if params['rebase'] == 'true'
10
-
11
- task = @release_manager.create_release(@user, request.body, options)
12
- redirect "/tasks/#{task.id}"
13
- end
14
-
15
6
  post '/releases', :consumes => :json do
16
- options = {}
17
- options['remote'] = true
18
- options['rebase'] = true if params['rebase'] == 'true'
19
7
  payload = json_decode(request.body)
8
+ rebase = params['rebase'] == 'true'
9
+ task = @release_manager.create_release_from_url(@user, payload['location'], rebase)
10
+ redirect "/tasks/#{task.id}"
11
+ end
20
12
 
21
- task = @release_manager.create_release(@user, payload['location'], options)
13
+ post '/releases', :consumes => :multipart do
14
+ rebase = params['rebase'] == 'true'
15
+ task = @release_manager.create_release_from_file_path(@user, params[:nginx_upload_path], rebase)
22
16
  redirect "/tasks/#{task.id}"
23
17
  end
24
18
 
25
19
  get '/releases' do
26
20
  releases = Models::Release.order_by(:name.asc).map do |release|
27
21
  release_versions = release.versions_dataset.order_by(:version.asc).map do |rv|
28
- Hash['version', rv.version.to_s,
29
- 'commit_hash', rv.commit_hash,
30
- 'uncommitted_changes', rv.uncommitted_changes,
31
- 'currently_deployed', !rv.deployments.empty?,
32
- 'job_names', rv.templates.map(&:name)]
22
+ {
23
+ 'version' => rv.version.to_s,
24
+ 'commit_hash' => rv.commit_hash,
25
+ 'uncommitted_changes' => rv.uncommitted_changes,
26
+ 'currently_deployed' => !rv.deployments.empty?,
27
+ 'job_names' => rv.templates.map(&:name),
28
+ }
33
29
  end
34
30
 
35
- Hash['name', release.name,
36
- 'release_versions', release_versions]
31
+ {
32
+ 'name' => release.name,
33
+ 'release_versions' => release_versions,
34
+ }
37
35
  end
38
36
 
39
37
  json_encode(releases)
@@ -3,14 +3,14 @@ require 'bosh/director/api/controllers/base_controller'
3
3
  module Bosh::Director
4
4
  module Api::Controllers
5
5
  class StemcellsController < BaseController
6
- post '/stemcells', :consumes => :tgz do
7
- task = @stemcell_manager.create_stemcell(@user, request.body, :remote => false)
6
+ post '/stemcells', :consumes => :json do
7
+ payload = json_decode(request.body)
8
+ task = @stemcell_manager.create_stemcell_from_url(@user, payload['location'])
8
9
  redirect "/tasks/#{task.id}"
9
10
  end
10
11
 
11
- post '/stemcells', :consumes => :json do
12
- payload = json_decode(request.body)
13
- task = @stemcell_manager.create_stemcell(@user, payload['location'], :remote => true)
12
+ post '/stemcells', :consumes => :multipart do
13
+ task = @stemcell_manager.create_stemcell_from_file_path(@user, params[:nginx_upload_path])
14
14
  redirect "/tasks/#{task.id}"
15
15
  end
16
16
 
@@ -3,8 +3,6 @@ module Bosh::Director
3
3
  class ReleaseManager
4
4
  include ApiHelper
5
5
 
6
- RELEASE_TGZ = 'release.tgz'
7
-
8
6
  # Finds release by name
9
7
  # @param [String] name Release name
10
8
  # @return [Models::Release]
@@ -48,21 +46,18 @@ module Bosh::Director
48
46
  release_version
49
47
  end
50
48
 
51
- def create_release(user, release_bundle, options = {})
52
- release_dir = Dir.mktmpdir('release')
53
-
54
- if options['remote']
55
- options['location'] = release_bundle
56
- else
57
- unless check_available_disk_space(release_dir, release_bundle.size)
58
- raise NotEnoughDiskSpace, 'Uploading release archive failed. ' +
59
- "Insufficient space on BOSH director in #{release_dir}"
60
- end
49
+ def create_release_from_url(user, release_url, rebase)
50
+ options = { remote: true, rebase: rebase }
51
+ JobQueue.new.enqueue(user, Jobs::UpdateRelease, 'create release', [release_url, options])
52
+ end
61
53
 
62
- write_file(File.join(release_dir, RELEASE_TGZ), release_bundle)
54
+ def create_release_from_file_path(user, release_path, rebase)
55
+ unless File.exists?(release_path)
56
+ raise DirectorError, "Failed to create release: file not found - #{release_path}"
63
57
  end
64
58
 
65
- JobQueue.new.enqueue(user, Jobs::UpdateRelease, 'create release', [release_dir, options])
59
+ options = { rebase: rebase }
60
+ JobQueue.new.enqueue(user, Jobs::UpdateRelease, 'create release', [release_path, options])
66
61
  end
67
62
 
68
63
  def delete_release(user, release, options = {})
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2009-2012 VMware, Inc.
1
+ require 'securerandom'
2
2
 
3
3
  module Bosh::Director
4
4
  module Api
@@ -21,23 +21,16 @@ module Bosh::Director
21
21
  false
22
22
  end
23
23
 
24
- def create_stemcell(user, stemcell, options = {})
25
- if options[:remote]
26
- stemcell_file = stemcell
27
- else
28
- random_name = "stemcell-#{SecureRandom.uuid}"
29
- stemcell_dir = Dir::tmpdir
30
- stemcell_file = File.join(stemcell_dir, random_name)
31
-
32
- unless check_available_disk_space(stemcell_dir, stemcell.size)
33
- raise NotEnoughDiskSpace, "Uploading stemcell archive failed. " +
34
- "Insufficient space on BOSH director in #{stemcell_dir}"
35
- end
36
-
37
- write_file(stemcell_file, stemcell)
24
+ def create_stemcell_from_url(user, stemcell_url)
25
+ JobQueue.new.enqueue(user, Jobs::UpdateStemcell, 'create stemcell', [stemcell_url, { remote: true }])
26
+ end
27
+
28
+ def create_stemcell_from_file_path(user, stemcell_path)
29
+ unless File.exists?(stemcell_path)
30
+ raise DirectorError, "Failed to create stemcell: file not found - #{stemcell_path}"
38
31
  end
39
32
 
40
- JobQueue.new.enqueue(user, Jobs::UpdateStemcell, 'create stemcell', [stemcell_file, options])
33
+ JobQueue.new.enqueue(user, Jobs::UpdateStemcell, 'create stemcell', [stemcell_path])
41
34
  end
42
35
 
43
36
  def delete_stemcell(user, stemcell, options={})
@@ -47,4 +40,4 @@ module Bosh::Director
47
40
  end
48
41
  end
49
42
  end
50
- end
43
+ end
@@ -19,6 +19,7 @@ require 'bosh/director/api/release_manager'
19
19
  require 'bosh/director/api/resource_manager'
20
20
  require 'bosh/director/api/snapshot_manager'
21
21
  require 'bosh/director/api/stemcell_manager'
22
+ require 'bosh/director/api/compiled_package_group_manager'
22
23
  require 'bosh/director/api/task_manager'
23
24
  require 'bosh/director/api/user_manager'
24
25
  require 'bosh/director/api/vm_state_manager'
@@ -8,33 +8,34 @@ module Bosh::Director::CompiledPackage
8
8
 
9
9
  def insert(compiled_package, release_version)
10
10
  package = Bosh::Director::Models::Package[fingerprint: compiled_package.package_fingerprint]
11
- stemcell = Bosh::Director::Models::Stemcell[sha1: compiled_package.stemcell_sha1]
12
-
13
11
  raise ArgumentError, [compiled_package.inspect, release_version.inspect].inspect unless package
14
12
 
15
- unless Bosh::Director::Models::CompiledPackage[
13
+ stemcell = Bosh::Director::Models::Stemcell[sha1: compiled_package.stemcell_sha1]
14
+
15
+ compiled_package_model = Bosh::Director::Models::CompiledPackage[
16
16
  package: package,
17
17
  stemcell: stemcell,
18
18
  dependency_key: release_version.package_dependency_key(package.name),
19
19
  ]
20
20
 
21
- oid = File.open(compiled_package.blob_path) do |f|
22
- @blobstore_client.create(f)
23
- end
21
+ return if compiled_package_model
22
+
23
+ oid = File.open(compiled_package.blob_path) do |f|
24
+ @blobstore_client.create(f)
25
+ end
24
26
 
25
- begin
26
- Bosh::Director::Models::CompiledPackage.create(
27
- blobstore_id: oid,
28
- package: package,
29
- stemcell: stemcell,
30
- sha1: compiled_package.sha1,
31
- dependency_key: release_version.package_dependency_key(package.name),
32
- build: Bosh::Director::Models::CompiledPackage.generate_build_number(package, stemcell),
33
- )
34
- rescue
35
- @blobstore_client.delete(oid)
36
- raise
37
- end
27
+ begin
28
+ Bosh::Director::Models::CompiledPackage.create(
29
+ blobstore_id: oid,
30
+ package: package,
31
+ stemcell: stemcell,
32
+ sha1: compiled_package.sha1,
33
+ dependency_key: release_version.package_dependency_key(package.name),
34
+ build: Bosh::Director::Models::CompiledPackage.generate_build_number(package, stemcell),
35
+ )
36
+ rescue
37
+ @blobstore_client.delete(oid)
38
+ raise
38
39
  end
39
40
  end
40
41
  end
@@ -8,11 +8,14 @@ module Bosh::Director::CompiledPackage
8
8
  @exec = options.fetch(:exec, Bosh::Exec)
9
9
  end
10
10
 
11
- def extract(tempdir=nil)
12
- tempdir ||= Dir.mktmpdir
13
- exec.sh("tar -C #{tempdir} -xf #{file}")
14
- manifest = YAML.load_file("#{tempdir}/compiled_packages.MF")
11
+ def extract
12
+ tmp_dir = Dir.mktmpdir
13
+
14
+ @exec.sh("tar -C #{tmp_dir} -xf #{@file}")
15
+
16
+ manifest = YAML.load_file("#{tmp_dir}/compiled_packages.MF")
15
17
  packages = []
18
+
16
19
  manifest['compiled_packages'].each do |p|
17
20
  packages << CompiledPackage.new(
18
21
  package_name: p['package_name'],
@@ -20,16 +23,13 @@ module Bosh::Director::CompiledPackage
20
23
  sha1: p['compiled_package_sha1'],
21
24
  stemcell_sha1: p['stemcell_sha1'],
22
25
  blobstore_id: p['blobstore_id'],
23
- blob_path: File.join(tempdir, 'compiled_packages', 'blobs', p['blobstore_id']))
26
+ blob_path: File.join(tmp_dir, 'compiled_packages', 'blobs', p['blobstore_id']),
27
+ )
24
28
  end
25
29
 
26
30
  yield manifest, packages
27
31
 
28
- FileUtils.rm_rf(tempdir)
32
+ FileUtils.rm_rf(tmp_dir)
29
33
  end
30
-
31
- private
32
-
33
- attr_reader :file, :exec
34
34
  end
35
35
  end
@@ -41,7 +41,7 @@ module Bosh::Director
41
41
  attr_accessor option
42
42
  end
43
43
 
44
- attr_reader :db_config
44
+ attr_reader :db_config, :redis_logger_level
45
45
 
46
46
  def clear
47
47
  CONFIG_OPTIONS.each do |option|
@@ -75,14 +75,14 @@ module Bosh::Director
75
75
  logging = config.fetch('logging', {})
76
76
  @log_device = MonoLogger::LocklessLogDevice.new(logging.fetch('file', STDOUT))
77
77
  @logger = MonoLogger.new(@log_device)
78
- @logger.level = MonoLogger.const_get(logging.fetch('level', 'debug').upcase)
78
+ @logger.level = Logger.const_get(logging.fetch('level', 'debug').upcase)
79
79
  @logger.formatter = ThreadFormatter.new
80
80
 
81
81
  # use a separate logger for redis to make it stfu
82
82
  redis_logger = MonoLogger.new(@log_device)
83
83
  logging = config.fetch('redis', {}).fetch('logging', {})
84
- redis_logger_level = logging.fetch('level', 'info').upcase
85
- redis_logger.level = MonoLogger.const_get(redis_logger_level)
84
+ @redis_logger_level = Logger.const_get(logging.fetch('level', 'info').upcase)
85
+ redis_logger.level = @redis_logger_level
86
86
 
87
87
  # Event logger supposed to be overridden per task,
88
88
  # the default one does nothing
@@ -93,7 +93,7 @@ module Bosh::Director
93
93
 
94
94
  @max_threads = config.fetch('max_threads', 32).to_i
95
95
 
96
- self.redis_options= {
96
+ self.redis_options = {
97
97
  :host => config['redis']['host'],
98
98
  :port => config['redis']['port'],
99
99
  :password => config['redis']['password'],
@@ -201,24 +201,20 @@ module Bosh::Director
201
201
  Config.cloud_options.fetch('properties', {}).fetch('cpi_log')
202
202
  end
203
203
 
204
- def logger=(logger)
205
- @logger = logger
206
- redis_options[:logger] = @logger
207
- if redis?
208
- redis.client.logger = @logger
209
- end
210
- end
211
-
212
204
  def job_cancelled?
213
205
  @current_job.task_checkpoint if @current_job
214
206
  end
215
- alias_method :task_checkpoint, :job_cancelled?
216
207
 
208
+ alias_method :task_checkpoint, :job_cancelled?
217
209
 
218
210
  def redis_options
219
211
  @redis_options ||= {}
220
212
  end
221
213
 
214
+ def redis_logger_level
215
+ @redis_logger_level || Logger::INFO
216
+ end
217
+
222
218
  def redis_options=(options)
223
219
  @redis_options = options
224
220
  end
@@ -252,6 +248,14 @@ module Bosh::Director
252
248
  threaded[:redis] ||= Redis.new(redis_options)
253
249
  end
254
250
 
251
+ def redis_logger=(logger)
252
+ if redis?
253
+ redis.client.logger = logger
254
+ else
255
+ redis_options[:logger] = logger
256
+ end
257
+ end
258
+
255
259
  def redis?
256
260
  !threaded[:redis].nil?
257
261
  end
@@ -346,6 +350,5 @@ module Bosh::Director
346
350
  def initialize(hash)
347
351
  @hash = hash
348
352
  end
349
-
350
353
  end
351
354
  end
@@ -1,12 +1,10 @@
1
+ require 'net/http'
2
+ require 'timeout'
3
+ require 'uri'
4
+
1
5
  module Bosh::Director
2
6
  module DownloadHelper
3
- require 'net/http'
4
- require 'timeout'
5
- require 'uri'
6
-
7
- ##
8
7
  # Downloads a remote file
9
- #
10
8
  # @param [String] resource Resource name to be logged
11
9
  # @param [String] remote_file Remote file to download
12
10
  # @param [String] local_file Local file to store the downloaded file
@@ -41,4 +39,4 @@ module Bosh::Director
41
39
  raise ResourceError, "Downloading remote #{resource} failed. Check task debug log for details."
42
40
  end
43
41
  end
44
- end
42
+ end
@@ -1,5 +1,3 @@
1
- # Copyright (c) 2009-2012 VMware, Inc.
2
-
3
1
  module Resque
4
2
  def redis
5
3
  Bosh::Director::Config.redis
@@ -7,15 +5,15 @@ module Resque
7
5
  end
8
6
 
9
7
  class Object
10
- def to_openstruct
11
- self
12
- end
8
+ def to_openstruct
9
+ self
10
+ end
13
11
  end
14
12
 
15
13
  class Array
16
- def to_openstruct
17
- map { |el| el.to_openstruct }
18
- end
14
+ def to_openstruct
15
+ map { |el| el.to_openstruct }
16
+ end
19
17
  end
20
18
 
21
19
  class Hash
@@ -30,35 +28,9 @@ class Hash
30
28
  self
31
29
  end
32
30
 
33
- def to_openstruct
34
- mapped = {}
35
- each { |key, value| mapped[key] = value.to_openstruct }
36
- OpenStruct.new(mapped)
37
- end
38
- end
39
-
40
- require "sequel/connection_pool/threaded"
41
-
42
- class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
43
-
44
- alias_method :acquire_original, :acquire
45
- alias_method :release_original, :release
46
-
47
- def acquire(thread)
48
- logger = Bosh::Director::Config.logger
49
- result = acquire_original(thread)
50
- if logger
51
- logger.debug("Acquired connection: #{@allocated[thread].object_id}")
52
- end
53
- result
54
- end
55
-
56
- def release(thread)
57
- logger = Bosh::Director::Config.logger
58
- if logger
59
- logger.debug("Released connection: #{@allocated[thread].object_id}")
60
- end
61
- release_original(thread)
31
+ def to_openstruct
32
+ mapped = {}
33
+ each { |key, value| mapped[key] = value.to_openstruct }
34
+ OpenStruct.new(mapped)
62
35
  end
63
-
64
36
  end
@@ -53,7 +53,9 @@ module Bosh::Director
53
53
  event_log = File.join(log_dir, 'event')
54
54
  result_log = File.join(log_dir, 'result')
55
55
 
56
- @task_logger = MonoLogger.new(debug_log)
56
+ debug_log_device = MonoLogger::LocklessLogDevice.new(debug_log)
57
+
58
+ @task_logger = MonoLogger.new(debug_log_device)
57
59
  @task_logger.level = Config.logger.level
58
60
  @task_logger.formatter = ThreadFormatter.new
59
61
 
@@ -61,6 +63,11 @@ module Bosh::Director
61
63
  Config.result = TaskResultFile.new(result_log)
62
64
  Config.logger = @task_logger
63
65
 
66
+ redis_task_logger = MonoLogger.new(debug_log_device)
67
+ redis_task_logger.level = Config.redis_logger_level
68
+ redis_task_logger.formatter = ThreadFormatter.new
69
+ Config.redis_logger = redis_task_logger
70
+
64
71
  Config.db.logger = @task_logger
65
72
 
66
73
  if Config.dns_enabled?
@@ -10,14 +10,13 @@ module Bosh::Director
10
10
  :import_compiled_packages
11
11
  end
12
12
 
13
- def initialize(export_dir)
14
- @export_dir = export_dir
15
-
13
+ def initialize(compiled_packages_path)
14
+ @compiled_packages_path = compiled_packages_path
16
15
  @blobstore_client = Bosh::Director::App.instance.blobstores.blobstore
17
16
  end
18
17
 
19
18
  def perform
20
- export = Bosh::Director::CompiledPackage::CompiledPackagesExport.new(file: export_path)
19
+ export = Bosh::Director::CompiledPackage::CompiledPackagesExport.new(file: @compiled_packages_path)
21
20
 
22
21
  export.extract do |manifest, packages|
23
22
  release_name = manifest.fetch('release_name')
@@ -38,17 +37,8 @@ module Bosh::Director
38
37
  end
39
38
  end
40
39
  ensure
41
- FileUtils.rm_rf(@export_dir)
40
+ FileUtils.rm_rf(@compiled_packages_path)
42
41
  end
43
-
44
- private
45
-
46
- def export_path
47
- File.join(@export_dir, 'compiled_packages_export.tgz')
48
- end
49
-
50
- attr_reader :blobstore_client
51
- attr_reader :export_dir
52
42
  end
53
43
  end
54
44
  end
@@ -1,5 +1,4 @@
1
- # Copyright (c) 2009-2012 VMware, Inc.
2
-
1
+ require 'securerandom'
3
2
  require 'common/version/release_version'
4
3
 
5
4
  module Bosh::Director
@@ -11,20 +10,27 @@ module Bosh::Director
11
10
  @queue = :normal
12
11
 
13
12
  attr_accessor :release_model
14
- attr_accessor :tmp_release_dir
15
13
 
16
14
  def self.job_type
17
15
  :update_release
18
16
  end
19
17
 
20
- # @param [String] tmp_release_dir Directory containing release bundle
18
+ # @param [String] release_path local path or remote url of the release archive
21
19
  # @param [Hash] options Release update options
22
- def initialize(tmp_release_dir, options = {})
23
- @tmp_release_dir = tmp_release_dir
20
+ def initialize(release_path, options = {})
21
+ if options['remote']
22
+ # file will be downloaded to the release_path
23
+ @release_path = File.join(Dir.tmpdir, "release-#{SecureRandom.uuid}")
24
+ @release_url = release_path
25
+ else
26
+ # file already exists at the release_path
27
+ @release_path = release_path
28
+ end
29
+
24
30
  @release_model = nil
25
31
  @release_version_model = nil
26
32
 
27
- @rebase = !!options["rebase"]
33
+ @rebase = !!options['rebase']
28
34
 
29
35
  @manifest = nil
30
36
  @name = nil
@@ -32,68 +38,62 @@ module Bosh::Director
32
38
 
33
39
  @packages_unchanged = false
34
40
  @jobs_unchanged = false
35
-
36
- @remote_release = options['remote'] || false
37
- @remote_release_location = options['location'] if @remote_release
38
41
  end
39
42
 
40
- # Extracts release tarball, verifies release manifest and saves release
41
- # in DB
43
+ # Extracts release tarball, verifies release manifest and saves release in DB
42
44
  # @return [void]
43
45
  def perform
44
46
  logger.info("Processing update release")
45
- if @rebase
46
- logger.info("Release rebase will be performed")
47
- end
47
+ logger.info("Release rebase will be performed") if @rebase
48
+
49
+ single_step_stage("Downloading remote release") { download_remote_release } if @release_url
48
50
 
49
- single_step_stage("Downloading remote release") { download_remote_release } if @remote_release
50
- single_step_stage("Extracting release") { extract_release }
51
- single_step_stage("Verifying manifest") { verify_manifest }
51
+ release_dir = nil
52
+ single_step_stage("Extracting release") { release_dir = extract_release }
52
53
 
53
- with_release_lock(@name) { process_release }
54
+ single_step_stage("Verifying manifest") { verify_manifest(release_dir) }
55
+
56
+ with_release_lock(@name) { process_release(release_dir) }
54
57
 
55
58
  if @rebase && @packages_unchanged && @jobs_unchanged
56
- raise DirectorError,
57
- "Rebase is attempted without any job or package changes"
59
+ raise DirectorError, "Rebase is attempted without any job or package changes"
58
60
  end
59
61
 
60
62
  "Created release `#{@name}/#{@version}'"
63
+
61
64
  rescue Exception => e
62
65
  remove_release_version_model
63
66
  raise e
67
+
64
68
  ensure
65
- if @tmp_release_dir && File.exists?(@tmp_release_dir)
66
- FileUtils.rm_rf(@tmp_release_dir)
67
- end
69
+ FileUtils.rm_rf(release_dir) if release_dir
70
+ FileUtils.rm_rf(@release_path) if @release_path
68
71
  end
69
72
 
70
73
  def download_remote_release
71
- release_file = File.join(@tmp_release_dir, Api::ReleaseManager::RELEASE_TGZ)
72
- download_remote_file('release', @remote_release_location, release_file)
74
+ download_remote_file('release', @release_url, @release_path)
73
75
  end
74
76
 
75
77
  # Extracts release tarball
76
78
  # @return [void]
77
79
  def extract_release
78
- release_tgz = File.join(@tmp_release_dir,
79
- Api::ReleaseManager::RELEASE_TGZ)
80
+ release_dir = Dir.mktmpdir
80
81
 
81
- result = Bosh::Exec.sh("tar -C #{@tmp_release_dir} -xzf #{release_tgz} 2>&1", :on_error => :return)
82
+ result = Bosh::Exec.sh("tar -C #{release_dir} -xzf #{@release_path} 2>&1", :on_error => :return)
82
83
  if result.failed?
83
- logger.error("Extracting release archive failed in dir #{@tmp_release_dir}, " +
84
+ logger.error("Failed to extract release archive '#{@release_path}' into dir '#{release_dir}', " +
84
85
  "tar returned #{result.exit_status}, " +
85
86
  "output: #{result.output}")
86
87
  raise ReleaseInvalidArchive, "Extracting release archive failed. Check task debug log for details."
87
88
  end
88
- ensure
89
- if release_tgz && File.exists?(release_tgz)
90
- FileUtils.rm(release_tgz)
91
- end
89
+
90
+ release_dir
92
91
  end
93
92
 
93
+ # @param [String] release_dir local path to the unpacked release
94
94
  # @return [void]
95
- def verify_manifest
96
- manifest_file = File.join(@tmp_release_dir, "release.MF")
95
+ def verify_manifest(release_dir)
96
+ manifest_file = File.join(release_dir, "release.MF")
97
97
  unless File.file?(manifest_file)
98
98
  raise ReleaseManifestNotFound, "Release manifest not found"
99
99
  end
@@ -117,8 +117,9 @@ module Bosh::Director
117
117
  end
118
118
 
119
119
  # Processes uploaded release, creates jobs and packages in DB if needed
120
+ # @param [String] release_dir local path to the unpacked release
120
121
  # @return [void]
121
- def process_release
122
+ def process_release(release_dir)
122
123
  @release_model = Models::Release.find_or_create(:name => @name)
123
124
 
124
125
  if @rebase
@@ -150,8 +151,8 @@ module Bosh::Director
150
151
  end
151
152
 
152
153
  @packages = {}
153
- process_packages
154
- process_jobs
154
+ process_packages(release_dir)
155
+ process_jobs(release_dir)
155
156
 
156
157
  event_log.begin_stage("Release has been created", 1)
157
158
  event_log.track("#{@name}/#{@version}") {}
@@ -197,8 +198,9 @@ module Bosh::Director
197
198
  # Finds all package definitions in the manifest and sorts them into two
198
199
  # buckets: new and existing packages, then creates new packages and points
199
200
  # current release version to the existing packages.
201
+ # @param [String] release_dir local path to the unpacked release
200
202
  # @return [void]
201
- def process_packages
203
+ def process_packages(release_dir)
202
204
  logger.info("Checking for new packages in release")
203
205
 
204
206
  new_packages = []
@@ -232,14 +234,15 @@ module Bosh::Director
232
234
  end
233
235
  end
234
236
 
235
- create_packages(new_packages)
237
+ create_packages(new_packages, release_dir)
236
238
  use_existing_packages(existing_packages)
237
239
  end
238
240
 
239
241
  # Creates packages using provided metadata
240
242
  # @param [Array<Hash>] packages Packages metadata
243
+ # @param [String] release_dir local path to the unpacked release
241
244
  # @return [void]
242
- def create_packages(packages)
245
+ def create_packages(packages, release_dir)
243
246
  if packages.empty?
244
247
  @packages_unchanged = true
245
248
  return
@@ -250,7 +253,7 @@ module Bosh::Director
250
253
  package_desc = "#{package_meta["name"]}/#{package_meta["version"]}"
251
254
  event_log.track(package_desc) do
252
255
  logger.info("Creating new package `#{package_desc}'")
253
- package = create_package(package_meta)
256
+ package = create_package(package_meta, release_dir)
254
257
  register_package(package)
255
258
  end
256
259
  end
@@ -272,8 +275,9 @@ module Bosh::Director
272
275
 
273
276
  # Creates package in DB according to given metadata
274
277
  # @param [Hash] package_meta Package metadata
278
+ # @param [String] release_dir local path to the unpacked release
275
279
  # @return [void]
276
- def create_package(package_meta)
280
+ def create_package(package_meta, release_dir)
277
281
  name, version = package_meta["name"], package_meta["version"]
278
282
 
279
283
  package_attrs = {
@@ -296,7 +300,7 @@ module Bosh::Director
296
300
  else
297
301
  logger.info("Creating #{desc} from provided bits")
298
302
 
299
- package_tgz = File.join(@tmp_release_dir, "packages", "#{name}.tgz")
303
+ package_tgz = File.join(release_dir, "packages", "#{name}.tgz")
300
304
  result = Bosh::Exec.sh("tar -tzf #{package_tgz} 2>&1", :on_error => :return)
301
305
  if result.failed?
302
306
  logger.error("Extracting #{desc} archive failed, " +
@@ -322,8 +326,9 @@ module Bosh::Director
322
326
  # Finds job template definitions in release manifest and sorts them into
323
327
  # two buckets: new and existing job templates, then creates new job
324
328
  # template records in the database and points release version to existing ones.
329
+ # @param [String] release_dir local path to the unpacked release
325
330
  # @return [void]
326
- def process_jobs
331
+ def process_jobs(release_dir)
327
332
  logger.info("Checking for new jobs in release")
328
333
 
329
334
  new_jobs = []
@@ -346,11 +351,11 @@ module Bosh::Director
346
351
  end
347
352
  end
348
353
 
349
- create_jobs(new_jobs)
354
+ create_jobs(new_jobs, release_dir)
350
355
  use_existing_jobs(existing_jobs)
351
356
  end
352
357
 
353
- def create_jobs(jobs)
358
+ def create_jobs(jobs, release_dir)
354
359
  if jobs.empty?
355
360
  @jobs_unchanged = true
356
361
  return
@@ -361,13 +366,13 @@ module Bosh::Director
361
366
  job_desc = "#{job_meta["name"]}/#{job_meta["version"]}"
362
367
  event_log.track(job_desc) do
363
368
  logger.info("Creating new template `#{job_desc}'")
364
- template = create_job(job_meta)
369
+ template = create_job(job_meta, release_dir)
365
370
  register_template(template)
366
371
  end
367
372
  end
368
373
  end
369
374
 
370
- def create_job(job_meta)
375
+ def create_job(job_meta, release_dir)
371
376
  name, version = job_meta["name"], job_meta["version"]
372
377
 
373
378
  template_attrs = {
@@ -382,8 +387,8 @@ module Bosh::Director
382
387
  "from provided bits")
383
388
  template = Models::Template.new(template_attrs)
384
389
 
385
- job_tgz = File.join(@tmp_release_dir, "jobs", "#{name}.tgz")
386
- job_dir = File.join(@tmp_release_dir, "jobs", "#{name}")
390
+ job_tgz = File.join(release_dir, "jobs", "#{name}.tgz")
391
+ job_dir = File.join(release_dir, "jobs", "#{name}")
387
392
 
388
393
  FileUtils.mkdir_p(job_dir)
389
394
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2009-2012 VMware, Inc.
1
+ require 'securerandom'
2
2
 
3
3
  module Bosh::Director
4
4
  module Jobs
@@ -14,27 +14,33 @@ module Bosh::Director
14
14
  :update_stemcell
15
15
  end
16
16
 
17
- # @param [String] stemcell_file Stemcell tarball path
18
- def initialize(stemcell_file, options = {})
19
- @stemcell_file = stemcell_file
17
+ # @param [String] stemcell_path local path or remote url of the stemcell archive
18
+ # @param [Hash] options Stemcell update options
19
+ def initialize(stemcell_path, options = {})
20
+ if options['remote']
21
+ # file will be downloaded to the stemcell_path
22
+ @stemcell_path = File.join(Dir.tmpdir, "stemcell-#{SecureRandom.uuid}")
23
+ @stemcell_url = stemcell_path
24
+ else
25
+ # file already exists at the stemcell_path
26
+ @stemcell_path = stemcell_path
27
+ end
28
+
20
29
  @cloud = Config.cloud
21
30
  @stemcell_manager = Api::StemcellManager.new
22
- @remote_stemcell = options['remote'] || false
23
31
  end
24
32
 
25
33
  def perform
26
34
  logger.info("Processing update stemcell")
27
- event_log.begin_stage("Update stemcell", update_steps)
28
35
 
29
- if @remote_stemcell
30
- downloaded_stemcell_dir = Dir.mktmpdir("downloaded-stemcell")
31
- download_remote_stemcell(downloaded_stemcell_dir)
32
- end
33
-
36
+ event_log.begin_stage("Update stemcell", @stemcell_url ? UPDATE_STEPS + 1 : UPDATE_STEPS)
37
+
38
+ track_and_log("Downloading remote stemcell") { download_remote_stemcell } if @stemcell_url
39
+
34
40
  stemcell_dir = Dir.mktmpdir("stemcell")
35
41
 
36
42
  track_and_log("Extracting stemcell archive") do
37
- result = Bosh::Exec.sh("tar -C #{stemcell_dir} -xzf #{@stemcell_file} 2>&1", :on_error => :return)
43
+ result = Bosh::Exec.sh("tar -C #{stemcell_dir} -xzf #{@stemcell_path} 2>&1", :on_error => :return)
38
44
  if result.failed?
39
45
  logger.error("Extracting stemcell archive failed in dir #{stemcell_dir}, " +
40
46
  "tar returned #{result.exit_status}, " +
@@ -75,8 +81,7 @@ module Bosh::Director
75
81
  stemcell.sha1 = @sha1
76
82
 
77
83
  track_and_log("Uploading stemcell #{@name}/#{@version} to the cloud") do
78
- stemcell.cid =
79
- @cloud.create_stemcell(@stemcell_image, @cloud_properties)
84
+ stemcell.cid = @cloud.create_stemcell(@stemcell_image, @cloud_properties)
80
85
  logger.info("Cloud created stemcell: #{stemcell.cid}")
81
86
  end
82
87
 
@@ -87,22 +92,13 @@ module Bosh::Director
87
92
  "/stemcells/#{stemcell.name}/#{stemcell.version}"
88
93
  ensure
89
94
  FileUtils.rm_rf(stemcell_dir) if stemcell_dir
90
- FileUtils.rm_rf(downloaded_stemcell_dir) if downloaded_stemcell_dir
91
- FileUtils.rm_rf(@stemcell_file) if @stemcell_file
92
- end
93
-
94
- def download_remote_stemcell(downloaded_stemcell_dir)
95
- track_and_log("Downloading remote stemcell") do
96
- downloaded_stemcell_file = File.join(downloaded_stemcell_dir, "stemcell-#{SecureRandom.uuid}")
97
- download_remote_file('stemcell', @stemcell_file, downloaded_stemcell_file)
98
- @stemcell_file = downloaded_stemcell_file
99
- end
95
+ FileUtils.rm_rf(@stemcell_path) if @stemcell_path
100
96
  end
101
97
 
102
98
  private
103
-
104
- def update_steps
105
- @remote_stemcell ? UPDATE_STEPS + 1 : UPDATE_STEPS
99
+
100
+ def download_remote_stemcell
101
+ download_remote_file('stemcell', @stemcell_url, @stemcell_path)
106
102
  end
107
103
  end
108
104
  end
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Director
3
- VERSION = '1.2641.0'
3
+ VERSION = '1.2652.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh-director
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2641.0
4
+ version: 1.2652.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VMware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-11 00:00:00.000000000 Z
11
+ date: 2014-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcrypt-ruby
@@ -30,126 +30,126 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.2641.0
33
+ version: 1.2652.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.2641.0
40
+ version: 1.2652.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bosh-core
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.2641.0
47
+ version: 1.2652.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.2641.0
54
+ version: 1.2652.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bosh-director-core
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.2641.0
61
+ version: 1.2652.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.2641.0
68
+ version: 1.2652.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bosh_common
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.2641.0
75
+ version: 1.2652.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.2641.0
82
+ version: 1.2652.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: bosh_cpi
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 1.2641.0
89
+ version: 1.2652.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 1.2641.0
96
+ version: 1.2652.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: bosh_openstack_cpi
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.2641.0
103
+ version: 1.2652.0
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.2641.0
110
+ version: 1.2652.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: bosh_aws_cpi
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 1.2641.0
117
+ version: 1.2652.0
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 1.2641.0
124
+ version: 1.2652.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: bosh_vsphere_cpi
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 1.2641.0
131
+ version: 1.2652.0
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 1.2641.0
138
+ version: 1.2652.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: bosh_warden_cpi
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 1.2641.0
145
+ version: 1.2652.0
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 1.2641.0
152
+ version: 1.2652.0
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: bosh_vcloud_cpi
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -446,7 +446,7 @@ dependencies:
446
446
  version: '0'
447
447
  description: |-
448
448
  BOSH Director
449
- 23fe6f
449
+ 43d2e8
450
450
  email: support@cloudfoundry.com
451
451
  executables:
452
452
  - bosh-director
@@ -502,6 +502,7 @@ files:
502
502
  - lib/bosh/director/api.rb
503
503
  - lib/bosh/director/api/api_helper.rb
504
504
  - lib/bosh/director/api/backup_manager.rb
505
+ - lib/bosh/director/api/compiled_package_group_manager.rb
505
506
  - lib/bosh/director/api/controller.rb
506
507
  - lib/bosh/director/api/controller_helpers.rb
507
508
  - lib/bosh/director/api/controllers/backups_controller.rb