Created
May 16, 2012 20:21
-
-
Save mpage/2713646 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "digest/md5" | |
require "logger" | |
require "tmpdir" | |
require "vmc" | |
# These are actually vmc requires | |
require "cli/config" | |
require "cli/zip_util" | |
def create_app_name | |
"nfs_race-" + Digest::MD5.hexdigest(Time.now.to_s) | |
end | |
def create_dummy_app(app_name) | |
base_dir = Dir.mktmpdir | |
app_contents =<<EOT | |
require "sinatra" | |
get "/" do | |
"HELLO! from #{app_name} created at #{Time.now}" | |
end | |
EOT | |
test_file = File.join(base_dir, "test.rb") | |
File.open(test_file, "w+") { |f| f.write(app_contents) } | |
base_dir | |
end | |
def create_resource_manifest(app_path) | |
fingerprints = [] | |
resource_files = Dir.glob("#{app_path}/**/*", File::FNM_DOTMATCH) | |
resource_files.each do |filename| | |
next if (File.directory?(filename) || !File.exists?(filename)) | |
fingerprints << { | |
:size => File.size(filename), | |
:sha1 => Digest::SHA1.file(filename).hexdigest, | |
:fn => filename | |
} | |
end | |
fingerprints | |
end | |
if ARGV.size != 4 | |
puts "Usage: nfs_race_repro.rb <cc ip> <different cc ip> <user> <pass>" | |
exit 1 | |
end | |
cc_a, cc_b, user, pass = ARGV | |
logger = Logger.new(STDOUT) | |
logger.level = Logger::INFO | |
vmcs = [cc_a, cc_b].map do |cc_ip| | |
logger.info("Logging in to #{cc_ip}") | |
vmc = VMC::Client.new("http://#{cc_ip}:9022") | |
vmc.login(user, pass) | |
logger.info("Success") | |
vmc | |
end | |
work_dir = Dir.mktmpdir | |
app_manifest = { | |
:staging => { | |
:framework => "sinatra", | |
:runtime => nil, | |
}, | |
:resources => { | |
:memory => 64 | |
} | |
} | |
app_name = create_app_name | |
app_path = create_dummy_app(app_name) | |
begin | |
logger.info("Creating app (#{app_name}) on #{vmcs[0].target}") | |
vmcs[0].create_app(app_name, app_manifest) | |
app_created = true | |
# Check resources on one CC. This should prime the dentry cache with negative | |
# entries. | |
logger.info("Checking resources on #{vmcs[0].target}") | |
resource_manifest = create_resource_manifest(app_path) | |
existing_resources = vmcs[0].check_resources(resource_manifest) | |
if existing_resources.size > 0 | |
# Should always need to upload, since our file has a unique-ish string in it | |
raise "CC should not have any of our resources. Has #{existing_resources}" | |
end | |
# Upload on the other CC. The dentry cache on the first CC should still have | |
# negative entries, while this CC will end up with positive ones. | |
logger.info("Uploading app to #{vmcs[1].target}") | |
app_zipfile_path = File.join(work_dir, "#{app_name}.zip") | |
VMC::Cli::ZipUtil.pack(app_path, app_zipfile_path) | |
vmcs[1].upload_app(app_name, app_zipfile_path, existing_resources) | |
# Check resources on the CC we just uploaded to. It should have the files | |
# we just uploaded in the resource pool now and will tell us that we do not | |
# need to upload them. | |
logger.info("Checking resources on #{vmcs[1].target}") | |
existing_resources = vmcs[1].check_resources(resource_manifest) | |
if existing_resources.size != 1 | |
raise "CC should have our resources. Has #{existing_resources} instead." | |
end | |
# Upload to the CC with the negative dentry cache entries. This should fail | |
# with an AppPackaging error. | |
logger.info("Uploading app to #{vmcs[0].target}") | |
# Copied directly from VMC | |
existing_resources.each do |resource| | |
logger.info("Removing #{resource[:fn]}") | |
FileUtils.rm_f resource[:fn] | |
# adjust filenames sans the explode_dir prefix | |
resource[:fn].sub!("#{app_path}/", '') | |
end | |
if VMC::Cli::ZipUtil.get_files_to_pack(app_path).empty? | |
Dir.chdir(app_path) do | |
File.new(".__empty__", "w") | |
end | |
end | |
app_zipfile_path = File.join(work_dir, "#{app_name}.zip") | |
FileUtils.rm(app_zipfile_path) | |
VMC::Cli::ZipUtil.pack(app_path, app_zipfile_path) | |
vmcs[0].upload_app(app_name, app_zipfile_path, existing_resources) | |
ensure | |
if app_created | |
logger.info("Deleting #{app_name}") | |
vmcs[0].delete_app(app_name) | |
end | |
if app_path | |
logger.info("Removing app locally") | |
FileUtils.rm_rf(app_path) | |
end | |
if work_dir | |
logger.info("Removing work dir") | |
FileUtils.rm_rf(work_dir) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment