class Bosh::Cli::Release
This class encapsulates the details of handling dev and final releases: also it partitions release metadata between final config (which is under version control) and user dev config.
Attributes
dir[R]
Public Class Methods
new(dir, final = false)
click to toggle source
# File lib/cli/release.rb, line 10 def initialize(dir, final = false) @dir = dir @final = final config_dir = File.join(dir, "config") @final_config_file = File.join(config_dir, "final.yml") @dev_config_file = File.join(config_dir, "dev.yml") @private_config_file = File.join(config_dir, "private.yml") unless File.directory?(dir) err("Cannot find release directory '#{dir}'") end unless File.directory?(config_dir) err("Cannot find release config directory '#{config_dir}'") end @final_config = load_config(@final_config_file) @dev_config = load_config(@dev_config_file) @private_config = load_config(@private_config_file) migrate_legacy_configs end
Public Instance Methods
blobstore()
click to toggle source
Picks blobstore client to use with current release.
@return [Bosh::Blobstore::Client] blobstore client
# File lib/cli/release.rb, line 96 def blobstore return @blobstore if @blobstore blobstore_config = Marshal.load(Marshal.dump(@final_config["blobstore"])) if blobstore_config.nil? err("Missing blobstore configuration, please update config/final.yml") if @final unless @user_warned warning("Missing blobstore configuration, please update config/final.yml before making a final release") @user_warned = true end return nil end provider = blobstore_config["provider"] options = blobstore_config["options"] || {} options = merge_private_data(provider, options) opts = Bosh::Common.symbolize_keys(options) @blobstore = Bosh::Blobstore::Client.safe_create(provider, opts) rescue Bosh::Blobstore::BlobstoreError => e err("Cannot initialize blobstore: #{e}") end
has_blobstore_secret?()
click to toggle source
# File lib/cli/release.rb, line 64 def has_blobstore_secret? bs = @private_config["blobstore"] return false unless @final_config['blobstore'] # Add special handling for local blobstore which should not need need credentials provider = @final_config['blobstore']['provider'] return true if provider == 'local' has_legacy_secret? || has_blobstore_secrets?(bs, "simple", "user", "password") || has_blobstore_secrets?(bs, "dav", "user", "password") || has_blobstore_secrets?(bs, "s3", "access_key_id", "secret_access_key") end
has_legacy_secret?()
click to toggle source
Check if the deprecated blobstore secret is provided in the private config file @return [Boolean]
# File lib/cli/release.rb, line 60 def has_legacy_secret? @private_config.has_key?("blobstore_secret") end
save_config()
click to toggle source
# File lib/cli/release.rb, line 121 def save_config write_yaml(@dev_config_file, @dev_config) write_yaml(@final_config_file, @final_config) end
Private Instance Methods
has_blobstore_secrets?(blobstore, name, *keys)
click to toggle source
# File lib/cli/release.rb, line 128 def has_blobstore_secrets?(blobstore, name, *keys) return false unless blobstore return false unless blobstore[name] keys.each {|key| return false unless blobstore[name][key]} true end
load_config(file)
click to toggle source
# File lib/cli/release.rb, line 184 def load_config(file) if File.exists?(file) load_yaml_file(file) else {} end end
merge_private_data(provider, options)
click to toggle source
Extracts private blobstore data from final.yml (i.e. secrets) and merges it into the blobstore options.
# File lib/cli/release.rb, line 138 def merge_private_data(provider, options) err("Missing blobstore secret configuration, please update config/private.yml") if @final && !has_blobstore_secret? bs = @private_config["blobstore"] return options unless bs if bs[provider].nil? && has_blobstore_secret? err("blobstore private provider does not match final provider") end options.merge(bs[provider] ? bs[provider] : {}) end
migrate_legacy_configs()
click to toggle source
Upgrade path for legacy clients that kept release metadata in config/dev.yml and config/final.yml
# File lib/cli/release.rb, line 154 def migrate_legacy_configs # We're using blobstore_options as old config marker. # Unfortunately old CLI won't tell you to upgrade because it checks # for valid blobstore options first, so instead of removing # blobstore_options we mark it as deprecated, so new CLI proceeds # to migrate while the old one tells you to upgrade. if @dev_config.has_key?("blobstore_options") && @dev_config["blobstore_options"] != "deprecated" say("Found legacy dev config file '#{@dev_config_file}'".make_yellow) new_dev_config = { "dev_name" => @dev_config["name"], "latest_release_filename" => @dev_config["latest_release_filename"], # Following two options are only needed for older clients # to fail gracefully and never actually read by a new client "blobstore_options" => "deprecated", } @dev_config = new_dev_config File.open(@dev_config_file, "w") do |f| Psych.dump(@dev_config, f) end say("Migrated dev config file format".make_green) end end
write_yaml(file, hash)
click to toggle source
# File lib/cli/release.rb, line 192 def write_yaml(file, hash) unless hash == load_config(file) File.open(file, "w+") do |f| Psych.dump(hash, f) end end end