app/controllers/runtime/restages_controller.rb
require 'actions/v2/app_stage'
require 'actions/staging_cancel'
require 'controllers/runtime/mixins/find_process_through_app'
module VCAP::CloudController
class RestagesController < RestController::ModelController
include FindProcessThroughApp
def self.dependencies
%i[app_event_repository stagers]
end
path_base 'apps'
model_class_name :ProcessModel
self.not_found_exception_name = 'AppNotFound'
def inject_dependencies(dependencies)
super
@app_event_repository = dependencies.fetch(:app_event_repository)
@stagers = dependencies.fetch(:stagers)
end
post "#{path_guid}/restage", :restage
def restage(guid)
process = find_guid_and_validate_access(:read_for_update, guid)
validate_process!(process)
model.db.transaction do
process.app.lock!
process.lock!
V2::AppStop.stop(process.app, StagingCancel.new(@stagers))
process.app.update(droplet_guid: nil)
AppStart.start_without_event(process.app, create_revision: false)
end
V2::AppStage.new(stagers: @stagers).stage(process)
@app_event_repository.record_app_restage(process, UserAuditInfo.from_context(SecurityContext))
TelemetryLogger.v2_emit(
'restage-app',
{
'app-id' => process.app_guid,
'user-id' => current_user.guid
}, {
'lifecycle' => process.app.lifecycle_type,
'buildpacks' => process.app.lifecycle_data.buildpacks,
'stack' => process.app.lifecycle_data.stack
}
)
[
HTTP::CREATED,
{ 'Location' => "#{self.class.path}/#{process.guid}" },
object_renderer.render_json(self.class, process, @opts)
]
rescue AppStart::InvalidApp => e
raise CloudController::Errors::ApiError.new_from_details('DockerDisabled') if e.message.match?(/docker_disabled/)
raise CloudController::Errors::ApiError.new_from_details('StagingError', e.message)
rescue AppStop::InvalidApp => e
raise CloudController::Errors::ApiError.new_from_details('StagingError', e.message)
end
private
def validate_process!(process)
raise CloudController::Errors::ApiError.new_from_details('AppNotFound', process.guid) unless process.web?
raise CloudController::Errors::ApiError.new_from_details('StagingError', 'App must have at least 1 instance to stage.') if process.instances < 1
raise CloudController::Errors::ApiError.new_from_details('NotStaged') if process.pending?
return unless process.latest_package.nil?
raise CloudController::Errors::ApiError.new_from_details('AppPackageInvalid', 'bits have not been uploaded')
end
end
end