Skip to content
This repository has been archived by the owner on Jan 26, 2022. It is now read-only.

Commit

Permalink
Add standalone framework
Browse files Browse the repository at this point in the history
- Add new standalone framework

- Allow users to choose runtime from
list if framework is standalone

- Allow default runtime to be specified
by framework

- Pass start command to server
on app creation

- Allow default memory to be specified by
runtime/framework combo

- Support pushing a single file, including
unpack and repack of zip and WAR

- Allow "None" as URL choice for standalone
apps

Change-Id: Icdc1ae9098a9365e3ec26b3bf2e5f215437a56a1
  • Loading branch information
Jennifer Hickey committed Mar 28, 2012
1 parent b627c98 commit df63c09
Show file tree
Hide file tree
Showing 8 changed files with 611 additions and 162 deletions.
2 changes: 2 additions & 0 deletions Rakefile
Expand Up @@ -30,6 +30,8 @@ TESTS_TO_BUILD = ["#{TESTS_PATH}/java_web/java_tiny_app",
"#{TESTS_PATH}/lift/hello_lift", "#{TESTS_PATH}/lift/hello_lift",
"#{TESTS_PATH}/spring/roo-guestbook", "#{TESTS_PATH}/spring/roo-guestbook",
"#{TESTS_PATH}/spring/spring-osgi-hello", "#{TESTS_PATH}/spring/spring-osgi-hello",
"#{TESTS_PATH}/standalone/java_app",
"#{TESTS_PATH}/standalone/python_app"
] ]


desc "Build the tests. If the git hash associated with the test assets has not changed, nothing is built. To force a build, invoke 'rake build[--force]'" desc "Build the tests. If the git hash associated with the test assets has not changed, nothing is built. To force a build, invoke 'rake build[--force]'"
Expand Down
217 changes: 120 additions & 97 deletions lib/cli/commands/apps.rb
Expand Up @@ -371,7 +371,6 @@ def app_exists?(appname)


def check_deploy_directory(path) def check_deploy_directory(path)
err 'Deployment path does not exist' unless File.exists? path err 'Deployment path does not exist' unless File.exists? path
err 'Deployment path is not a directory' unless File.directory? path
return if File.expand_path(Dir.tmpdir) != File.expand_path(path) return if File.expand_path(Dir.tmpdir) != File.expand_path(path)
err "Can't deploy applications from staging directory: [#{Dir.tmpdir}]" err "Can't deploy applications from staging directory: [#{Dir.tmpdir}]"
end end
Expand Down Expand Up @@ -410,101 +409,112 @@ def upload_app_bits(appname, path)
explode_dir = "#{Dir.tmpdir}/.vmc_#{appname}_files" explode_dir = "#{Dir.tmpdir}/.vmc_#{appname}_files"
FileUtils.rm_rf(explode_dir) # Make sure we didn't have anything left over.. FileUtils.rm_rf(explode_dir) # Make sure we didn't have anything left over..


Dir.chdir(path) do if path =~ /\.(war|zip)$/
# Stage the app appropriately and do the appropriate fingerprinting, etc. #single file that needs unpacking
if war_file = Dir.glob('*.war').first VMC::Cli::ZipUtil.unpack(path, explode_dir)
VMC::Cli::ZipUtil.unpack(war_file, explode_dir) elsif !File.directory? path
else #single file that doesn't need unpacking
check_unreachable_links(path) FileUtils.mkdir(explode_dir)
FileUtils.mkdir(explode_dir) FileUtils.cp(path,explode_dir)
else
Dir.chdir(path) do
# Stage the app appropriately and do the appropriate fingerprinting, etc.
if war_file = Dir.glob('*.war').first
VMC::Cli::ZipUtil.unpack(war_file, explode_dir)
elsif zip_file = Dir.glob('*.zip').first
VMC::Cli::ZipUtil.unpack(zip_file, explode_dir)
else
check_unreachable_links(path)
FileUtils.mkdir(explode_dir)


files = Dir.glob('{*,.[^\.]*}') files = Dir.glob('{*,.[^\.]*}')


# Do not process .git files # Do not process .git files
files.delete('.git') if files files.delete('.git') if files


FileUtils.cp_r(files, explode_dir) FileUtils.cp_r(files, explode_dir)


