Includes the addition of a global cloud controller route,
`/info/runtimes', which responds with all runtime information from the
DEAs. Also includes some renovations for how we store app metadata.

Change-Id: I11b076b6c53b962acfa58407b7ebe857060bb08a
This commit is contained in:
Alex Suraci 2011-07-12 17:50:26 -07:00
Родитель 6d3f1529cc
Коммит 7867815b2d
11 изменённых файлов: 96 добавлений и 23 удалений

Просмотреть файл

@ -225,6 +225,13 @@ class AppsController < ApplicationController
changed = app.changed
CloudController.logger.debug "app: #{app.id} Updating #{changed.inspect}"
# reject attempts to start in debug mode if debugging is disabled
if body_params[:debug] and app.state == 'STARTED' and !AppConfig[:allow_debug]
raise CloudError.new(CloudError::APP_DEBUG_DISALLOWED)
end
app.metadata[:debug] = body_params[:debug] if body_params
# 'app.save' can actually raise an exception, if whatever is
# invalid happens all the way down at the DB layer.
begin

Просмотреть файл

@ -19,6 +19,10 @@ class DefaultController < ApplicationController
render :json => info
end
def runtime_info
render :json => AppConfig[:runtimes]
end
def service_info
svcs = Service.active_services.select {|svc| svc.visible_to_user?(user)}
CloudController.logger.debug("Global service listing found #{svcs.length} services.")

Просмотреть файл

@ -12,6 +12,10 @@ class App < ActiveRecord::Base
before_validation :normalize_legacy_staging_strings!
serialize :metadata, Hash
after_initialize :set_defaults
after_create :add_owner_as_collaborator
scope :started, lambda { where("apps.state = ?", 'STARTED') }
@ -78,6 +82,10 @@ class App < ActiveRecord::Base
result
end
def set_defaults
self.metadata ||= {}
end
def total_memory
instances * memory
end
@ -93,7 +101,11 @@ class App < ActiveRecord::Base
:services => bound_services,
:version => generate_version,
:env => environment,
:meta => {:version => lock_version, :created => Time.now.to_i} }
:meta => metadata.merge({
:version => lock_version,
:created => Time.now.to_i
})
}
end
# Called by AppManager when staging this app.
@ -338,16 +350,6 @@ class App < ActiveRecord::Base
end
end
def metadata
json = read_attribute(:metadata_json)
return {} if json.blank?
Yajl::Parser.parse(json, :symbolize_keys => true)
end
def metadata=(hash)
write_attribute(:metadata_json, Yajl::Encoder.encode(hash))
end
def environment
json_crypt = read_attribute(:environment_json)
return [] if json_crypt.blank?

Просмотреть файл

@ -191,6 +191,7 @@ class AppManager
f = Fiber.new do
message = start_message.dup
message[:executableUri] = download_app_uri(message[:executableUri])
message[:debug] = @app.metadata[:debug]
(index...max_to_start).each do |i|
message[:index] = i
dea_id = find_dea_for(message)
@ -323,8 +324,8 @@ class AppManager
raise e # re-raise here to propogate to the API call.
end
# Returns an array of hashes containing 'index', 'state', and 'since'(timestamp)
# for all instances running, or trying to run, the app.
# Returns an array of hashes containing 'index', 'state', 'since'(timestamp),
# and 'debug_port' for all instances running, or trying to run, the app.
def find_instances
return [] unless app.started?
instances = app.instances
@ -370,7 +371,8 @@ class AppManager
indices[index] = {
:index => index,
:state => instance_json[:state],
:since => instance_json[:state_timestamp]
:since => instance_json[:state_timestamp],
:debug_port => instance_json[:debug_port]
}
end
end

Просмотреть файл

@ -81,6 +81,8 @@ staging:
max_staging_runtime: 120 # secs
secure: false
allow_debug: false
# admin support
admins: [derek@gmail.com, foobar@vmware.com]
https_required: false
@ -105,3 +107,19 @@ builtin_services:
token: "0xdeadbeef"
rabbitmq:
token: "0xdeadbeef"
# used for /info/runtimes endpoint (served unfiltered as JSON)
runtimes:
ruby18:
version: 1.8.7
ruby19:
version: 1.9.2
node:
version: 0.4.[2-9]
java:
version: 1.6.0
debug_modes:
- run
- wait
erlangR14B02:
version: ".* 5.8.3"

Просмотреть файл

@ -4,6 +4,7 @@
CloudController::Application.routes.draw do
get 'info' => 'default#info', :as => :cloud_info
get 'info/services' => 'default#service_info', :as => :cloud_service_info
get 'info/runtimes' => 'default#runtime_info', :as => :cloud_runtime_info
get 'users' => 'users#list', :as => :list_users
post 'users' => 'users#create', :as => :create_user
get 'users/*email' => 'users#info', :as => :user_info

Просмотреть файл

@ -0,0 +1,9 @@
class RenameAppMetadataJsonToMetadata < ActiveRecord::Migration
def self.up
rename_column :apps, :metadata_json, :metadata
end
def self.down
rename_column :apps, :metadata, :metadata_json
end
end

Просмотреть файл

@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20110521014004) do
ActiveRecord::Schema.define(:version => 20110707170643) do
create_table "app_collaborations", :force => true do |t|
t.integer "app_id"
@ -32,7 +32,7 @@ ActiveRecord::Schema.define(:version => 20110521014004) do
t.string "package_state", :default => "PENDING"
t.string "package_hash"
t.text "environment_json"
t.text "metadata_json"
t.text "metadata"
t.boolean "external_secret", :default => false
t.datetime "created_at"
t.datetime "updated_at"

Просмотреть файл

@ -39,6 +39,7 @@ class CloudError < StandardError
APP_FILE_ERROR = [306, HTTP_INTERNAL_SERVER_ERROR, "Error retrieving file '%s'"]
APP_INVALID_RUNTIME = [307, HTTP_BAD_REQUEST, "Invalid runtime specification [%s] for framework: '%s'"]
APP_INVALID_FRAMEWORK = [308, HTTP_BAD_REQUEST, "Invalid framework description: '%s'"]
APP_DEBUG_DISALLOWED = [309, HTTP_BAD_REQUEST, "Cloud controller has disallowed debugging."]
# Bits
RESOURCES_UNKNOWN_PACKAGE_TYPE = [400, HTTP_BAD_REQUEST, "Unknown package type requested: \"%\""]

Просмотреть файл

@ -43,6 +43,11 @@ runtimes:
version: 1.6.0
version_flag: '-version'
environment:
debug_env:
run:
- JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=$VCAP_DEBUG_PORT,server=y,suspend=n"
wait:
- JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=$VCAP_DEBUG_PORT,server=y,suspend=y"
php:
executable: php
version: 5.3.[2-6]

Просмотреть файл

@ -399,7 +399,8 @@ module DEA
:state_timestamp => instance[:state_timestamp],
:file_uri => "http://#{@local_ip}:#{@file_viewer_port}/droplets/",
:credentials => @file_auth,
:staged => instance[:staged]
:staged => instance[:staged],
:debug_port => instance[:debug_port]
}
if include_stats && instance[:state] == :RUNNING
response[:stats] = {
@ -494,6 +495,7 @@ module DEA
users = message_json['users']
runtime = message_json['runtime']
framework = message_json['framework']
debug = message_json['debug']
# Limits processing
mem = DEFAULT_APP_MEM
@ -560,16 +562,26 @@ module DEA
end
start_operation = proc do
port = VCAP.grab_ephemeral_port
@logger.debug('Completed download')
@logger.info("Starting up instance #{instance[:log_id]} on port:#{port}")
port = VCAP.grab_ephemeral_port
instance[:port] = port
starting = "Starting up instance #{instance[:log_id]} on port:#{port}"
if debug
debug_port = VCAP.grab_ephemeral_port
instance[:debug_port] = debug_port
instance[:debug_mode] = debug
@logger.info("#{starting} with debugger:#{debug_port}")
else
@logger.info(starting)
end
@logger.debug("Clients: #{@num_clients}")
@logger.debug("Reserved Memory Usage: #{@reserved_mem} MB of #{@max_memory} MB TOTAL")
instance[:port] = port
manifest_file = File.join(instance[:dir], 'droplet.yaml')
manifest = {}
manifest = File.open(manifest_file) { |f| YAML.load(f) } if File.file?(manifest_file)
@ -856,7 +868,7 @@ module DEA
if state && state['state'] == 'RUNNING'
block.call(true)
timer.cancel
else
elsif instance[:debug_mode] != "wait"
attempts += 1
if attempts > 600 || instance[:state] != :STARTING # 5 minutes or instance was stopped
block.call(false)
@ -1048,6 +1060,12 @@ module DEA
env_hash.to_json
end
def debug_env(instance)
return unless instance[:debug_port]
return unless envs = @runtimes[instance[:runtime]]['debug_env']
envs[instance[:debug_mode]]
end
def setup_instance_env(instance, app_env, services)
env = []
@ -1056,6 +1074,12 @@ module DEA
env << "VCAP_SERVICES='#{create_services_for_env(services)}'"
env << "VCAP_APP_HOST='#{@local_ip}'"
env << "VCAP_APP_PORT='#{instance[:port]}'"
env << "VCAP_DEBUG_PORT='#{instance[:debug_port]}'"
if vars = debug_env(instance)
@logger.info("Debugger environment variables: #{vars.inspect}")
env += vars
end
# LEGACY STUFF
env << "VMC_WARNING_WARNING='All VMC_* environment variables are deprecated, please use VCAP_* versions.'"