Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Provide buildpack cache download URI in staging request

  • Loading branch information...
commit 8fb61c4643375249862135972283b25f5671cee2 1 parent 7a9340f
Maria Shaldibina and Matthew Boedicker authored
View
66 lib/cloud_controller/api/staging.rb
@@ -19,6 +19,7 @@ class Staging < RestController::Base
APP_PATH = "/staging/apps"
DROPLET_PATH = "/staging/droplets"
+ BUILDPACK_CACHE_PATH = "/staging/buildpack_cache"
class DropletUploadHandle
attr_accessor :guid, :upload_path, :buildpack_cache_upload_path
@@ -59,7 +60,7 @@ def buildpack_cache_upload_uri(guid)
def droplet_download_uri(guid)
if local?
- staging_uri("/staging/droplets/#{guid}")
+ staging_uri("#{DROPLET_PATH}/#{guid}")
else
droplet_uri(guid)
end
@@ -113,22 +114,8 @@ def local?
@connection_config[:provider].downcase == "local"
end
- # Return droplet uri for path for a given app's guid.
- #
- # The url is valid for 1 hour when using aws.
- # TODO: The expiration should be configurable.
- def droplet_uri(guid)
- key = key_from_guid(guid, :droplet)
- f = droplet_dir.files.head(key)
- return nil unless f
-
- # unfortunately fog doesn't have a unified interface for non-public
- # urls
- if local?
- f.public_url
- else
- f.url(Time.now + 3600)
- end
+ def buildpack_cache_download_uri(guid)
+ staging_uri("#{BUILDPACK_CACHE_PATH}/#{guid}")
end
def droplet_local_path(guid)
@@ -139,6 +126,18 @@ def buildpack_cache_local_path(guid)
local_path(guid, :buildpack_cache)
end
+ # Return droplet uri for path for a given app's guid.
+ #
+ # The url is valid for 1 hour when using aws.
+ # TODO: The expiration should be configurable.
+ def droplet_uri(guid)
+ package_uri(guid, :droplet)
+ end
+
+ def buildpack_cache_uri(guid)
+ package_uri(guid, :buildpack_cache)
+ end
+
private
def store_package(guid, path, type)
@@ -153,9 +152,23 @@ def store_package(guid, path, type)
def upload_uri(guid, type)
if type == :buildpack_cache
- staging_uri("/staging/buildpack_cache/#{guid}")
+ staging_uri("#{BUILDPACK_CACHE_PATH}/#{guid}")
else
- staging_uri("/staging/droplets/#{guid}")
+ staging_uri("#{DROPLET_PATH}/#{guid}")
+ end
+ end
+
+ def package_uri(guid, type)
+ key = key_from_guid(guid, type)
+ f = droplet_dir.files.head(key)
+ return nil unless f
+
+ # unfortunately fog doesn't have a unified interface for non-public
+ # urls
+ if local?
+ f.public_url
+ else
+ f.url(Time.now + 3600)
end
end
@@ -256,6 +269,12 @@ def download_droplet(guid)
download(guid, droplet_path, droplet_url)
end
+ def download_buildpack_cache(guid)
+ buildpack_cache_path = Staging.buildpack_cache_local_path(guid)
+ buildpack_cache_url = Staging.buildpack_cache_uri(guid)
+ download(guid, buildpack_cache_path, buildpack_cache_url)
+ end
+
private
def download(guid, droplet_path, url)
@@ -280,8 +299,6 @@ def download(guid, droplet_path, url)
end
end
- private
-
def upload(guid, type)
tag = (type == :buildpack_cache) ? "buildpack_cache" : "staged_droplet"
app = Models::App.find(:guid => guid)
@@ -350,9 +367,10 @@ def tmpdir
end
get "/staging/apps/:guid", :download_app
- post "/staging/droplets/:guid", :upload_droplet
- get "/staging/droplets/:guid", :download_droplet
+ post "#{DROPLET_PATH}/:guid", :upload_droplet
+ get "#{DROPLET_PATH}/:guid", :download_droplet
- post "/staging/buildpack_cache/:guid", :upload_buildpack_cache
+ post "#{BUILDPACK_CACHE_PATH}/:guid", :upload_buildpack_cache
+ get "#{BUILDPACK_CACHE_PATH}/:guid", :download_buildpack_cache
end
end
View
1  lib/cloud_controller/app_stager.rb
@@ -113,6 +113,7 @@ def staging_request(async)
:properties => staging_task_properties(@app),
:download_uri => Staging.app_uri(@app.guid),
:upload_uri => Staging.droplet_upload_uri(@app.guid),
+ :buildpack_cache_download_uri => Staging.buildpack_cache_download_uri(@app.guid),
:buildpack_cache_upload_uri => Staging.buildpack_cache_upload_uri(@app.guid),
:async => async }
end
View
77 spec/api/staging_spec.rb
@@ -11,7 +11,7 @@ module VCAP::CloudController
let(:staging_password) { "password" }
let(:app_guid) { "abc" }
let(:workspace) { Dir.mktmpdir }
- let(:staging_config) do
+ let(:original_staging_config) do
{
:max_staging_runtime => max_staging_runtime,
:bind_address => cc_addr,
@@ -35,6 +35,7 @@ module VCAP::CloudController
}
},
:droplets => {
+ :droplet_directory_key => "cc-droplets",
:fog_connection => {
:provider => "Local",
:local_root => Dir.mktmpdir("droplets", workspace)
@@ -45,6 +46,7 @@ module VCAP::CloudController
}
}
end
+ let(:staging_config) { original_staging_config }
before do
Fog.unmock!
@@ -144,7 +146,7 @@ def self.it_destroys_handle
end
end
- describe "upload_uri" do
+ describe "droplet_upload_uri" do
it "should return a uri to our cc" do
uri = Staging.droplet_upload_uri(app_guid)
uri.should == "http://#{staging_user}:#{staging_password}@#{cc_addr}:#{cc_port}/staging/droplets/#{app_guid}"
@@ -158,6 +160,19 @@ def self.it_destroys_handle
end
end
+ describe "buildpack_cache_download_uri" do
+ let(:buildpack_cache) { Tempfile.new(app_guid) }
+
+ after { FileUtils.rm(buildpack_cache.path) }
+
+ it "should return a uri to our cc" do
+ Staging.store_buildpack_cache(app_guid, buildpack_cache.path)
+
+ uri = Staging.buildpack_cache_download_uri(app_guid)
+ uri.should == "http://#{staging_user}:#{staging_password}@#{cc_addr}:#{cc_port}/staging/buildpack_cache/#{app_guid}"
+ end
+ end
+
shared_examples "staging bad auth" do |verb|
it "should return 403 for bad credentials" do
authorize "hacker", "sw0rdf1sh"
@@ -360,5 +375,63 @@ def make_request(droplet_guid=app_obj.guid)
end
end
end
+
+ describe "GET /staging/buildpack_cache/:guid" do
+ let(:app_obj) { Models::App.make }
+ let(:buildpack_cache) { Tempfile.new(app_obj.guid) }
+
+ before do
+ buildpack_cache.write("droplet contents")
+ buildpack_cache.close
+
+ authorize staging_user, staging_password
+ end
+
+ after { FileUtils.rm(buildpack_cache.path) }
+
+ def make_request(droplet_guid=app_obj.guid)
+ get "/staging/buildpack_cache/#{droplet_guid}"
+ end
+
+ context "with a valid buildpack cache" do
+ context "when nginx is enabled" do
+ it "redirects nginx to serve staged droplet" do
+ Staging.store_buildpack_cache(app_obj.guid, buildpack_cache.path)
+
+ make_request
+ last_response.status.should == 200
+ last_response.headers["X-Accel-Redirect"].should match("/cc-droplets/.*/#{app_obj.guid}")
+ end
+ end
+
+ context "when nginx is disabled" do
+ let(:staging_config) do
+ original_staging_config.merge({ :nginx => { :use_nginx => false } })
+ end
+
+ it "should return the buildpack cache" do
+ Staging.store_buildpack_cache(app_obj.guid, buildpack_cache.path)
+
+ make_request
+ last_response.status.should == 200
+ last_response.body.should == "droplet contents"
+ end
+ end
+ end
+
+ context "with a valid buildpack cache but no file" do
+ it "should return an error" do
+ make_request
+ last_response.status.should == 400
+ end
+ end
+
+ context "with an invalid buildpack cache" do
+ it "should return an error" do
+ get "/staging/buildpack_cache/bad"
+ last_response.status.should == 404
+ end
+ end
+ end
end
end
View
1  spec/app_stager_spec.rb
@@ -520,6 +520,7 @@ def store_app_package(app)
r[:download_uri].should match /^http/
r[:upload_uri].should match /^http/
r[:buildpack_cache_upload_uri].should match /^http/
+ r[:buildpack_cache_download_uri].should match /^http/
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.