find_sockets(explode_dir).each do |s| find_sockets(explode_dir).each do |s|
File.delete s File.delete s
end
end end
end end
end


# Send the resource list to the cloudcontroller, the response will tell us what it already has.. # Send the resource list to the cloudcontroller, the response will tell us what it already has..
unless @options[:noresources] unless @options[:noresources]
display ' Checking for available resources: ', false display ' Checking for available resources: ', false
fingerprints = [] fingerprints = []
total_size = 0 total_size = 0
resource_files = Dir.glob("#{explode_dir}/**/*", File::FNM_DOTMATCH) resource_files = Dir.glob("#{explode_dir}/**/*", File::FNM_DOTMATCH)
resource_files.each do |filename| resource_files.each do |filename|
next if (File.directory?(filename) || !File.exists?(filename)) next if (File.directory?(filename) || !File.exists?(filename))
fingerprints << { fingerprints << {
:size => File.size(filename), :size => File.size(filename),
:sha1 => Digest::SHA1.file(filename).hexdigest, :sha1 => Digest::SHA1.file(filename).hexdigest,
:fn => filename :fn => filename
} }
total_size += File.size(filename) total_size += File.size(filename)
end end

# Check to see if the resource check is worth the round trip
if (total_size > (64*1024)) # 64k for now
# Send resource fingerprints to the cloud controller
appcloud_resources = client.check_resources(fingerprints)
end
display 'OK'.green

if appcloud_resources
display ' Processing resources: ', false
# We can then delete what we do not need to send.
appcloud_resources.each do |resource|
FileUtils.rm_f resource[:fn]
# adjust filenames sans the explode_dir prefix
resource[:fn].sub!("#{explode_dir}/", '')
end
display 'OK'.green
end


# Check to see if the resource check is worth the round trip
if (total_size > (64*1024)) # 64k for now
# Send resource fingerprints to the cloud controller
appcloud_resources = client.check_resources(fingerprints)
end end
display 'OK'.green


# If no resource needs to be sent, add an empty file to ensure we have if appcloud_resources
# a multi-part request that is expected by nginx fronting the CC. display ' Processing resources: ', false
if VMC::Cli::ZipUtil.get_files_to_pack(explode_dir).empty? # We can then delete what we do not need to send.
Dir.chdir(explode_dir) do appcloud_resources.each do |resource|
File.new(".__empty__", "w") FileUtils.rm_f resource[:fn]
# adjust filenames sans the explode_dir prefix
resource[:fn].sub!("#{explode_dir}/", '')
end end
display 'OK'.green
end end
# Perform Packing of the upload bits here.
display ' Packing application: ', false
VMC::Cli::ZipUtil.pack(explode_dir, upload_file)
display 'OK'.green


upload_size = File.size(upload_file); end
if upload_size > 1024*1024
upload_size = (upload_size/(1024.0*1024.0)).round.to_s + 'M' # If no resource needs to be sent, add an empty file to ensure we have
elsif upload_size > 0 # a multi-part request that is expected by nginx fronting the CC.
upload_size = (upload_size/1024.0).round.to_s + 'K' if VMC::Cli::ZipUtil.get_files_to_pack(explode_dir).empty?
else Dir.chdir(explode_dir) do
upload_size = '0K' File.new(".__empty__", "w")
end end
end
# Perform Packing of the upload bits here.
display ' Packing application: ', false
VMC::Cli::ZipUtil.pack(explode_dir, upload_file)
display 'OK'.green


upload_str = " Uploading (#{upload_size}): " upload_size = File.size(upload_file);
display upload_str, false if upload_size > 1024*1024
upload_size = (upload_size/(1024.0*1024.0)).round.to_s + 'M'
elsif upload_size > 0
upload_size = (upload_size/1024.0).round.to_s + 'K'
else
upload_size = '0K'
end


FileWithPercentOutput.display_str = upload_str upload_str = " Uploading (#{upload_size}): "
FileWithPercentOutput.upload_size = File.size(upload_file); display upload_str, false
file = FileWithPercentOutput.open(upload_file, 'rb')


client.upload_app(appname, file, appcloud_resources) FileWithPercentOutput.display_str = upload_str
display 'OK'.green if VMC::Cli::ZipUtil.get_files_to_pack(explode_dir).empty? FileWithPercentOutput.upload_size = File.size(upload_file);
file = FileWithPercentOutput.open(upload_file, 'rb')


display 'Push Status: ', false client.upload_app(appname, file, appcloud_resources)
display 'OK'.green display 'OK'.green if VMC::Cli::ZipUtil.get_files_to_pack(explode_dir).empty?
end


ensure display 'Push Status: ', false
# Cleanup if we created an exploded directory. display 'OK'.green
FileUtils.rm_f(upload_file) if upload_file
FileUtils.rm_rf(explode_dir) if explode_dir ensure
# Cleanup if we created an exploded directory.
FileUtils.rm_f(upload_file) if upload_file
FileUtils.rm_rf(explode_dir) if explode_dir
end end


def check_app_limit def check_app_limit
Expand Down Expand Up @@ -908,6 +918,8 @@ def do_push(appname=nil)
url = info(:url) || info(:urls) url = info(:url) || info(:urls)
mem, memswitch = nil, info(:mem) mem, memswitch = nil, info(:mem)
memswitch = normalize_mem(memswitch) if memswitch memswitch = normalize_mem(memswitch) if memswitch
command = info(:command)
runtime = info(:runtime)


# Check app existing upfront if we have appname # Check app existing upfront if we have appname
app_checked = false app_checked = false
Expand All @@ -934,9 +946,30 @@ def do_push(appname=nil)
err "Application '#{appname}' already exists, use update or delete." err "Application '#{appname}' already exists, use update or delete."
end end


default_url = "#{appname}.#{target_base}" if ignore_framework
framework = VMC::Cli::Framework.new
elsif f = info(:framework)
info = Hash[f["info"].collect { |k, v| [k.to_sym, v] }]

framework = VMC::Cli::Framework.create(f["name"], info)
exec = framework.exec if framework && framework.exec
else
framework = detect_framework(prompt_ok)
end

err "Application Type undetermined for path '#{@application}'" unless framework

if not runtime
default_runtime = framework.default_runtime @application
runtime = detect_runtime(default_runtime, !no_prompt) if framework.prompt_for_runtime?
end
command = ask("Start Command") if !command && framework.require_start_command?

default_url = "None"
default_url = "#{appname}.#{VMC::Cli::Config.suggest_url}" if framework.require_url?



unless no_prompt || url unless no_prompt || url || !framework.require_url?
url = ask( url = ask(
"Application Deployed URL", "Application Deployed URL",
:default => default_url :default => default_url
Expand All @@ -947,29 +980,18 @@ def do_push(appname=nil)
# this common error # this common error
url = nil if YES_SET.member? url url = nil if YES_SET.member? url
end end

url = nil if url == "None"
default_url = nil if default_url == "None"
url ||= default_url url ||= default_url


if ignore_framework
framework = VMC::Cli::Framework.new
elsif f = info(:framework)
info = Hash[f["info"].collect { |k, v| [k.to_sym, v] }]

framework = VMC::Cli::Framework.new(f["name"], info)
exec = framework.exec if framework && framework.exec
else
framework = detect_framework(prompt_ok)
end

err "Application Type undetermined for path '#{@application}'" unless framework

if memswitch if memswitch
mem = memswitch mem = memswitch
elsif prompt_ok elsif prompt_ok
mem = ask("Memory Reservation", mem = ask("Memory Reservation",
:default => framework.memory, :choices => mem_choices) :default => framework.memory(runtime),
:choices => mem_choices)
else else
mem = framework.memory mem = framework.memory runtime
end end


# Set to MB number # Set to MB number
Expand All @@ -984,14 +1006,15 @@ def do_push(appname=nil)
:name => "#{appname}", :name => "#{appname}",
:staging => { :staging => {
:framework => framework.name, :framework => framework.name,
:runtime => info(:runtime) :runtime => runtime
}, },
:uris => Array(url), :uris => Array(url),
:instances => instances, :instances => instances,
:resources => { :resources => {
:memory => mem_quota :memory => mem_quota
}, }
} }
manifest[:staging][:command] = command if command


# Send the manifest to the cloud controller # Send the manifest to the cloud controller
client.create_app(appname, manifest) client.create_app(appname, manifest)
Expand Down

0 comments on commit df63c09

Please sign in to comment.