From 4db12430ba0c6c021b114c143aaea94f1f754d66 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Thu, 18 Jan 2018 16:16:55 -0800 Subject: Remove erl_call and deploy resources We deprecated these for removal in Chef 14. Signed-off-by: Tim Smith --- lib/chef/provider/deploy.rb | 470 ------------ lib/chef/provider/deploy/revision.rb | 107 --- lib/chef/provider/deploy/timestamped.rb | 34 - lib/chef/provider/erl_call.rb | 76 -- lib/chef/providers.rb | 5 - lib/chef/resource/deploy.rb | 449 ------------ lib/chef/resource/deploy_revision.rb | 31 - lib/chef/resource/erl_call.rb | 90 --- lib/chef/resource/timestamped_deploy.rb | 26 - lib/chef/resources.rb | 4 - spec/functional/resource/deploy_revision_spec.rb | 881 ----------------------- spec/unit/provider/deploy/revision_spec.rb | 110 --- spec/unit/provider/deploy/timestamped_spec.rb | 40 - spec/unit/provider/deploy_spec.rb | 641 ----------------- spec/unit/provider/erl_call_spec.rb | 77 -- spec/unit/provider_resolver_spec.rb | 4 - spec/unit/resource/deploy_revision_spec.rb | 42 -- spec/unit/resource/deploy_spec.rb | 283 -------- spec/unit/resource/erl_call_spec.rb | 81 --- spec/unit/resource/timestamped_deploy_spec.rb | 32 - 20 files changed, 3483 deletions(-) delete mode 100644 lib/chef/provider/deploy.rb delete mode 100644 lib/chef/provider/deploy/revision.rb delete mode 100644 lib/chef/provider/deploy/timestamped.rb delete mode 100644 lib/chef/provider/erl_call.rb delete mode 100644 lib/chef/resource/deploy.rb delete mode 100644 lib/chef/resource/deploy_revision.rb delete mode 100644 lib/chef/resource/erl_call.rb delete mode 100644 lib/chef/resource/timestamped_deploy.rb delete mode 100644 spec/functional/resource/deploy_revision_spec.rb delete mode 100644 spec/unit/provider/deploy/revision_spec.rb delete mode 100644 spec/unit/provider/deploy/timestamped_spec.rb delete mode 100644 spec/unit/provider/deploy_spec.rb delete mode 100644 spec/unit/provider/erl_call_spec.rb delete mode 100644 spec/unit/resource/deploy_revision_spec.rb delete mode 100644 spec/unit/resource/deploy_spec.rb delete mode 100644 spec/unit/resource/erl_call_spec.rb delete mode 100644 spec/unit/resource/timestamped_deploy_spec.rb diff --git a/lib/chef/provider/deploy.rb b/lib/chef/provider/deploy.rb deleted file mode 100644 index c4229d2441..0000000000 --- a/lib/chef/provider/deploy.rb +++ /dev/null @@ -1,470 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2008-2017, Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "chef/mixin/from_file" -require "chef/provider/git" -require "chef/provider/subversion" -require "chef/dsl/recipe" -require "chef/util/path_helper" - -class Chef - class Provider - class Deploy < Chef::Provider - - include Chef::DSL::Recipe - include Chef::Mixin::FromFile - - attr_reader :scm_provider, :release_path, :shared_path, :previous_release_path - - def initialize(new_resource, run_context) - super(new_resource, run_context) - - # will resolve to either git or svn based on resource attributes, - # and will create a resource corresponding to that provider - @scm_provider = new_resource.scm_provider.new(new_resource, run_context) - - # @configuration is not used by Deploy, it is only for backwards compat with - # chef-deploy or capistrano hooks that might use it to get environment information - @configuration = new_resource.to_hash - @configuration[:environment] = @configuration[:environment] && @configuration[:environment]["RAILS_ENV"] - end - - def load_current_resource - @scm_provider.load_current_resource - @release_path = new_resource.deploy_to + "/releases/#{release_slug}" - @shared_path = new_resource.shared_path - end - - def sudo(command, &block) - execute(command, &block) - end - - def run(command, &block) - exec = execute(command, &block) - exec.user(new_resource.user) if new_resource.user - exec.group(new_resource.group) if new_resource.group - exec.cwd(release_path) unless exec.cwd - exec.environment(new_resource.environment) unless exec.environment - converge_by("execute #{command}") do - exec - end - end - - def define_resource_requirements - requirements.assert(:rollback) do |a| - a.assertion { all_releases[-2] } - a.failure_message(RuntimeError, "There is no release to rollback to!") - #There is no reason to assume 2 deployments in a single chef run, hence fails in whyrun. - end - - [ new_resource.before_migrate, new_resource.before_symlink, - new_resource.before_restart, new_resource.after_restart ].each do |script| - requirements.assert(:deploy, :force_deploy) do |a| - callback_file = "#{release_path}/#{script}" - a.assertion do - if script && script.class == String - ::File.exist?(callback_file) - else - true - end - end - a.failure_message(RuntimeError, "Can't find your callback file #{callback_file}") - a.whyrun("Would assume callback file #{callback_file} included in release") - end - end - end - - def action_deploy - save_release_state - if deployed?(release_path ) - if current_release?(release_path ) - Chef::Log.debug("#{new_resource} is the latest version") - else - rollback_to release_path - end - else - - with_rollback_on_error do - deploy - end - end - end - - def action_force_deploy - if deployed?(release_path) - converge_by("delete deployed app at #{release_path} prior to force-deploy") do - Chef::Log.info("Already deployed app at #{release_path}, forcing.") - FileUtils.rm_rf(release_path) - Chef::Log.info("#{new_resource} forcing deploy of already deployed app at #{release_path}") - end - end - - # Alternatives: - # * Move release_path directory before deploy and move it back when error occurs - # * Rollback to previous commit - # * Do nothing - because deploy is force, it will be retried in short time - # Because last is simplest, keep it - deploy - end - - def action_rollback - rollback_to all_releases[-2] - end - - def rollback_to(target_release_path) - @release_path = target_release_path - - rp_index = all_releases.index(release_path) - releases_to_nuke = all_releases[(rp_index + 1)..-1] - - rollback - - releases_to_nuke.each do |i| - converge_by("roll back by removing release #{i}") do - Chef::Log.info "#{new_resource} removing release: #{i}" - FileUtils.rm_rf i - end - release_deleted(i) - end - end - - def deploy - verify_directories_exist - update_cached_repo # no converge-by - scm provider will dothis - enforce_ownership - copy_cached_repo - install_gems - enforce_ownership - callback(:before_migrate, new_resource.before_migrate) - migrate - callback(:before_symlink, new_resource.before_symlink) - symlink - callback(:before_restart, new_resource.before_restart) - restart - callback(:after_restart, new_resource.after_restart) - cleanup! - Chef::Log.info "#{new_resource} deployed to #{new_resource.deploy_to}" - end - - def rollback - Chef::Log.info "#{new_resource} rolling back to previous release #{release_path}" - symlink - Chef::Log.info "#{new_resource} restarting with previous release" - restart - end - - def callback(what, callback_code = nil) - @collection = Chef::ResourceCollection.new - case callback_code - when Proc - Chef::Log.info "#{new_resource} running callback #{what}" - recipe_eval(&callback_code) - when String - run_callback_from_file("#{release_path}/#{callback_code}") - when nil - run_callback_from_file("#{release_path}/deploy/#{what}.rb") - end - end - - def migrate - run_symlinks_before_migrate - - if new_resource.migrate - enforce_ownership - - environment = new_resource.environment - env_info = environment && environment.map do |key_and_val| - "#{key_and_val.first}='#{key_and_val.last}'" - end.join(" ") - - converge_by("execute migration command #{new_resource.migration_command}") do - Chef::Log.info "#{new_resource} migrating #{new_resource.user} with environment #{env_info}" - shell_out!(new_resource.migration_command, run_options(:cwd => release_path, :log_level => :info)) - end - end - end - - def symlink - purge_tempfiles_from_current_release - link_tempfiles_to_current_release - link_current_release_to_production - Chef::Log.info "#{new_resource} updated symlinks" - end - - def restart - if restart_cmd = new_resource.restart_command - if restart_cmd.kind_of?(Proc) - Chef::Log.info("#{new_resource} restarting app with embedded recipe") - recipe_eval(&restart_cmd) - else - converge_by("restart app using command #{new_resource.restart_command}") do - Chef::Log.info("#{new_resource} restarting app") - shell_out!(new_resource.restart_command, run_options(:cwd => new_resource.current_path)) - end - end - end - end - - def cleanup! - converge_by("update release history data") do - release_created(release_path) - end - - chop = -1 - new_resource.keep_releases - all_releases[0..chop].each do |old_release| - converge_by("remove old release #{old_release}") do - Chef::Log.info "#{new_resource} removing old release #{old_release}" - FileUtils.rm_rf(old_release) - end - release_deleted(old_release) - end - end - - def all_releases - Dir.glob(Chef::Util::PathHelper.escape_glob_dir(new_resource.deploy_to) + "/releases/*").sort - end - - def update_cached_repo - if new_resource.svn_force_export - # TODO assertion, non-recoverable - @scm_provider must be svn if force_export? - svn_force_export - else - run_scm_sync - end - end - - def run_scm_sync - @scm_provider.run_action(:sync) - end - - def svn_force_export - Chef::Log.info "#{new_resource} exporting source repository" - @scm_provider.run_action(:force_export) - end - - def copy_cached_repo - target_dir_path = new_resource.deploy_to + "/releases" - converge_by("deploy from repo to #{target_dir_path} ") do - FileUtils.rm_rf(release_path) if ::File.exist?(release_path) - FileUtils.mkdir_p(target_dir_path) - FileUtils.cp_r(::File.join(new_resource.destination, "."), release_path, :preserve => true) - Chef::Log.info "#{new_resource} copied the cached checkout to #{release_path}" - end - end - - def enforce_ownership - converge_by("force ownership of #{new_resource.deploy_to} to #{new_resource.group}:#{new_resource.user}") do - FileUtils.chown_R(new_resource.user, new_resource.group, new_resource.deploy_to, :force => true) - Chef::Log.info("#{new_resource} set user to #{new_resource.user}") if new_resource.user - Chef::Log.info("#{new_resource} set group to #{new_resource.group}") if new_resource.group - end - end - - def verify_directories_exist - create_dir_unless_exists(new_resource.deploy_to) - create_dir_unless_exists(new_resource.shared_path) - end - - def link_current_release_to_production - converge_by(["remove existing link at #{new_resource.current_path}", - "link release #{release_path} into production at #{new_resource.current_path}"]) do - FileUtils.rm_f(new_resource.current_path) - begin - FileUtils.ln_sf(release_path, new_resource.current_path) - rescue => e - raise Chef::Exceptions::FileNotFound.new("Cannot symlink current release to production: #{e.message}") - end - Chef::Log.info "#{new_resource} linked release #{release_path} into production at #{new_resource.current_path}" - end - enforce_ownership - end - - def run_symlinks_before_migrate - links_info = new_resource.symlink_before_migrate.map { |src, dst| "#{src} => #{dst}" }.join(", ") - converge_by("make pre-migration symlinks: #{links_info}") do - new_resource.symlink_before_migrate.each do |src, dest| - begin - FileUtils.ln_sf(new_resource.shared_path + "/#{src}", release_path + "/#{dest}") - rescue => e - raise Chef::Exceptions::FileNotFound.new("Cannot symlink #{new_resource.shared_path}/#{src} to #{release_path}/#{dest} before migrate: #{e.message}") - end - end - Chef::Log.info "#{new_resource} made pre-migration symlinks" - end - end - - def link_tempfiles_to_current_release - dirs_info = new_resource.create_dirs_before_symlink.join(",") - new_resource.create_dirs_before_symlink.each do |dir| - create_dir_unless_exists(release_path + "/#{dir}") - end - Chef::Log.info("#{new_resource} created directories before symlinking: #{dirs_info}") - - links_info = new_resource.symlinks.map { |src, dst| "#{src} => #{dst}" }.join(", ") - converge_by("link shared paths into current release: #{links_info}") do - new_resource.symlinks.each do |src, dest| - begin - FileUtils.ln_sf(::File.join(new_resource.shared_path, src), ::File.join(release_path, dest)) - rescue => e - raise Chef::Exceptions::FileNotFound.new("Cannot symlink shared data #{::File.join(new_resource.shared_path, src)} to #{::File.join(release_path, dest)}: #{e.message}") - end - end - Chef::Log.info("#{new_resource} linked shared paths into current release: #{links_info}") - end - run_symlinks_before_migrate - enforce_ownership - end - - def create_dirs_before_symlink - end - - def purge_tempfiles_from_current_release - log_info = new_resource.purge_before_symlink.join(", ") - converge_by("purge directories in checkout #{log_info}") do - new_resource.purge_before_symlink.each { |dir| FileUtils.rm_rf(release_path + "/#{dir}") } - Chef::Log.info("#{new_resource} purged directories in checkout #{log_info}") - end - end - - protected - - # Internal callback, called after copy_cached_repo. - # Override if you need to keep state externally. - # Note that YOU are responsible for implementing whyrun-friendly behavior - # in any actions you take in this callback. - def release_created(release_path) - end - - # Note that YOU are responsible for using appropriate whyrun nomenclature - # Override if you need to keep state externally. - # Note that YOU are responsible for implementing whyrun-friendly behavior - # in any actions you take in this callback. - def release_deleted(release_path) - end - - def release_slug - raise Chef::Exceptions::Override, "You must override release_slug in #{self}" - end - - def install_gems - gem_resource_collection_runner.converge - end - - def gem_resource_collection_runner - child_context = run_context.create_child - gem_packages.each { |rbgem| child_context.resource_collection.insert(rbgem) } - Chef::Runner.new(child_context) - end - - def gem_packages - return [] unless ::File.exist?("#{release_path}/gems.yml") - gems = YAML.load(IO.read("#{release_path}/gems.yml")) - - gems.map do |g| - r = Chef::Resource::GemPackage.new(g[:name], run_context) - r.version g[:version] - r.action :install - r.source "http://gems.github.com" - r - end - end - - def run_options(run_opts = {}) - run_opts[:user] = new_resource.user if new_resource.user - run_opts[:group] = new_resource.group if new_resource.group - run_opts[:environment] = new_resource.environment if new_resource.environment - run_opts[:log_tag] = new_resource.to_s - run_opts[:log_level] ||= :debug - if run_opts[:log_level] == :info - if STDOUT.tty? && !Chef::Config[:daemon] && Chef::Log.info? - run_opts[:live_stream] = STDOUT - end - end - run_opts - end - - def run_callback_from_file(callback_file) - Chef::Log.info "#{new_resource} queueing checkdeploy hook #{callback_file}" - recipe_eval do - Dir.chdir(release_path) do - from_file(callback_file) if ::File.exist?(callback_file) - end - end - end - - def create_dir_unless_exists(dir) - if ::File.directory?(dir) - Chef::Log.debug "#{new_resource} not creating #{dir} because it already exists" - return false - end - converge_by("create new directory #{dir}") do - begin - FileUtils.mkdir_p(dir) - Chef::Log.debug "#{new_resource} created directory #{dir}" - if new_resource.user - FileUtils.chown(new_resource.user, nil, dir) - Chef::Log.debug("#{new_resource} set user to #{new_resource.user} for #{dir}") - end - if new_resource.group - FileUtils.chown(nil, new_resource.group, dir) - Chef::Log.debug("#{new_resource} set group to #{new_resource.group} for #{dir}") - end - rescue => e - raise Chef::Exceptions::FileNotFound.new("Cannot create directory #{dir}: #{e.message}") - end - end - end - - def with_rollback_on_error - yield - rescue ::Exception => e - if new_resource.rollback_on_error - Chef::Log.warn "Error on deploying #{release_path}: #{e.message}" - failed_release = release_path - - if previous_release_path - @release_path = previous_release_path - rollback - end - converge_by("remove failed deploy #{failed_release}") do - Chef::Log.info "Removing failed deploy #{failed_release}" - FileUtils.rm_rf failed_release - end - release_deleted(failed_release) - end - - raise - end - - def save_release_state - if ::File.exists?(new_resource.current_path) - release = ::File.readlink(new_resource.current_path) - @previous_release_path = release if ::File.exists?(release) - end - end - - def deployed?(release) - all_releases.include?(release) - end - - def current_release?(release) - @previous_release_path == release - end - end - end -end diff --git a/lib/chef/provider/deploy/revision.rb b/lib/chef/provider/deploy/revision.rb deleted file mode 100644 index 06138e4f05..0000000000 --- a/lib/chef/provider/deploy/revision.rb +++ /dev/null @@ -1,107 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Author:: Tim Hinderliter () -# Author:: Seth Falcon () -# Copyright:: Copyright 2009-2016, Daniel DeLeo -# Copyright:: Copyright 2010-2016, Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "chef/provider" -require "chef/provider/deploy" -require "chef/json_compat" - -class Chef - class Provider - class Deploy - class Revision < Chef::Provider::Deploy - provides :deploy_revision - provides :deploy_branch - - def all_releases - sorted_releases - end - - def action_deploy - validate_release_history! - super - end - - def cleanup! - super - - known_releases = sorted_releases - - Dir["#{Chef::Util::PathHelper.escape_glob_dir(new_resource.deploy_to)}/releases/*"].each do |release_dir| - unless known_releases.include?(release_dir) - converge_by("Remove unknown release in #{release_dir}") do - FileUtils.rm_rf(release_dir) - end - end - end - end - - protected - - def release_created(release) - sorted_releases { |r| r.delete(release); r << release } - end - - def release_deleted(release) - sorted_releases { |r| r.delete(release) } - end - - def release_slug - scm_provider.revision_slug - end - - private - - def sorted_releases - cache = load_cache - if block_given? - yield cache - save_cache(cache) - end - cache - end - - def validate_release_history! - sorted_releases do |release_list| - release_list.each do |path| - release_list.delete(path) unless ::File.exist?(path) - end - end - end - - def sorted_releases_from_filesystem - Dir.glob(Chef::Util::PathHelper.escape_glob_dir(new_resource.deploy_to) + "/releases/*").sort_by { |d| ::File.ctime(d) } - end - - def load_cache - Chef::JSONCompat.parse(Chef::FileCache.load("revision-deploys/#{new_resource.name}")) - rescue Chef::Exceptions::FileNotFound - sorted_releases_from_filesystem - end - - def save_cache(cache) - Chef::FileCache.store("revision-deploys/#{new_resource.name}", Chef::JSONCompat.to_json(cache)) - cache - end - - end - end - end -end diff --git a/lib/chef/provider/deploy/timestamped.rb b/lib/chef/provider/deploy/timestamped.rb deleted file mode 100644 index 5486b092d3..0000000000 --- a/lib/chef/provider/deploy/timestamped.rb +++ /dev/null @@ -1,34 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2009-2016, Daniel DeLeo -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -class Chef - class Provider - class Deploy - class Timestamped < Chef::Provider::Deploy - provides :timestamped_deploy - provides :deploy - - protected - - def release_slug - Time.now.utc.strftime("%Y%m%d%H%M%S") - end - end - end - end -end diff --git a/lib/chef/provider/erl_call.rb b/lib/chef/provider/erl_call.rb deleted file mode 100644 index b73341bb16..0000000000 --- a/lib/chef/provider/erl_call.rb +++ /dev/null @@ -1,76 +0,0 @@ -# -# Author:: Joe Williams () -# Copyright:: Copyright 2009-2016, Joe Williams -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "chef/log" -require "chef/provider" - -class Chef - class Provider - class ErlCall < Chef::Provider - - provides :erl_call - - def initialize(node, new_resource) - super(node, new_resource) - end - - def load_current_resource - true - end - - def action_run - case new_resource.name_type - when "sname" - node = "-sname #{new_resource.node_name}" - when "name" - node = "-name #{new_resource.node_name}" - end - - if new_resource.cookie - cookie = "-c #{new_resource.cookie}" - else - cookie = "" - end - - if new_resource.distributed - distributed = "-s" - else - distributed = "" - end - - command = "erl_call -e #{distributed} #{node} #{cookie}" - - converge_by("run erlang block") do - so = shell_out!(command, input: new_resource.code) - - # fail if stderr contains anything - if so.stderr.length > 0 - raise Chef::Exceptions::ErlCall, so.stderr - end - - # fail if the first 4 characters aren't "{ok," - unless so.stdout[0..3].include?("{ok,") - raise Chef::Exceptions::ErlCall, so.stdout - end - - end - end - - end - end -end diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb index a3332477e7..507203fd28 100644 --- a/lib/chef/providers.rb +++ b/lib/chef/providers.rb @@ -24,12 +24,10 @@ require "chef/provider/cookbook_file" require "chef/provider/cron" require "chef/provider/cron/solaris" require "chef/provider/cron/aix" -require "chef/provider/deploy" require "chef/provider/directory" require "chef/provider/dsc_script" require "chef/provider/dsc_resource" require "chef/provider/env" -require "chef/provider/erl_call" require "chef/provider/execute" require "chef/provider/file" require "chef/provider/git" @@ -131,9 +129,6 @@ require "chef/provider/mount/aix" require "chef/provider/mount/solaris" require "chef/provider/mount/windows" -require "chef/provider/deploy/revision" -require "chef/provider/deploy/timestamped" - require "chef/provider/remote_file/ftp" require "chef/provider/remote_file/sftp" require "chef/provider/remote_file/http" diff --git a/lib/chef/resource/deploy.rb b/lib/chef/resource/deploy.rb deleted file mode 100644 index f74fe86c12..0000000000 --- a/lib/chef/resource/deploy.rb +++ /dev/null @@ -1,449 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Author:: Tyler Cloke () -# Copyright:: Copyright 2008-2016, Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# EX: -# deploy "/my/deploy/dir" do -# repo "git@github.com/whoami/project" -# revision "abc123" # or "HEAD" or "TAG_for_1.0" or (subversion) "1234" -# user "deploy_ninja" -# enable_submodules true -# migrate true -# migration_command "rake db:migrate" -# environment "RAILS_ENV" => "production", "OTHER_ENV" => "foo" -# shallow_clone true -# depth 1 -# action :deploy # or :rollback -# restart_command "touch tmp/restart.txt" -# git_ssh_wrapper "wrap-ssh4git.sh" -# scm_provider Chef::Provider::Git # is the default, for svn: Chef::Provider::Subversion -# svn_username "whoami" -# svn_password "supersecret" -# end - -require "chef/resource/scm" - -class Chef - class Resource - - # Deploy: Deploy apps from a source control repository. - # - # Callbacks: - # Callbacks can be a block or a string. If given a block, the code - # is evaluated as an embedded recipe, and run at the specified - # point in the deploy process. If given a string, the string is taken as - # a path to a callback file/recipe. Paths are evaluated relative to the - # release directory. Callback files can contain chef code (resources, etc.) - # - class Deploy < Chef::Resource - - identity_attr :repository - - state_attrs :deploy_to, :revision - - default_action :deploy - allowed_actions :force_deploy, :deploy, :rollback - - def initialize(name, run_context = nil) - super - @deploy_to = name - @environment = nil - @repository_cache = "cached-copy" - @copy_exclude = [] - @purge_before_symlink = %w{log tmp/pids public/system} - @create_dirs_before_symlink = %w{tmp public config} - @symlink_before_migrate = { "config/database.yml" => "config/database.yml" } - @symlinks = { "system" => "public/system", "pids" => "tmp/pids", "log" => "log" } - @revision = "HEAD" - @migrate = false - @rollback_on_error = false - @remote = "origin" - @enable_submodules = false - @shallow_clone = false - @depth = nil - @scm_provider = Chef::Provider::Git - @svn_force_export = false - @additional_remotes = Hash[] - @keep_releases = 5 - @enable_checkout = true - @checkout_branch = "deploy" - end - - # This resource is deprecated. - def after_created - Chef.deprecated(:deploy_resource, "The #{resource_name} resource (#{source_line}) is deprecated and will be removed from Chef core in 14.0 (April 2018). " \ - "A migration cookbook will be available in the future, see the deprecation documentation for more information.") - end - - # where the checked out/cloned code goes - def destination - @destination ||= shared_path + "/#{@repository_cache}" - end - - # where shared stuff goes, i.e., logs, tmp, etc. goes here - def shared_path - @shared_path ||= @deploy_to + "/shared" - end - - # where the deployed version of your code goes - def current_path - @current_path ||= @deploy_to + "/current" - end - - def depth(arg = @shallow_clone ? 5 : nil) - set_or_return( - :depth, - arg, - :kind_of => [ Integer ] - ) - end - - # note: deploy_to is your application "meta-root." - def deploy_to(arg = nil) - set_or_return( - :deploy_to, - arg, - :kind_of => [ String ] - ) - end - - def repo(arg = nil) - set_or_return( - :repo, - arg, - :kind_of => [ String ] - ) - end - alias :repository :repo - - def remote(arg = nil) - set_or_return( - :remote, - arg, - :kind_of => [ String ] - ) - end - - def role(arg = nil) - set_or_return( - :role, - arg, - :kind_of => [ String ] - ) - end - - def restart_command(arg = nil, &block) - arg ||= block - set_or_return( - :restart_command, - arg, - :kind_of => [ String, Proc ] - ) - end - alias :restart :restart_command - - def migrate(arg = nil) - set_or_return( - :migrate, - arg, - :kind_of => [ TrueClass, FalseClass ] - ) - end - - def migration_command(arg = nil) - set_or_return( - :migration_command, - arg, - :kind_of => [ String ] - ) - end - - def rollback_on_error(arg = nil) - set_or_return( - :rollback_on_error, - arg, - :kind_of => [ TrueClass, FalseClass ] - ) - end - - def user(arg = nil) - set_or_return( - :user, - arg, - :kind_of => [ String ] - ) - end - - def group(arg = nil) - set_or_return( - :group, - arg, - :kind_of => [ String ] - ) - end - - def enable_submodules(arg = nil) - set_or_return( - :enable_submodules, - arg, - :kind_of => [ TrueClass, FalseClass ] - ) - end - - def shallow_clone(arg = nil) - set_or_return( - :shallow_clone, - arg, - :kind_of => [ TrueClass, FalseClass ] - ) - end - - def repository_cache(arg = nil) - set_or_return( - :repository_cache, - arg, - :kind_of => [ String ] - ) - end - - def copy_exclude(arg = nil) - set_or_return( - :copy_exclude, - arg, - :kind_of => [ String ] - ) - end - - def revision(arg = nil) - set_or_return( - :revision, - arg, - :kind_of => [ String ] - ) - end - alias :branch :revision - - def git_ssh_wrapper(arg = nil) - set_or_return( - :git_ssh_wrapper, - arg, - :kind_of => [ String ] - ) - end - alias :ssh_wrapper :git_ssh_wrapper - - def svn_username(arg = nil) - set_or_return( - :svn_username, - arg, - :kind_of => [ String ] - ) - end - - def svn_password(arg = nil) - set_or_return( - :svn_password, - arg, - :kind_of => [ String ] - ) - end - - def svn_arguments(arg = nil) - set_or_return( - :svn_arguments, - arg, - :kind_of => [ String ] - ) - end - - def svn_info_args(arg = nil) - set_or_return( - :svn_arguments, - arg, - :kind_of => [ String ]) - end - - def scm_provider(arg = nil) - klass = if arg.kind_of?(String) || arg.kind_of?(Symbol) - lookup_provider_constant(arg) - else - arg - end - set_or_return( - :scm_provider, - klass, - :kind_of => [ Class ] - ) - end - - # This is to support "provider :revision" without deprecation warnings. - # Do NOT copy this. - def self.provider_base - Chef::Provider::Deploy - end - - def svn_force_export(arg = nil) - set_or_return( - :svn_force_export, - arg, - :kind_of => [ TrueClass, FalseClass ] - ) - end - - def environment(arg = nil) - if arg.is_a?(String) - Chef::Log.debug "Setting RAILS_ENV, RACK_ENV, and MERB_ENV to `#{arg}'" - Chef::Log.warn "[DEPRECATED] please modify your deploy recipe or attributes to set the environment using a hash" - arg = { "RAILS_ENV" => arg, "MERB_ENV" => arg, "RACK_ENV" => arg } - end - set_or_return( - :environment, - arg, - :kind_of => [ Hash ] - ) - end - - # The number of old release directories to keep around after cleanup - def keep_releases(arg = nil) - [set_or_return( - :keep_releases, - arg, - :kind_of => [ Integer ]), 1].max - end - - # An array of paths, relative to your app's root, to be purged from a - # SCM clone/checkout before symlinking. Use this to get rid of files and - # directories you want to be shared between releases. - # Default: ["log", "tmp/pids", "public/system"] - def purge_before_symlink(arg = nil) - set_or_return( - :purge_before_symlink, - arg, - :kind_of => Array - ) - end - - # An array of paths, relative to your app's root, where you expect dirs to - # exist before symlinking. This runs after #purge_before_symlink, so you - # can use this to recreate dirs that you had previously purged. - # For example, if you plan to use a shared directory for pids, and you - # want it to be located in $APP_ROOT/tmp/pids, you could purge tmp, - # then specify tmp here so that the tmp directory will exist when you - # symlink the pids directory in to the current release. - # Default: ["tmp", "public", "config"] - def create_dirs_before_symlink(arg = nil) - set_or_return( - :create_dirs_before_symlink, - arg, - :kind_of => Array - ) - end - - # A Hash of shared/dir/path => release/dir/path. This attribute determines - # which files and dirs in the shared directory get symlinked to the current - # release directory, and where they go. If you have a directory - # $shared/pids that you would like to symlink as $current_release/tmp/pids - # you specify it as "pids" => "tmp/pids" - # Default {"system" => "public/system", "pids" => "tmp/pids", "log" => "log"} - def symlinks(arg = nil) - set_or_return( - :symlinks, - arg, - :kind_of => Hash - ) - end - - # A Hash of shared/dir/path => release/dir/path. This attribute determines - # which files in the shared directory get symlinked to the current release - # directory and where they go. Unlike map_shared_files, these are symlinked - # *before* any migration is run. - # For a rails/merb app, this is used to link in a known good database.yml - # (with the production db password) before running migrate. - # Default {"config/database.yml" => "config/database.yml"} - def symlink_before_migrate(arg = nil) - set_or_return( - :symlink_before_migrate, - arg, - :kind_of => Hash - ) - end - - # Callback fires before migration is run. - def before_migrate(arg = nil, &block) - arg ||= block - set_or_return(:before_migrate, arg, :kind_of => [Proc, String]) - end - - # Callback fires before symlinking - def before_symlink(arg = nil, &block) - arg ||= block - set_or_return(:before_symlink, arg, :kind_of => [Proc, String]) - end - - # Callback fires before restart - def before_restart(arg = nil, &block) - arg ||= block - set_or_return(:before_restart, arg, :kind_of => [Proc, String]) - end - - # Callback fires after restart - def after_restart(arg = nil, &block) - arg ||= block - set_or_return(:after_restart, arg, :kind_of => [Proc, String]) - end - - def additional_remotes(arg = nil) - set_or_return( - :additional_remotes, - arg, - :kind_of => Hash - ) - end - - def enable_checkout(arg = nil) - set_or_return( - :enable_checkout, - arg, - :kind_of => [TrueClass, FalseClass] - ) - end - - def checkout_branch(arg = nil) - set_or_return( - :checkout_branch, - arg, - :kind_of => String - ) - end - - # FIXME The Deploy resource may be passed to an SCM provider as its - # resource. The SCM provider knows that SCM resources can specify a - # timeout for SCM operations. The deploy resource must therefore support - # a timeout method, but the timeout it describes is for SCM operations, - # not the overall deployment. This is potentially confusing. - def timeout(arg = nil) - set_or_return( - :timeout, - arg, - :kind_of => Integer - ) - end - - end - end -end diff --git a/lib/chef/resource/deploy_revision.rb b/lib/chef/resource/deploy_revision.rb deleted file mode 100644 index 41046ec288..0000000000 --- a/lib/chef/resource/deploy_revision.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2009-2016, Daniel DeLeo -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -class Chef - class Resource - - # Convenience class for using the deploy resource with the revision - # deployment strategy (provider) - class DeployRevision < Chef::Resource::Deploy - end - - class DeployBranch < Chef::Resource::DeployRevision - end - - end -end diff --git a/lib/chef/resource/erl_call.rb b/lib/chef/resource/erl_call.rb deleted file mode 100644 index 6bc71e75e6..0000000000 --- a/lib/chef/resource/erl_call.rb +++ /dev/null @@ -1,90 +0,0 @@ -# -# Author:: Joe Williams () -# Author:: Tyler Cloke () -# Copyright:: Copyright 2009-2016, Joe Williams -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "chef/resource" -require "chef/provider/erl_call" - -class Chef - class Resource - class ErlCall < Chef::Resource - - # erl_call : http://erlang.org/doc/man/erl_call.html - - identity_attr :code - - default_action :run - - def initialize(name, run_context = nil) - super - - @code = "q()." # your erlang code goes here - @cookie = nil # cookie of the erlang node - @distributed = false # if you want to have a distributed erlang node - @name_type = "sname" # type of erlang hostname name or sname - @node_name = "chef@localhost" # the erlang node hostname - end - - def code(arg = nil) - set_or_return( - :code, - arg, - :kind_of => [ String ] - ) - end - - def cookie(arg = nil) - set_or_return( - :cookie, - arg, - :kind_of => [ String ] - ) - end - - def distributed(arg = nil) - set_or_return( - :distributed, - arg, - :kind_of => [ TrueClass, FalseClass ] - ) - end - - def name_type(arg = nil) - set_or_return( - :name_type, - arg, - :kind_of => [ String ] - ) - end - - def node_name(arg = nil) - set_or_return( - :node_name, - arg, - :kind_of => [ String ] - ) - end - - # This resource is deprecated. - def after_created - Chef.deprecated(:erl_resource, "The #{resource_name} resource (#{source_line}) is deprecated and will be removed from Chef core in 14.0 (April 2018).") - end - - end - end -end diff --git a/lib/chef/resource/timestamped_deploy.rb b/lib/chef/resource/timestamped_deploy.rb deleted file mode 100644 index 1d6b07a719..0000000000 --- a/lib/chef/resource/timestamped_deploy.rb +++ /dev/null @@ -1,26 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2009-2016, Daniel DeLeo -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -class Chef - class Resource - # Convenience class for using the deploy resource with the timestamped - # deployment strategy (provider) - class TimestampedDeploy < Chef::Resource::Deploy - end - end -end diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb index 54d21fd53c..0723f1b45a 100644 --- a/lib/chef/resources.rb +++ b/lib/chef/resources.rb @@ -28,15 +28,12 @@ require "chef/resource/chef_gem" require "chef/resource/chocolatey_package" require "chef/resource/cron" require "chef/resource/csh" -require "chef/resource/deploy" -require "chef/resource/deploy_revision" require "chef/resource/directory" require "chef/resource/dpkg_package" require "chef/resource/dnf_package" require "chef/resource/dsc_script" require "chef/resource/dsc_resource" require "chef/resource/env" -require "chef/resource/erl_call" require "chef/resource/execute" require "chef/resource/file" require "chef/resource/freebsd_package" @@ -81,7 +78,6 @@ require "chef/resource/windows_service" require "chef/resource/subversion" require "chef/resource/smartos_package" require "chef/resource/template" -require "chef/resource/timestamped_deploy" require "chef/resource/user" require "chef/resource/user/aix_user" require "chef/resource/user/dscl_user" diff --git a/spec/functional/resource/deploy_revision_spec.rb b/spec/functional/resource/deploy_revision_spec.rb deleted file mode 100644 index 572609d8ff..0000000000 --- a/spec/functional/resource/deploy_revision_spec.rb +++ /dev/null @@ -1,881 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2012-2016, Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "spec_helper" -require "tmpdir" - -# Deploy relies heavily on symlinks, so it doesn't work on windows. -describe Chef::Resource::DeployRevision, :unix_only => true, :requires_git => true do - - let(:file_cache_path) { Dir.mktmpdir } - let(:deploy_directory) { Dir.mktmpdir } - - # By making restart or other operations write to this file, we can externally - # track the order in which those operations happened. - let(:observe_order_file) { Tempfile.new("deploy-resource-observe-operations") } - - before do - Chef::Log.level = :info - @old_file_cache_path = Chef::Config[:file_cache_path] - Chef::Config[:file_cache_path] = file_cache_path - end - - after do - Chef::Config[:file_cache_path] = @old_file_cache_path - FileUtils.remove_entry_secure deploy_directory if File.exist?(deploy_directory) - FileUtils.remove_entry_secure file_cache_path - observe_order_file.close - FileUtils.remove_entry_secure observe_order_file.path - end - - before(:all) do - @ohai = Ohai::System.new - @ohai.all_plugins(%w{platform os}) - end - - let(:node) do - Chef::Node.new.tap do |n| - n.name "rspec-test" - n.consume_external_attrs(@ohai.data, {}) - end - end - - let(:event_dispatch) { Chef::EventDispatch::Dispatcher.new } - let(:run_context) { Chef::RunContext.new(node, {}, event_dispatch) } - - # These tests use git's bundle feature, which is a way to export an entire - # git repo (or subset of commits) as a single file. - # - # Generally you can treat a git bundle as a regular git remote. - # - # See also: http://git-scm.com/2010/03/10/bundles.html - let(:git_bundle_repo) { File.expand_path("git_bundles/sinatra-test-app.gitbundle", CHEF_SPEC_DATA) } - - let(:git_bundle_with_in_repo_callbacks) { File.expand_path("git_bundles/sinatra-test-app-with-callback-files.gitbundle", CHEF_SPEC_DATA) } - - let(:git_bundle_with_in_repo_symlinks) { File.expand_path("git_bundles/sinatra-test-app-with-symlinks.gitbundle", CHEF_SPEC_DATA) } - - # This is the fourth version - let(:latest_rev) { "3eb5ca6c353c83d9179dd3b29347539829b401f3" } - - # This is the third version - let(:previous_rev) { "6d19a6dbecc8e37f5b2277345885c0c783eb8fb1" } - - # This is the second version - let(:second_rev) { "0827e1b0e5043608ac0a824da5c558e252154ad0" } - - # This is the sixth version, it is on the "with-deploy-scripts" branch - let(:rev_with_in_repo_callbacks) { "2404d015882659754bdb93ad6e4b4d3d02691a82" } - - # This is the fifth version in the "with-symlinks" branch - let(:rev_with_in_repo_symlinks) { "5a4748c52aaea8250b4346a9b8ede95ee3755e28" } - - # Read values from the +observe_order_file+ and split each line. This way you - # can see in which order things really happened. - def actual_operations_order - IO.read(observe_order_file.path).split("\n").map(&:strip) - end - - # 1. touch `restart.txt` in cwd so we know that the command is run with the - # right cwd. - # 2. Append +tag+ to the `observe_order_file` so we can check the order in - # which operations happen later in the test. - def shell_restart_command(tag) - "touch restart.txt && echo '#{tag}' >> #{observe_order_file.path}" - end - - let(:basic_deploy_resource) do - Chef::Resource::DeployRevision.new(deploy_directory, run_context).tap do |r| - r.name "deploy-revision-unit-test" - r.repo git_bundle_repo - r.symlink_before_migrate({}) - r.symlinks({}) - end - end - - let(:deploy_to_latest_rev) do - basic_deploy_resource.dup.tap do |r| - r.revision(latest_rev) - r.restart_command shell_restart_command(:deploy_to_latest_rev) - end - end - - let(:deploy_to_previous_rev) do - basic_deploy_resource.dup.tap do |r| - r.revision(previous_rev) - r.restart_command shell_restart_command(:deploy_to_previous_rev) - end - end - - let(:deploy_to_latest_rev_again) do - basic_deploy_resource.dup.tap do |r| - r.revision(latest_rev) - r.restart_command shell_restart_command(:deploy_to_latest_rev_again) - end - end - - let(:deploy_to_previous_rev_again) do - basic_deploy_resource.dup.tap do |r| - r.revision(previous_rev) - r.restart_command shell_restart_command(:deploy_to_previous_rev_again) - end - end - - let(:deploy_to_second_rev) do - basic_deploy_resource.dup.tap do |r| - r.revision(second_rev) - r.restart_command shell_restart_command(:deploy_to_second_rev) - end - end - - let(:deploy_to_second_rev_again) do - basic_deploy_resource.dup.tap do |r| - r.revision(second_rev) - r.restart_command shell_restart_command(:deploy_to_second_rev_again) - end - end - - let(:deploy_to_second_rev_again_again) do - basic_deploy_resource.dup.tap do |r| - r.revision(second_rev) - r.restart_command shell_restart_command(:deploy_to_second_rev_again_again) - end - end - - # Computes the full path for +path+ relative to the deploy directory - def rel_path(path) - File.expand_path(path, deploy_directory) - end - - def actual_current_rev - Dir.chdir(rel_path("current")) do - `git rev-parse HEAD`.strip - end - end - - def self.the_app_is_deployed_at_revision(target_rev_spec) - it "deploys the app to the target revision (#{target_rev_spec})" do - target_rev = send(target_rev_spec) - - expect(File).to exist(rel_path("current")) - - expect(actual_current_rev).to eq(target_rev) - - # Is the app code actually there? - expect(File).to exist(rel_path("current/app/app.rb")) - end - end - - context "when deploying a simple app" do - describe "for the first time, with the required directory layout precreated" do - before do - FileUtils.mkdir_p(rel_path("releases")) - FileUtils.mkdir_p(rel_path("shared")) - deploy_to_latest_rev.run_action(:deploy) - end - - the_app_is_deployed_at_revision(:latest_rev) - - it "restarts the application" do - expect(File).to exist(rel_path("current/restart.txt")) - expect(actual_operations_order).to eq(%w{deploy_to_latest_rev}) - end - - it "is marked as updated" do - expect(deploy_to_latest_rev).to be_updated_by_last_action - end - end - - describe "back to a previously deployed revision, with the directory structure precreated" do - before do - FileUtils.mkdir_p(rel_path("releases")) - FileUtils.mkdir_p(rel_path("shared")) - - deploy_to_latest_rev.run_action(:deploy) - deploy_to_previous_rev.run_action(:deploy) - deploy_to_latest_rev_again.run_action(:deploy) - end - - the_app_is_deployed_at_revision(:latest_rev) - - it "restarts the application after rolling back" do - expect(actual_operations_order).to eq(%w{deploy_to_latest_rev deploy_to_previous_rev deploy_to_latest_rev_again}) - end - - it "is marked updated" do - expect(deploy_to_latest_rev_again).to be_updated_by_last_action - end - - it "deploys the right code" do - expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the fourth version of the app") - end - end - - describe "for the first time, with no existing directory layout" do - before do - deploy_to_latest_rev.run_action(:deploy) - end - - it "creates the required directory tree" do - expect(File).to be_directory(rel_path("releases")) - expect(File).to be_directory(rel_path("shared")) - expect(File).to be_directory(rel_path("releases/#{latest_rev}")) - - expect(File).to be_directory(rel_path("current/tmp")) - expect(File).to be_directory(rel_path("current/config")) - expect(File).to be_directory(rel_path("current/public")) - - expect(File).to be_symlink(rel_path("current")) - expect(File.readlink(rel_path("current"))).to eq(rel_path("releases/#{latest_rev}")) - end - - the_app_is_deployed_at_revision(:latest_rev) - - it "restarts the application" do - expect(File).to exist(rel_path("current/restart.txt")) - expect(actual_operations_order).to eq(%w{deploy_to_latest_rev}) - end - - it "is marked as updated" do - expect(deploy_to_latest_rev).to be_updated_by_last_action - end - end - - describe "again to the current revision" do - before do - deploy_to_latest_rev.run_action(:deploy) - deploy_to_latest_rev.run_action(:deploy) - end - - the_app_is_deployed_at_revision(:latest_rev) - - it "does not restart the app" do - expect(actual_operations_order).to eq(%w{deploy_to_latest_rev}) - end - - it "is not marked updated" do - expect(deploy_to_latest_rev).not_to be_updated_by_last_action - end - - end - - describe "again with force_deploy" do - before do - deploy_to_latest_rev.run_action(:force_deploy) - deploy_to_latest_rev_again.run_action(:force_deploy) - end - - the_app_is_deployed_at_revision(:latest_rev) - - it "restarts the app" do - expect(actual_operations_order).to eq(%w{deploy_to_latest_rev deploy_to_latest_rev_again}) - end - - it "is marked updated" do - expect(deploy_to_latest_rev).to be_updated_by_last_action - end - - end - - describe "again to a new revision" do - before do - deploy_to_previous_rev.run_action(:deploy) - deploy_to_latest_rev.run_action(:deploy) - end - - the_app_is_deployed_at_revision(:latest_rev) - - it "restarts the application after the new deploy" do - expect(actual_operations_order).to eq(%w{deploy_to_previous_rev deploy_to_latest_rev}) - end - - it "is marked updated" do - expect(deploy_to_previous_rev).to be_updated_by_last_action - end - - it "leaves the old copy of the app around for rollback" do - expect(File).to exist(File.join(deploy_directory, "releases", previous_rev)) - end - - end - - describe "back to a previously deployed revision (implicit rollback)" do - before do - deploy_to_latest_rev.run_action(:deploy) - deploy_to_previous_rev.run_action(:deploy) - deploy_to_latest_rev_again.run_action(:deploy) - end - - the_app_is_deployed_at_revision(:latest_rev) - - it "restarts the application after rolling back" do - expect(actual_operations_order).to eq(%w{deploy_to_latest_rev deploy_to_previous_rev deploy_to_latest_rev_again}) - end - - it "is marked updated" do - expect(deploy_to_latest_rev_again).to be_updated_by_last_action - end - - it "deploys the right code" do - expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the fourth version of the app") - end - end - - describe "back to a previously deployed revision where resource rev == latest revision (explicit rollback)" do - before do - deploy_to_previous_rev.run_action(:deploy) - @previous_rev_all_releases = deploy_to_previous_rev.provider_for_action(:deploy).all_releases - deploy_to_latest_rev.run_action(:deploy) - @latest_rev_all_releases = deploy_to_latest_rev.provider_for_action(:deploy).all_releases - deploy_to_latest_rev_again.run_action(:rollback) - @previous_rev_again_all_releases = deploy_to_latest_rev_again.provider_for_action(:deploy).all_releases - end - - the_app_is_deployed_at_revision(:previous_rev) - - it "restarts the application after rolling back" do - expect(actual_operations_order).to eq(%w{deploy_to_previous_rev deploy_to_latest_rev deploy_to_latest_rev_again}) - end - - it "is marked updated" do - expect(deploy_to_latest_rev_again).to be_updated_by_last_action - end - - it "deploys the right code" do - expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the third version of the app") - end - - it "all_releases after first deploy should have one entry" do - expect(@previous_rev_all_releases.length).to eq(1) - end - - it "all_releases after second deploy should have two entries" do - expect(@latest_rev_all_releases.length).to eq(2) - end - - it "all_releases after rollback should have one entry" do - expect(@previous_rev_again_all_releases.length).to eq(1) - end - - it "all_releases after rollback should be the same as after the first deploy" do - expect(@previous_rev_again_all_releases).to eq(@previous_rev_all_releases) - end - - end - - describe "back to a previously deployed revision where resource rev == previous revision (explicit rollback)" do - before do - deploy_to_previous_rev.run_action(:deploy) - @previous_rev_all_releases = deploy_to_previous_rev.provider_for_action(:deploy).all_releases - deploy_to_latest_rev.run_action(:deploy) - @latest_rev_all_releases = deploy_to_latest_rev.provider_for_action(:deploy).all_releases - deploy_to_previous_rev_again.run_action(:rollback) - # FIXME: only difference with previous test is using latest_rev_again insetad of previous_rev_again - @previous_rev_again_all_releases = deploy_to_latest_rev_again.provider_for_action(:deploy).all_releases - end - - the_app_is_deployed_at_revision(:previous_rev) - - it "restarts the application after rolling back" do - expect(actual_operations_order).to eq(%w{deploy_to_previous_rev deploy_to_latest_rev deploy_to_previous_rev_again}) - end - - it "is marked updated" do - expect(deploy_to_previous_rev_again).to be_updated_by_last_action - end - - it "deploys the right code" do - expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the third version of the app") - end - - it "all_releases after first deploy should have one entry" do - expect(@previous_rev_all_releases.length).to eq(1) - end - - it "all_releases after second deploy should have two entries" do - expect(@latest_rev_all_releases.length).to eq(2) - end - - it "all_releases after rollback should have one entry" do - expect(@previous_rev_again_all_releases.length).to eq(1) - end - - it "all_releases after rollback should be the same as after the first deploy" do - expect(@previous_rev_again_all_releases).to eq(@previous_rev_all_releases) - end - end - - describe "back to a previously deployed revision where resource rev == latest revision (explicit rollback)" do - before do - deploy_to_second_rev.run_action(:deploy) - @first_deploy_all_releases = deploy_to_second_rev.provider_for_action(:deploy).all_releases - deploy_to_previous_rev.run_action(:deploy) - @second_deploy_all_releases = deploy_to_previous_rev.provider_for_action(:deploy).all_releases - deploy_to_previous_rev_again.run_action(:rollback) - @third_deploy_all_releases = deploy_to_previous_rev_again.provider_for_action(:deploy).all_releases - deploy_to_latest_rev.run_action(:deploy) - @fourth_deploy_all_releases = deploy_to_latest_rev.provider_for_action(:deploy).all_releases - deploy_to_latest_rev_again.run_action(:rollback) - @fifth_deploy_all_releases = deploy_to_latest_rev_again.provider_for_action(:deploy).all_releases - end - - the_app_is_deployed_at_revision(:second_rev) - - it "restarts the application after rolling back" do - expect(actual_operations_order).to eq(%w{deploy_to_second_rev deploy_to_previous_rev deploy_to_previous_rev_again deploy_to_latest_rev deploy_to_latest_rev_again}) - end - - it "is marked updated" do - expect(deploy_to_latest_rev_again).to be_updated_by_last_action - end - - it "deploys the right code" do - expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the second version of the app") - end - - it "all_releases after rollback should have one entry" do - expect(@fifth_deploy_all_releases.length).to eq(1) - end - - it "all_releases after rollback should be the same as after the first deploy" do - expect(@fifth_deploy_all_releases).to eq(@first_deploy_all_releases) - end - end - - describe "back to a previously deployed revision where resource rev == latest revision (explicit rollback)" do - before do - deploy_to_second_rev.run_action(:deploy) - @first_deploy_all_releases = deploy_to_second_rev.provider_for_action(:deploy).all_releases - deploy_to_previous_rev.run_action(:deploy) - @second_deploy_all_releases = deploy_to_previous_rev.provider_for_action(:deploy).all_releases - deploy_to_second_rev_again.run_action(:rollback) - @third_deploy_all_releases = deploy_to_second_rev_again.provider_for_action(:deploy).all_releases - deploy_to_latest_rev.run_action(:deploy) - @fourth_deploy_all_releases = deploy_to_latest_rev.provider_for_action(:deploy).all_releases - deploy_to_second_rev_again_again.run_action(:rollback) - @fifth_deploy_all_releases = deploy_to_second_rev_again_again.provider_for_action(:deploy).all_releases - end - - the_app_is_deployed_at_revision(:second_rev) - - it "restarts the application after rolling back" do - expect(actual_operations_order).to eq(%w{deploy_to_second_rev deploy_to_previous_rev deploy_to_second_rev_again deploy_to_latest_rev deploy_to_second_rev_again_again}) - end - - it "is marked updated" do - expect(deploy_to_second_rev_again_again).to be_updated_by_last_action - end - - it "deploys the right code" do - expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the second version of the app") - end - - it "all_releases after rollback should have one entry" do - expect(@fifth_deploy_all_releases.length).to eq(1) - end - - it "all_releases after rollback should be the same as after the first deploy" do - expect(@fifth_deploy_all_releases).to eq(@first_deploy_all_releases) - end - - end - - # CHEF-3435 - describe "to a deploy_to path that does not yet exist" do - - let(:top_level_tmpdir) { Dir.mktmpdir } - - # override top level deploy_directory let block with one that is two - # directories deeper - let(:deploy_directory) { File.expand_path("nested/deeper", top_level_tmpdir) } - - after do - FileUtils.remove_entry_secure top_level_tmpdir - end - - before do - expect(File).not_to exist(deploy_directory) - deploy_to_latest_rev.run_action(:deploy) - end - - it "creates the required directory tree" do - expect(File).to be_directory(rel_path("releases")) - expect(File).to be_directory(rel_path("shared")) - expect(File).to be_directory(rel_path("releases/#{latest_rev}")) - - expect(File).to be_directory(rel_path("current/tmp")) - expect(File).to be_directory(rel_path("current/config")) - expect(File).to be_directory(rel_path("current/public")) - - expect(File).to be_symlink(rel_path("current")) - expect(File.readlink(rel_path("current"))).to eq(rel_path("releases/#{latest_rev}")) - end - - the_app_is_deployed_at_revision(:latest_rev) - - end - end - - context "when deploying an app with inline recipe callbacks" do - - # Use closures to capture and mutate this variable. This allows us to track - # ordering of operations. - callback_order = [] - - let(:deploy_to_latest_with_inline_recipes) do - deploy_to_latest_rev.dup.tap do |r| - r.symlink_before_migrate "config/config.ru" => "config.ru" - r.before_migrate do - callback_order << :before_migrate - - file "#{release_path}/before_migrate.txt" do - # The content here isn't relevant, but it gets printed when running - # the tests. Could be handy for debugging. - content callback_order.inspect - end - end - r.before_symlink do - callback_order << :before_symlink - - current_release_path = release_path - ruby_block "ensure before symlink" do - block do - if ::File.exist?(::File.join(current_release_path, "/tmp")) - raise "Ordering issue with provider, expected symlinks to not have been created" - end - end - end - - file "#{release_path}/before_symlink.txt" do - content callback_order.inspect - end - end - r.before_restart do - callback_order << :before_restart - - current_release_path = release_path - ruby_block "ensure after symlink" do - block do - unless ::File.exist?(::File.join(current_release_path, "/tmp")) - raise "Ordering issue with provider, expected symlinks to have been created" - end - end - end - - file "#{release_path}/tmp/before_restart.txt" do - content callback_order.inspect - end - end - r.after_restart do - callback_order << :after_restart - file "#{release_path}/tmp/after_restart.txt" do - content callback_order.inspect - end - end - end - end - - before do - callback_order.clear # callback_order variable is global for this context group - deploy_to_latest_with_inline_recipes.run_action(:deploy) - end - - the_app_is_deployed_at_revision(:latest_rev) - - it "is marked updated" do - expect(deploy_to_latest_with_inline_recipes).to be_updated_by_last_action - end - - it "calls the callbacks in order" do - expect(callback_order).to eq([:before_migrate, :before_symlink, :before_restart, :after_restart]) - end - - it "runs chef resources in the callbacks" do - expect(File).to exist(rel_path("current/before_migrate.txt")) - expect(File).to exist(rel_path("current/before_symlink.txt")) - expect(File).to exist(rel_path("current/tmp/before_restart.txt")) - expect(File).to exist(rel_path("current/tmp/after_restart.txt")) - end - end - - context "when deploying an app with in-repo callback scripts" do - let(:deploy_with_in_repo_callbacks) do - basic_deploy_resource.dup.tap do |r| - r.repo git_bundle_with_in_repo_callbacks - r.revision rev_with_in_repo_callbacks - end - end - - before do - deploy_with_in_repo_callbacks.run_action(:deploy) - end - - the_app_is_deployed_at_revision(:rev_with_in_repo_callbacks) - - it "runs chef resources in the callbacks" do - expect(File).to exist(rel_path("current/before_migrate.txt")) - expect(File).to exist(rel_path("current/before_symlink.txt")) - expect(File).to exist(rel_path("current/tmp/before_restart.txt")) - expect(File).to exist(rel_path("current/tmp/after_restart.txt")) - end - - end - - context "when deploying an app with migrations" do - let(:deploy_with_migration) do - basic_deploy_resource.dup.tap do |r| - - # Need this so we can call methods from this test inside the inline - # recipe callbacks - spec_context = self - - r.revision latest_rev - - # enable migrations - r.migrate true - # abuse `shell_restart_command` so we can observe order of when the - # miration command gets run - r.migration_command shell_restart_command("migration") - r.before_migrate do - - # inline recipe callbacks don't cwd, so you have to get the release - # directory as a local and "capture" it in the closure. - current_release = release_path - execute spec_context.shell_restart_command("before_migrate") do - cwd current_release - end - end - r.before_symlink do - current_release = release_path - execute spec_context.shell_restart_command("before_symlink") do - cwd current_release - end - end - - r.before_restart do - current_release = release_path - execute spec_context.shell_restart_command("before_restart") do - cwd current_release - end - end - - r.after_restart do - current_release = release_path - execute spec_context.shell_restart_command("after_restart") do - cwd current_release - end - end - - end - end - - before do - deploy_with_migration.run_action(:deploy) - end - - it "runs migrations in between the before_migrate and before_symlink steps" do - expect(actual_operations_order).to eq(%w{before_migrate migration before_symlink before_restart after_restart}) - end - end - - context "when deploying an app with in-repo symlinks" do - let(:deploy_with_in_repo_symlinks) do - basic_deploy_resource.dup.tap do |r| - r.repo git_bundle_with_in_repo_symlinks - r.revision rev_with_in_repo_symlinks - end - end - - it "should not raise an exception calling File.utime on symlinks" do - expect { deploy_with_in_repo_symlinks.run_action(:deploy) }.not_to raise_error - end - end - - context "when a previously deployed application has been nuked" do - - shared_examples_for "a redeployed application" do - - it "should redeploy the application" do - expect(File).to be_directory(rel_path("releases")) - expect(File).to be_directory(rel_path("shared")) - expect(File).to be_directory(rel_path("releases/#{latest_rev}")) - - expect(File).to be_directory(rel_path("current/tmp")) - expect(File).to be_directory(rel_path("current/config")) - expect(File).to be_directory(rel_path("current/public")) - - expect(File).to be_symlink(rel_path("current")) - expect(File.readlink(rel_path("current"))).to eq(rel_path("releases/#{latest_rev}")) - end - end - - # background: If a deployment is hosed and the user decides to rm -rf the - # deployment dir, deploy resource should detect that and nullify its cache. - - context "by removing the entire deploy directory" do - - before do - deploy_to_latest_rev.dup.run_action(:deploy) - FileUtils.rm_rf(deploy_directory) - deploy_to_latest_rev.dup.run_action(:deploy) - end - - include_examples "a redeployed application" - - end - - context "by removing the current/ directory" do - - before do - deploy_to_latest_rev.dup.run_action(:deploy) - FileUtils.rm(rel_path("current")) - deploy_to_latest_rev.dup.run_action(:deploy) - end - - include_examples "a redeployed application" - - end - end - - context "when a deployment fails" do - - shared_examples_for "a recovered deployment" do - - it "should redeploy the application" do - expect(File).to be_directory(rel_path("releases")) - expect(File).to be_directory(rel_path("shared")) - expect(File).to be_directory(rel_path("releases/#{latest_rev}")) - - expect(File).to be_directory(rel_path("current/tmp")) - expect(File).to be_directory(rel_path("current/config")) - expect(File).to be_directory(rel_path("current/public")) - - expect(File).to be_symlink(rel_path("current")) - expect(File.readlink(rel_path("current"))).to eq(rel_path("releases/#{latest_rev}")) - - # if callbacks ran, we know the app was deployed and not merely rolled - # back to a (busted) prior deployment. - expect(callback_order).to eq([:before_migrate, - :before_symlink, - :before_restart, - :after_restart ]) - end - end - - let!(:callback_order) { [] } - - let(:deploy_to_latest_with_callback_tracking) do - resource = deploy_to_latest_rev.dup - tracker = callback_order - resource.before_migrate { tracker << :before_migrate } - resource.before_symlink { tracker << :before_symlink } - resource.before_restart { tracker << :before_restart } - resource.after_restart { tracker << :after_restart } - resource - end - - [:before_migrate, :before_symlink, :before_restart, :after_restart].each do |callback| - - context "in the `#{callback}' callback" do - before do - expect { deploy_that_fails.run_action(:deploy) }.to raise_error(Exception, %r{I am a failed deploy}) - deploy_to_latest_with_callback_tracking.run_action(:deploy) - end - - let(:deploy_that_fails) do - resource = deploy_to_latest_rev.dup - errant_callback = lambda { |x| raise Exception, "I am a failed deploy" } - resource.send(callback, &errant_callback) - resource - end - - include_examples "a recovered deployment" - - end - - end - - context "in the service restart step" do - - let(:deploy_that_fails) do - resource = deploy_to_latest_rev.dup - resource.restart_command("RUBYOPT=\"\" ruby -e 'exit 1'") - resource - end - - before do - expect { deploy_that_fails.run_action(:deploy) }.to raise_error(Mixlib::ShellOut::ShellCommandFailed) - deploy_to_latest_with_callback_tracking.run_action(:deploy) - end - - include_examples "a recovered deployment" - end - - context "when cloning the app code" do - - class BadTimeScmProvider - def initialize(new_resource, run_context) - end - - def load_current_resource - end - - def revision_slug - "5" - end - - def run_action(action) - raise "network error" - end - end - - let(:deploy_that_fails) do - resource = deploy_to_latest_rev.dup - resource.scm_provider(BadTimeScmProvider) - resource - end - - before do - expect { deploy_that_fails.run_action(:deploy) }.to raise_error(RuntimeError, /network error/) - deploy_to_latest_with_callback_tracking.run_action(:deploy) - end - - include_examples "a recovered deployment" - end - - context "and then is deployed to a different revision" do - - let(:deploy_that_fails) do - resource = deploy_to_previous_rev.dup - resource.after_restart { |x| raise Exception, "I am a failed deploy" } - resource - end - - before do - expect { deploy_that_fails.run_action(:deploy) }.to raise_error(Exception, %r{I am a failed deploy}) - deploy_to_latest_rev.run_action(:deploy) - end - - it "removes the unsuccessful deploy after a later successful deploy" do - expect(::File).not_to exist(File.join(deploy_directory, "releases", previous_rev)) - end - - end - - end -end diff --git a/spec/unit/provider/deploy/revision_spec.rb b/spec/unit/provider/deploy/revision_spec.rb deleted file mode 100644 index 8f8280e11d..0000000000 --- a/spec/unit/provider/deploy/revision_spec.rb +++ /dev/null @@ -1,110 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2008-2016, Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "spec_helper" - -describe Chef::Provider::Deploy::Revision do - - before do - allow(ChefConfig).to receive(:windows?) { false } - @temp_dir = Dir.mktmpdir - Chef::Config[:file_cache_path] = @temp_dir - @resource = Chef::Resource::Deploy.new("/my/deploy/dir") - @resource.revision("8a3195bf3efa246f743c5dfa83683201880f935c") - @node = Chef::Node.new - @events = Chef::EventDispatch::Dispatcher.new - @run_context = Chef::RunContext.new(@node, {}, @events) - @provider = Chef::Provider::Deploy::Revision.new(@resource, @run_context) - @provider.load_current_resource - @runner = double("runnah") - allow(Chef::Runner).to receive(:new).and_return(@runner) - @expected_release_dir = "/my/deploy/dir/releases/8a3195bf3efa246f743c5dfa83683201880f935c" - end - - after do - # Make sure we don't keep any state in our tests - FileUtils.rm_rf @temp_dir if File.directory?( @temp_dir ) - end - - it "uses the resolved revision from the SCM as the release slug" do - allow(@provider.scm_provider).to receive(:revision_slug).and_return("uglySlugly") - expect(@provider.send(:release_slug)).to eq("uglySlugly") - end - - it "deploys to a dir named after the revision" do - expect(@provider.release_path).to eq(@expected_release_dir) - end - - it "stores the release dir in the file cache in the cleanup step" do - allow(FileUtils).to receive(:mkdir_p) - allow(FileUtils).to receive(:cp_r) - @provider.cleanup! - allow(@provider).to receive(:release_slug).and_return("73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2") - @provider.load_current_resource - @provider.cleanup! - second_release = "/my/deploy/dir/releases/73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2" - - expect(@provider.all_releases).to eq([@expected_release_dir, second_release]) - end - - it "removes a release from the file cache when it's used again in another release and append it to the end" do - allow(FileUtils).to receive(:mkdir_p) - allow(FileUtils).to receive(:cp_r) - @provider.cleanup! - allow(@provider).to receive(:release_slug).and_return("73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2") - @provider.load_current_resource - @provider.cleanup! - second_release = "/my/deploy/dir/releases/73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2" - expect(@provider.all_releases).to eq([@expected_release_dir, second_release]) - @provider.cleanup! - - allow(@provider).to receive(:release_slug).and_return("8a3195bf3efa246f743c5dfa83683201880f935c") - @provider.load_current_resource - @provider.cleanup! - expect(@provider.all_releases).to eq([second_release, @expected_release_dir]) - end - - it "removes a release from the file cache when it's deleted by :cleanup!" do - release_paths = %w{first second third fourth fifth}.map do |release_name| - "/my/deploy/dir/releases/#{release_name}" - end - release_paths.each do |release_path| - @provider.send(:release_created, release_path) - end - expect(@provider.all_releases).to eq(release_paths) - - allow(FileUtils).to receive(:rm_rf) - @provider.cleanup! - - expected_release_paths = (%w{second third fourth fifth} << @resource.revision).map do |release_name| - "/my/deploy/dir/releases/#{release_name}" - end - - expect(@provider.all_releases).to eq(expected_release_paths) - end - - it "regenerates the file cache if it's not available" do - oldest = "/my/deploy/dir/releases/oldest" - latest = "/my/deploy/dir/releases/latest" - expect(Dir).to receive(:glob).with("/my/deploy/dir/releases/*").and_return([latest, oldest]) - expect(::File).to receive(:ctime).with(oldest).and_return(Time.now - 10) - expect(::File).to receive(:ctime).with(latest).and_return(Time.now - 1) - expect(@provider.all_releases).to eq([oldest, latest]) - end - -end diff --git a/spec/unit/provider/deploy/timestamped_spec.rb b/spec/unit/provider/deploy/timestamped_spec.rb deleted file mode 100644 index fdb90bf438..0000000000 --- a/spec/unit/provider/deploy/timestamped_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2008-2016, Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "spec_helper" - -describe Chef::Provider::Deploy::Timestamped do - - before do - @release_time = Time.utc( 2004, 8, 15, 16, 23, 42) - allow(Time).to receive(:now).and_return(@release_time) - @expected_release_dir = "/my/deploy/dir/releases/20040815162342" - @resource = Chef::Resource::Deploy.new("/my/deploy/dir") - @node = Chef::Node.new - @events = Chef::EventDispatch::Dispatcher.new - @run_context = Chef::RunContext.new(@node, {}, @events) - @timestamped_deploy = Chef::Provider::Deploy::Timestamped.new(@resource, @run_context) - @runner = double("runnah") - allow(Chef::Runner).to receive(:new).and_return(@runner) - end - - it "gives a timestamp for release_slug" do - expect(@timestamped_deploy.send(:release_slug)).to eq("20040815162342") - end - -end diff --git a/spec/unit/provider/deploy_spec.rb b/spec/unit/provider/deploy_spec.rb deleted file mode 100644 index b0ede7e260..0000000000 --- a/spec/unit/provider/deploy_spec.rb +++ /dev/null @@ -1,641 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2008-2016, Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "spec_helper" - -describe Chef::Provider::Deploy do - - before do - allow(ChefConfig).to receive(:windows?) { false } - @release_time = Time.utc( 2004, 8, 15, 16, 23, 42) - allow(Time).to receive(:now).and_return(@release_time) - @expected_release_dir = "/my/deploy/dir/releases/20040815162342" - @resource = Chef::Resource::Deploy.new("/my/deploy/dir") - @node = Chef::Node.new - @events = Chef::EventDispatch::Dispatcher.new - @run_context = Chef::RunContext.new(@node, {}, @events) - @provider = Chef::Provider::Deploy.new(@resource, @run_context) - allow(@provider).to receive(:release_slug) - allow(@provider).to receive(:release_path).and_return(@expected_release_dir) - end - - it "loads scm resource" do - expect(@provider.scm_provider).to receive(:load_current_resource) - @provider.load_current_resource - end - - it "supports :deploy and :rollback actions" do - expect(@provider).to respond_to(:action_deploy) - expect(@provider).to respond_to(:action_rollback) - end - - context "when the deploy resource has a timeout attribute" do - let(:ten_seconds) { 10 } - before { @resource.timeout(ten_seconds) } - it "relays the timeout to the scm resource" do - expect(@provider.scm_provider.new_resource.timeout).to eq(ten_seconds) - end - end - - context "when the deploy resource has no timeout attribute" do - it "should not set a timeout on the scm resource" do - expect(@provider.scm_provider.new_resource.timeout).to be_nil - end - end - - context "when the deploy_to dir does not exist yet" do - before do - expect(FileUtils).to receive(:mkdir_p).with(@resource.deploy_to).ordered - expect(FileUtils).to receive(:mkdir_p).with(@resource.shared_path).ordered - allow(::File).to receive(:directory?).and_return(false) - allow(@provider).to receive(:symlink) - allow(@provider).to receive(:migrate) - allow(@provider).to receive(:copy_cached_repo) - end - - it "creates deploy_to dir" do - expect(::Dir).to receive(:chdir).with(@expected_release_dir).exactly(4).times - expect(@provider).to receive(:enforce_ownership).twice - allow(@provider).to receive(:update_cached_repo) - @provider.deploy - end - - end - - it "does not create deploy_to dir if it exists" do - allow(::File).to receive(:directory?).and_return(true) - expect(::Dir).to receive(:chdir).with(@expected_release_dir).exactly(4).times - expect(FileUtils).not_to receive(:mkdir_p).with(@resource.deploy_to) - expect(FileUtils).not_to receive(:mkdir_p).with(@resource.shared_path) - expect(@provider).to receive(:enforce_ownership).twice - allow(@provider).to receive(:copy_cached_repo) - allow(@provider).to receive(:update_cached_repo) - allow(@provider).to receive(:symlink) - allow(@provider).to receive(:migrate) - @provider.deploy - end - - it "ensures the deploy_to dir ownership after the verfication that it exists" do - expect(::Dir).to receive(:chdir).with(@expected_release_dir).exactly(4).times - expect(@provider).to receive(:verify_directories_exist).ordered - expect(@provider).to receive(:enforce_ownership).ordered - allow(@provider).to receive(:copy_cached_repo) - allow(@provider).to receive(:update_cached_repo) - allow(@provider).to receive(:install_gems) - expect(@provider).to receive(:enforce_ownership).ordered - allow(@provider).to receive(:enforce_ownership) - allow(@provider).to receive(:symlink) - allow(@provider).to receive(:migrate) - @provider.deploy - end - - it "updates and copies the repo, then does a migrate, symlink, restart, restart, cleanup on deploy" do - allow(FileUtils).to receive(:mkdir_p).with("/my/deploy/dir") - allow(FileUtils).to receive(:mkdir_p).with("/my/deploy/dir/shared") - expect(@provider).to receive(:enforce_ownership).twice - expect(@provider).to receive(:update_cached_repo) - expect(@provider).to receive(:copy_cached_repo) - expect(@provider).to receive(:install_gems) - expect(@provider).to receive(:callback).with(:before_migrate, nil) - expect(@provider).to receive(:migrate) - expect(@provider).to receive(:callback).with(:before_symlink, nil) - expect(@provider).to receive(:symlink) - expect(@provider).to receive(:callback).with(:before_restart, nil) - expect(@provider).to receive(:restart) - expect(@provider).to receive(:callback).with(:after_restart, nil) - expect(@provider).to receive(:cleanup!) - @provider.deploy - end - - it "should not deploy if there is already a deploy at release_path, and it is the current release" do - allow(@provider).to receive(:all_releases).and_return([@expected_release_dir]) - allow(@provider).to receive(:current_release?).with(@expected_release_dir).and_return(true) - expect(@provider).not_to receive(:deploy) - @provider.run_action(:deploy) - end - - it "should call action_rollback if there is already a deploy of this revision at release_path, and it is not the current release" do - allow(@provider).to receive(:all_releases).and_return([@expected_release_dir, "102021"]) - allow(@provider).to receive(:current_release?).with(@expected_release_dir).and_return(false) - expect(@provider).to receive(:rollback_to).with(@expected_release_dir) - expect(@provider).to receive(:current_release?) - @provider.run_action(:deploy) - end - - it "calls deploy when deploying a new release" do - allow(@provider).to receive(:all_releases).and_return([]) - expect(@provider).to receive(:deploy) - @provider.run_action(:deploy) - end - - it "runs action svn_force_export when new_resource.svn_force_export is true" do - @resource.svn_force_export true - expect(@provider.scm_provider).to receive(:run_action).with(:force_export) - @provider.update_cached_repo - end - - it "Removes the old release before deploying when force deploying over it" do - allow(@provider).to receive(:all_releases).and_return([@expected_release_dir]) - expect(FileUtils).to receive(:rm_rf).with(@expected_release_dir) - expect(@provider).to receive(:deploy) - @provider.run_action(:force_deploy) - end - - it "deploys as normal when force deploying and there's no prior release at the same path" do - allow(@provider).to receive(:all_releases).and_return([]) - expect(@provider).to receive(:deploy) - @provider.run_action(:force_deploy) - end - - it "dont care by default if error happens on deploy" do - allow(@provider).to receive(:all_releases).and_return(["previous_release"]) - allow(@provider).to receive(:deploy) { raise "Unexpected error" } - allow(@provider).to receive(:previous_release_path).and_return("previous_release") - expect(@provider).not_to receive(:rollback) - expect do - @provider.run_action(:deploy) - end.to raise_exception(RuntimeError, "Unexpected error") - end - - it "rollbacks to previous release if error happens on deploy" do - @resource.rollback_on_error true - allow(@provider).to receive(:all_releases).and_return(["previous_release"]) - allow(@provider).to receive(:deploy) { raise "Unexpected error" } - allow(@provider).to receive(:previous_release_path).and_return("previous_release") - expect(@provider).to receive(:rollback) - expect do - @provider.run_action(:deploy) - end.to raise_exception(RuntimeError, "Unexpected error") - end - - describe "on systems without broken Dir.glob results" do - it "sets the release path to the penultimate release when one is not specified, symlinks, and rm's the last release on rollback" do - allow(@provider).to receive(:release_path).and_return("/my/deploy/dir/releases/3") - all_releases = ["/my/deploy/dir/releases/1", "/my/deploy/dir/releases/2", "/my/deploy/dir/releases/3", "/my/deploy/dir/releases/4", "/my/deploy/dir/releases/5"] - allow(Dir).to receive(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) - expect(@provider).to receive(:symlink) - expect(FileUtils).to receive(:rm_rf).with("/my/deploy/dir/releases/4") - expect(FileUtils).to receive(:rm_rf).with("/my/deploy/dir/releases/5") - @provider.run_action(:rollback) - expect(@provider.release_path).to eql("/my/deploy/dir/releases/3") - expect(@provider.shared_path).to eql("/my/deploy/dir/shared") - end - - it "sets the release path to the specified release, symlinks, and rm's any newer releases on rollback" do - allow(@provider).to receive(:release_path).and_call_original - all_releases = ["/my/deploy/dir/releases/20040815162342", "/my/deploy/dir/releases/20040700000000", - "/my/deploy/dir/releases/20040600000000", "/my/deploy/dir/releases/20040500000000"].sort! - allow(Dir).to receive(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) - expect(@provider).to receive(:symlink) - expect(FileUtils).to receive(:rm_rf).with("/my/deploy/dir/releases/20040815162342") - @provider.run_action(:rollback) - expect(@provider.release_path).to eql("/my/deploy/dir/releases/20040700000000") - expect(@provider.shared_path).to eql("/my/deploy/dir/shared") - end - - it "sets the release path to the penultimate release, symlinks, and rm's the last release on rollback" do - allow(@provider).to receive(:release_path).and_call_original - all_releases = [ "/my/deploy/dir/releases/20040815162342", - "/my/deploy/dir/releases/20040700000000", - "/my/deploy/dir/releases/20040600000000", - "/my/deploy/dir/releases/20040500000000"] - allow(Dir).to receive(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) - expect(@provider).to receive(:symlink) - expect(FileUtils).to receive(:rm_rf).with("/my/deploy/dir/releases/20040815162342") - @provider.run_action(:rollback) - expect(@provider.release_path).to eql("/my/deploy/dir/releases/20040700000000") - expect(@provider.shared_path).to eql("/my/deploy/dir/shared") - end - - describe "if there are no releases to fallback to" do - - it "an exception is raised when there is only 1 release" do - #@provider.unstub(:release_path) -- unstub the release path on top to feed our own release path - all_releases = [ "/my/deploy/dir/releases/20040815162342"] - allow(Dir).to receive(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) - #@provider.should_receive(:symlink) - #FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/releases/20040815162342") - #@provider.run_action(:rollback) - #@provider.release_path.should eql(NIL) -- no check needed since assertions will fail - expect do - @provider.run_action(:rollback) - end.to raise_exception(RuntimeError, "There is no release to rollback to!") - end - - it "an exception is raised when there are no releases" do - all_releases = [] - allow(Dir).to receive(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) - expect do - @provider.run_action(:rollback) - end.to raise_exception(RuntimeError, "There is no release to rollback to!") - end - end - end - - describe "CHEF-628: on systems with broken Dir.glob results" do - it "sets the release path to the penultimate release, symlinks, and rm's the last release on rollback" do - allow(@provider).to receive(:release_path).and_call_original - all_releases = [ "/my/deploy/dir/releases/20040500000000", - "/my/deploy/dir/releases/20040600000000", - "/my/deploy/dir/releases/20040700000000", - "/my/deploy/dir/releases/20040815162342" ] - allow(Dir).to receive(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) - expect(@provider).to receive(:symlink) - expect(FileUtils).to receive(:rm_rf).with("/my/deploy/dir/releases/20040815162342") - @provider.run_action(:rollback) - expect(@provider.release_path).to eql("/my/deploy/dir/releases/20040700000000") - expect(@provider.shared_path).to eql("/my/deploy/dir/shared") - end - end - - it "raises a runtime error when there's no release to rollback to" do - all_releases = [] - allow(Dir).to receive(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) - expect { @provider.run_action(:rollback) }.to raise_error(RuntimeError) - end - - it "runs the new resource collection in the runner during a callback" do - @runner = double("Runner") - allow(Chef::Runner).to receive(:new).and_return(@runner) - expect(@runner).to receive(:converge) - callback_code = Proc.new { :noop } - @provider.callback(:whatevs, callback_code) - end - - it "loads callback files from the release/ dir if the file exists" do - foo_callback = @expected_release_dir + "/deploy/foo.rb" - expect(::File).to receive(:exist?).with(foo_callback).once.and_return(true) - expect(::Dir).to receive(:chdir).with(@expected_release_dir).and_yield - expect(@provider).to receive(:from_file).with(foo_callback) - @provider.callback(:foo, "deploy/foo.rb") - end - - it "raises a runtime error if a callback file is explicitly specified but does not exist" do - baz_callback = "/deploy/baz.rb" - expect(::File).to receive(:exist?).with("#{@expected_release_dir}/#{baz_callback}").and_return(false) - @resource.before_migrate baz_callback - @provider.define_resource_requirements - @provider.action = :deploy - expect { @provider.process_resource_requirements }.to raise_error(RuntimeError) - end - - it "runs a default callback if the callback code is nil" do - bar_callback = @expected_release_dir + "/deploy/bar.rb" - expect(::File).to receive(:exist?).with(bar_callback).and_return(true) - expect(::Dir).to receive(:chdir).with(@expected_release_dir).and_yield - expect(@provider).to receive(:from_file).with(bar_callback) - @provider.callback(:bar, nil) - end - - it "skips an eval callback if the file doesn't exist" do - barbaz_callback = @expected_release_dir + "/deploy/barbaz.rb" - expect(::File).to receive(:exist?).with(barbaz_callback).and_return(false) - expect(::Dir).to receive(:chdir).with(@expected_release_dir).and_yield - expect(@provider).not_to receive(:from_file) - @provider.callback(:barbaz, nil) - end - - # CHEF-3449 #converge_by is called in #recipe_eval and must happen in sequence - # with the other calls to #converge_by to keep the train on the tracks - it "evaluates a callback file before the corresponding step" do - expect(@provider).to receive(:verify_directories_exist) - expect(@provider).to receive(:update_cached_repo) - expect(@provider).to receive(:enforce_ownership) - expect(@provider).to receive(:copy_cached_repo) - expect(@provider).to receive(:install_gems) - expect(@provider).to receive(:enforce_ownership) - expect(@provider).to receive(:converge_by).ordered # before_migrate - expect(@provider).to receive(:migrate).ordered - expect(@provider).to receive(:converge_by).ordered # before_symlink - expect(@provider).to receive(:symlink).ordered - expect(@provider).to receive(:converge_by).ordered # before_restart - expect(@provider).to receive(:restart).ordered - expect(@provider).to receive(:converge_by).ordered # after_restart - expect(@provider).to receive(:cleanup!) - @provider.deploy - end - - it "gets a SCM provider as specified by its resource" do - expect(@provider.scm_provider).to be_an_instance_of(Chef::Provider::Git) - expect(@provider.scm_provider.new_resource.destination).to eql("/my/deploy/dir/shared/cached-copy") - end - - it "syncs the cached copy of the repo" do - expect(@provider.scm_provider).to receive(:run_action).with(:sync) - @provider.update_cached_repo - end - - it "makes a copy of the cached repo in releases dir" do - expect(FileUtils).to receive(:mkdir_p).with("/my/deploy/dir/releases") - expect(FileUtils).to receive(:cp_r).with("/my/deploy/dir/shared/cached-copy/.", @expected_release_dir, :preserve => true) - @provider.copy_cached_repo - end - - it "calls the internal callback :release_created when cleaning up the releases" do - allow(FileUtils).to receive(:mkdir_p) - allow(FileUtils).to receive(:cp_r) - expect(@provider).to receive(:release_created) - @provider.cleanup! - end - - it "chowns the whole release dir to user and group specified in the resource" do - @resource.user "foo" - @resource.group "bar" - expect(FileUtils).to receive(:chown_R).with("foo", "bar", "/my/deploy/dir", { :force => true }) - @provider.enforce_ownership - end - - it "skips the migration when resource.migrate => false but runs symlinks before migration" do - @resource.migrate false - expect(@provider).not_to receive :shell_out! - expect(@provider).to receive :run_symlinks_before_migrate - @provider.migrate - end - - it "links the database.yml and runs resource.migration_command when resource.migrate #=> true" do - @resource.migrate true - @resource.migration_command "migration_foo" - @resource.user "deployNinja" - @resource.group "deployNinjas" - @resource.environment "RAILS_ENV" => "production" - expect(FileUtils).to receive(:ln_sf).with("/my/deploy/dir/shared/config/database.yml", @expected_release_dir + "/config/database.yml") - expect(@provider).to receive(:enforce_ownership) - - allow(STDOUT).to receive(:tty?).and_return(true) - allow(Chef::Log).to receive(:info?).and_return(true) - expect(@provider).to receive(:shell_out!).with("migration_foo", :cwd => @expected_release_dir, - :user => "deployNinja", :group => "deployNinjas", - :log_level => :info, :live_stream => STDOUT, - :log_tag => "deploy[/my/deploy/dir]", - :environment => { "RAILS_ENV" => "production" }) - @provider.migrate - end - - it "purges the current release's /log /tmp/pids/ and /public/system directories" do - expect(FileUtils).to receive(:rm_rf).with(@expected_release_dir + "/log") - expect(FileUtils).to receive(:rm_rf).with(@expected_release_dir + "/tmp/pids") - expect(FileUtils).to receive(:rm_rf).with(@expected_release_dir + "/public/system") - @provider.purge_tempfiles_from_current_release - end - - it "symlinks temporary files and logs from the shared dir into the current release" do - allow(FileUtils).to receive(:mkdir_p).with(@resource.shared_path + "/system") - allow(FileUtils).to receive(:mkdir_p).with(@resource.shared_path + "/pids") - allow(FileUtils).to receive(:mkdir_p).with(@resource.shared_path + "/log") - expect(FileUtils).to receive(:mkdir_p).with(@expected_release_dir + "/tmp") - expect(FileUtils).to receive(:mkdir_p).with(@expected_release_dir + "/public") - expect(FileUtils).to receive(:mkdir_p).with(@expected_release_dir + "/config") - expect(FileUtils).to receive(:ln_sf).with("/my/deploy/dir/shared/system", @expected_release_dir + "/public/system") - expect(FileUtils).to receive(:ln_sf).with("/my/deploy/dir/shared/pids", @expected_release_dir + "/tmp/pids") - expect(FileUtils).to receive(:ln_sf).with("/my/deploy/dir/shared/log", @expected_release_dir + "/log") - expect(FileUtils).to receive(:ln_sf).with("/my/deploy/dir/shared/config/database.yml", @expected_release_dir + "/config/database.yml") - expect(@provider).to receive(:enforce_ownership) - @provider.link_tempfiles_to_current_release - end - - it "symlinks the current release dir into production" do - expect(FileUtils).to receive(:rm_f).with("/my/deploy/dir/current") - expect(FileUtils).to receive(:ln_sf).with(@expected_release_dir, "/my/deploy/dir/current") - expect(@provider).to receive(:enforce_ownership) - @provider.link_current_release_to_production - end - - context "with a customized app layout" do - - before do - @resource.purge_before_symlink(%w{foo bar}) - @resource.create_dirs_before_symlink(%w{baz qux}) - @resource.symlinks "foo/bar" => "foo/bar", "baz" => "qux/baz" - @resource.symlink_before_migrate "radiohead/in_rainbows.yml" => "awesome" - end - - it "purges the purge_before_symlink directories" do - expect(FileUtils).to receive(:rm_rf).with(@expected_release_dir + "/foo") - expect(FileUtils).to receive(:rm_rf).with(@expected_release_dir + "/bar") - @provider.purge_tempfiles_from_current_release - end - - it "symlinks files from the shared directory to the current release directory" do - expect(FileUtils).to receive(:mkdir_p).with(@expected_release_dir + "/baz") - expect(FileUtils).to receive(:mkdir_p).with(@expected_release_dir + "/qux") - allow(FileUtils).to receive(:mkdir_p).with(@resource.shared_path + "/foo/bar") - allow(FileUtils).to receive(:mkdir_p).with(@resource.shared_path + "/baz") - expect(FileUtils).to receive(:ln_sf).with("/my/deploy/dir/shared/foo/bar", @expected_release_dir + "/foo/bar") - expect(FileUtils).to receive(:ln_sf).with("/my/deploy/dir/shared/baz", @expected_release_dir + "/qux/baz") - expect(FileUtils).to receive(:ln_sf).with("/my/deploy/dir/shared/radiohead/in_rainbows.yml", @expected_release_dir + "/awesome") - expect(@provider).to receive(:enforce_ownership) - @provider.link_tempfiles_to_current_release - end - - end - - it "does nothing for restart if restart_command is empty" do - expect(@provider).not_to receive(:shell_out!) - @provider.restart - end - - it "runs the restart command in the current application dir when the resource has a restart_command" do - @resource.restart_command "restartcmd" - expect(@provider).to receive(:shell_out!).with("restartcmd", :cwd => "/my/deploy/dir/current", :log_tag => "deploy[/my/deploy/dir]", :log_level => :debug) - @provider.restart - end - - it "lists all available releases" do - all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000", - "/my/deploy/dir/20040600000000", "/my/deploy/dir/20040500000000"].sort! - expect(Dir).to receive(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) - expect(@provider.all_releases).to eql(all_releases) - end - - it "removes all but the 5 newest releases" do - all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000", - "/my/deploy/dir/20040600000000", "/my/deploy/dir/20040500000000", - "/my/deploy/dir/20040400000000", "/my/deploy/dir/20040300000000", - "/my/deploy/dir/20040200000000", "/my/deploy/dir/20040100000000"].sort! - allow(@provider).to receive(:all_releases).and_return(all_releases) - expect(FileUtils).to receive(:rm_rf).with("/my/deploy/dir/20040100000000") - expect(FileUtils).to receive(:rm_rf).with("/my/deploy/dir/20040200000000") - expect(FileUtils).to receive(:rm_rf).with("/my/deploy/dir/20040300000000") - @provider.cleanup! - end - - it "removes all but a certain number of releases when the resource has a keep_releases" do - @resource.keep_releases 7 - all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000", - "/my/deploy/dir/20040600000000", "/my/deploy/dir/20040500000000", - "/my/deploy/dir/20040400000000", "/my/deploy/dir/20040300000000", - "/my/deploy/dir/20040200000000", "/my/deploy/dir/20040100000000"].sort! - allow(@provider).to receive(:all_releases).and_return(all_releases) - expect(FileUtils).to receive(:rm_rf).with("/my/deploy/dir/20040100000000") - @provider.cleanup! - end - - it "fires a callback for :release_deleted when deleting an old release" do - all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000", - "/my/deploy/dir/20040600000000", "/my/deploy/dir/20040500000000", - "/my/deploy/dir/20040400000000", "/my/deploy/dir/20040300000000"].sort! - allow(@provider).to receive(:all_releases).and_return(all_releases) - allow(FileUtils).to receive(:rm_rf) - expect(@provider).to receive(:release_deleted).with("/my/deploy/dir/20040300000000") - @provider.cleanup! - end - - it "puts resource.to_hash in @configuration for backwards compat with capistano-esque deploy hooks" do - expect(@provider.instance_variable_get(:@configuration)).to eq(@resource.to_hash) - end - - it "sets @configuration[:environment] to the value of RAILS_ENV for backwards compat reasons" do - resource = Chef::Resource::Deploy.new("/my/deploy/dir") - resource.environment "production" - provider = Chef::Provider::Deploy.new(resource, @run_context) - expect(provider.instance_variable_get(:@configuration)[:environment]).to eql("production") - end - - it "shouldn't give a no method error on migrate if the environment is nil" do - allow(@provider).to receive(:enforce_ownership) - allow(@provider).to receive(:run_symlinks_before_migrate) - allow(@provider).to receive(:shell_out!) - @provider.migrate - - end - - context "using inline recipes for callbacks" do - - it "runs an inline recipe with the provided block for :callback_name == {:recipe => &block} " do - snitch = nil - recipe_code = Proc.new { snitch = 42 } - #@provider.should_receive(:instance_eval).with(&recipe_code) - @provider.callback(:whateverz, recipe_code) - expect(snitch).to eq(42) - end - - it "loads a recipe file from the specified path and from_file evals it" do - expect(::File).to receive(:exist?).with(@expected_release_dir + "/chefz/foobar_callback.rb").once.and_return(true) - expect(::Dir).to receive(:chdir).with(@expected_release_dir).and_yield - expect(@provider).to receive(:from_file).with(@expected_release_dir + "/chefz/foobar_callback.rb") - @provider.callback(:whateverz, "chefz/foobar_callback.rb") - end - - it "instance_evals a block/proc for restart command" do - snitch = nil - restart_cmd = Proc.new { snitch = 42 } - @resource.restart(&restart_cmd) - @provider.restart - expect(snitch).to eq(42) - end - - end - - describe "API bridge to capistrano" do - it "defines sudo as a forwarder to execute" do - expect(@provider).to receive(:execute).with("the moon, fool") - @provider.sudo("the moon, fool") - end - - it "defines run as a forwarder to execute, setting the user, group, cwd and environment to new_resource.user" do - mock_execution = double("Resource::Execute") - expect(@provider).to receive(:execute).with("iGoToHell4this").and_return(mock_execution) - @resource.user("notCoolMan") - @resource.group("Ggroup") - @resource.environment("APP_ENV" => "staging") - @resource.deploy_to("/my/app") - expect(mock_execution).to receive(:user).with("notCoolMan") - expect(mock_execution).to receive(:group).with("Ggroup") - expect(mock_execution).to receive(:cwd) { |*args| - if args.empty? - nil - else - expect(args.size).to eq(1) - expect(args.first).to eq(@provider.release_path) - end - }.twice - expect(mock_execution).to receive(:environment) { |*args| - if args.empty? - nil - else - expect(args.size).to eq(1) - expect(args.first).to eq({ "APP_ENV" => "staging" }) - end - }.twice - @provider.run("iGoToHell4this") - - end - - it "defines run as a forwarder to execute, setting cwd and environment but not override" do - mock_execution = double("Resource::Execute") - expect(@provider).to receive(:execute).with("iGoToHell4this").and_return(mock_execution) - @resource.user("notCoolMan") - expect(mock_execution).to receive(:user).with("notCoolMan") - expect(mock_execution).to receive(:cwd).with(no_args()).and_return("/some/value") - expect(mock_execution).to receive(:environment).with(no_args()).and_return({}) - @provider.run("iGoToHell4this") - end - - it "converts sudo and run to exec resources in hooks" do - runner = double("tehRunner") - allow(Chef::Runner).to receive(:new).and_return(runner) - - snitch = nil - @resource.user("tehCat") - - callback_code = Proc.new do - snitch = 42 - temp_collection = resource_collection - run("tehMice") - snitch = temp_collection.lookup("execute[tehMice]") - end - - expect(runner).to receive(:converge) - # - @provider.callback(:phony, callback_code) - expect(snitch).to be_an_instance_of(Chef::Resource::Execute) - expect(snitch.user).to eq("tehCat") - end - end - - describe "installing gems from a gems.yml" do - - before do - allow(::File).to receive(:exist?).with("#{@expected_release_dir}/gems.yml").and_return(true) - @gem_list = [{ :name => "eventmachine", :version => "0.12.9" }] - end - - it "reads a gems.yml file, creating gem providers for each with action :upgrade" do - expect(IO).to receive(:read).with("#{@expected_release_dir}/gems.yml").and_return("cookie") - expect(YAML).to receive(:load).with("cookie").and_return(@gem_list) - - gems = @provider.send(:gem_packages) - - expect(gems.map { |g| g.action }).to eq([%i{install}]) - expect(gems.map { |g| g.name }).to eq(%w{eventmachine}) - expect(gems.map { |g| g.version }).to eq(%w{0.12.9}) - end - - it "takes a list of gem providers converges them" do - allow(IO).to receive(:read) - allow(YAML).to receive(:load).and_return(@gem_list) - expected_gem_resources = @provider.send(:gem_packages).map { |r| [r.name, r.version] } - gem_runner = @provider.send(:gem_resource_collection_runner) - # no one has heard of defining == to be meaningful so I have use this monstrosity - actual = gem_runner.run_context.resource_collection.all_resources.map { |r| [r.name, r.version] } - expect(actual).to eq(expected_gem_resources) - end - - end - -end diff --git a/spec/unit/provider/erl_call_spec.rb b/spec/unit/provider/erl_call_spec.rb deleted file mode 100644 index b5d3ae8c07..0000000000 --- a/spec/unit/provider/erl_call_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -# -# Author:: Joe Williams () -# Copyright:: Copyright 2009-2016, Joe Williams -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "spec_helper" - -describe Chef::Provider::ErlCall do - before(:each) do - @node = Chef::Node.new - @events = Chef::EventDispatch::Dispatcher.new - @run_context = Chef::RunContext.new(@node, {}, @events) - - @new_resource = Chef::Resource::ErlCall.new("test", @node) - @new_resource.code("io:format(\"burritos\", []).") - @new_resource.node_name("chef@localhost") - @new_resource.name("test") - - @provider = Chef::Provider::ErlCall.new(@new_resource, @run_context) - - @status = double("Status", stdout: "{ok, woohoo}", stderr: "") - allow(@provider).to receive(:shell_out!).and_return(@status) - end - - it "should return a Chef::Provider::ErlCall object" do - provider = Chef::Provider::ErlCall.new(@new_resource, @run_context) - expect(provider).to be_a_kind_of(Chef::Provider::ErlCall) - end - - it "should return true" do - expect(@provider.load_current_resource).to eql(true) - end - - describe "when running a distributed erl call resource" do - before do - @new_resource.cookie("nomnomnom") - @new_resource.distributed(true) - @new_resource.name_type("sname") - end - - it "should write to stdin of the erl_call command" do - expected_cmd = "erl_call -e -s -sname chef@localhost -c nomnomnom" - expect(@provider).to receive(:shell_out!).with(expected_cmd, input: @new_resource.code).and_return(@status) - - @provider.action_run - end - end - - describe "when running a local erl call resource" do - before do - @new_resource.cookie(nil) - @new_resource.distributed(false) - @new_resource.name_type("name") - end - - it "should write to stdin of the erl_call command" do - expected_cmd = "erl_call -e -name chef@localhost " - expect(@provider).to receive(:shell_out!).with(expected_cmd, input: @new_resource.code).and_return(@status) - - @provider.action_run - end - end - -end diff --git a/spec/unit/provider_resolver_spec.rb b/spec/unit/provider_resolver_spec.rb index d1aaa6a8ea..a331093055 100644 --- a/spec/unit/provider_resolver_spec.rb +++ b/spec/unit/provider_resolver_spec.rb @@ -558,10 +558,7 @@ describe Chef::ProviderResolver do chef_gem: [ Chef::Resource::ChefGem, Chef::Provider::Package::Rubygems ], cookbook_file: [ Chef::Resource::CookbookFile, Chef::Provider::CookbookFile ], csh: [ Chef::Resource::Csh, Chef::Provider::Script ], - deploy: [ Chef::Resource::Deploy, Chef::Provider::Deploy::Timestamped ], - deploy_revision: [ Chef::Resource::DeployRevision, Chef::Provider::Deploy::Revision ], directory: [ Chef::Resource::Directory, Chef::Provider::Directory ], - erl_call: [ Chef::Resource::ErlCall, Chef::Provider::ErlCall ], execute: [ Chef::Resource::Execute, Chef::Provider::Execute ], file: [ Chef::Resource::File, Chef::Provider::File ], gem_package: [ Chef::Resource::GemPackage, Chef::Provider::Package::Rubygems ], @@ -585,7 +582,6 @@ describe Chef::ProviderResolver do script: [ Chef::Resource::Script, Chef::Provider::Script ], subversion: [ Chef::Resource::Subversion, Chef::Provider::Subversion ], template: [ Chef::Resource::Template, Chef::Provider::Template ], - timestamped_deploy: [ Chef::Resource::TimestampedDeploy, Chef::Provider::Deploy::Timestamped ], aix_user: [ Chef::Resource::User::AixUser, Chef::Provider::User::Aix ], dscl_user: [ Chef::Resource::User::DsclUser, Chef::Provider::User::Dscl ], linux_user: [ Chef::Resource::User::LinuxUser, Chef::Provider::User::Linux ], diff --git a/spec/unit/resource/deploy_revision_spec.rb b/spec/unit/resource/deploy_revision_spec.rb deleted file mode 100644 index aa12b9595d..0000000000 --- a/spec/unit/resource/deploy_revision_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2009-2016, Daniel DeLeo -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "spec_helper" -require "support/shared/unit/resource/static_provider_resolution" - -describe Chef::Resource::DeployRevision do - - static_provider_resolution( - resource: Chef::Resource::DeployRevision, - provider: Chef::Provider::Deploy::Revision, - name: :deploy_revision, - action: :deploy - ) - -end - -describe Chef::Resource::DeployBranch do - - static_provider_resolution( - resource: Chef::Resource::DeployBranch, - provider: Chef::Provider::Deploy::Revision, - name: :deploy_branch, - action: :deploy - ) - -end diff --git a/spec/unit/resource/deploy_spec.rb b/spec/unit/resource/deploy_spec.rb deleted file mode 100644 index fe3d6972da..0000000000 --- a/spec/unit/resource/deploy_spec.rb +++ /dev/null @@ -1,283 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2008-2017, Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "spec_helper" -require "support/shared/unit/resource/static_provider_resolution" - -describe Chef::Resource::Deploy do - - static_provider_resolution( - resource: Chef::Resource::Deploy, - provider: Chef::Provider::Deploy::Timestamped, - name: :deploy, - action: :deploy - ) - - class << self - def resource_has_a_string_attribute(attr_name) - it "has a String attribute for #{attr_name}" do - @resource.send(attr_name, "this is a string") - expect(@resource.send(attr_name)).to eql("this is a string") - expect { @resource.send(attr_name, 8675309) }.to raise_error(ArgumentError) - end - end - - def resource_has_a_boolean_attribute(attr_name, opts = { :defaults_to => false }) - it "has a Boolean attribute for #{attr_name}" do - expect(@resource.send(attr_name)).to eql(opts[:defaults_to]) - @resource.send(attr_name, !opts[:defaults_to]) - expect(@resource.send(attr_name)).to eql( !opts[:defaults_to] ) - end - end - - def resource_has_a_callback_attribute(attr_name) - it "has a Callback attribute #{attr_name}" do - callback_block = lambda { :noop } - expect { @resource.send(attr_name, &callback_block) }.not_to raise_error - expect(@resource.send(attr_name)).to eq(callback_block) - callback_file = "path/to/callback.rb" - expect { @resource.send(attr_name, callback_file) }.not_to raise_error - expect(@resource.send(attr_name)).to eq(callback_file) - expect { @resource.send(attr_name, :this_is_fail) }.to raise_error(ArgumentError) - end - end - end - - before do - @resource = Chef::Resource::Deploy.new("/my/deploy/dir") - end - - resource_has_a_string_attribute(:repo) - resource_has_a_string_attribute(:deploy_to) - resource_has_a_string_attribute(:role) - resource_has_a_string_attribute(:restart_command) - resource_has_a_string_attribute(:migration_command) - resource_has_a_string_attribute(:user) - resource_has_a_string_attribute(:group) - resource_has_a_string_attribute(:repository_cache) - resource_has_a_string_attribute(:copy_exclude) - resource_has_a_string_attribute(:revision) - resource_has_a_string_attribute(:remote) - resource_has_a_string_attribute(:git_ssh_wrapper) - resource_has_a_string_attribute(:svn_username) - resource_has_a_string_attribute(:svn_password) - resource_has_a_string_attribute(:svn_arguments) - resource_has_a_string_attribute(:svn_info_args) - - resource_has_a_boolean_attribute(:migrate, :defaults_to => false) - resource_has_a_boolean_attribute(:enable_submodules, :defaults_to => false) - resource_has_a_boolean_attribute(:shallow_clone, :defaults_to => false) - - it "uses the first argument as the deploy directory" do - expect(@resource.deploy_to).to eql("/my/deploy/dir") - end - - # For git, any revision, branch, tag, whatever is resolved to a SHA1 ref. - # For svn, the branch is included in the repo URL. - # Therefore, revision and branch ARE NOT SEPARATE THINGS - it "aliases #revision as #branch" do - @resource.branch "stable" - expect(@resource.revision).to eql("stable") - end - - it "takes the SCM resource to use as a constant, and defaults to git" do - expect(@resource.scm_provider).to eql(Chef::Provider::Git) - @resource.scm_provider Chef::Provider::Subversion - expect(@resource.scm_provider).to eql(Chef::Provider::Subversion) - end - - it "allows scm providers to be set via symbol" do - expect(@resource.scm_provider).to eq(Chef::Provider::Git) - @resource.scm_provider :subversion - expect(@resource.scm_provider).to eq(Chef::Provider::Subversion) - end - - it "allows scm providers to be set via string" do - expect(@resource.scm_provider).to eq(Chef::Provider::Git) - @resource.scm_provider "subversion" - expect(@resource.scm_provider).to eq(Chef::Provider::Subversion) - end - - it "has a boolean attribute for svn_force_export defaulting to false" do - expect(@resource.svn_force_export).to be_falsey - @resource.svn_force_export true - expect(@resource.svn_force_export).to be_truthy - expect { @resource.svn_force_export(10053) }.to raise_error(ArgumentError) - end - - it "takes arbitrary environment variables in a hash" do - @resource.environment "RAILS_ENV" => "production" - expect(@resource.environment).to eq({ "RAILS_ENV" => "production" }) - end - - it "takes string arguments to environment for backwards compat, setting RAILS_ENV, RACK_ENV, and MERB_ENV" do - @resource.environment "production" - expect(@resource.environment).to eq({ "RAILS_ENV" => "production", "RACK_ENV" => "production", "MERB_ENV" => "production" }) - end - - it "sets destination to $deploy_to/shared/$repository_cache" do - expect(@resource.destination).to eql("/my/deploy/dir/shared/cached-copy") - end - - it "sets shared_path to $deploy_to/shared" do - expect(@resource.shared_path).to eql("/my/deploy/dir/shared") - end - - it "sets current_path to $deploy_to/current" do - expect(@resource.current_path).to eql("/my/deploy/dir/current") - end - - it "gets the current_path correct even if the shared_path is set (regression test)" do - @resource.shared_path - expect(@resource.current_path).to eql("/my/deploy/dir/current") - end - - it "allows depth to be set via integer" do - expect(@resource.depth).to be_nil - @resource.depth 1 - expect(@resource.depth).to eql(1) - end - - it "gives #depth as 5 if shallow clone is true, nil otherwise" do - expect(@resource.depth).to be_nil - @resource.shallow_clone true - expect(@resource.depth).to eql(5) - end - - it "aliases repo as repository" do - @resource.repository "git@github.com/opcode/cookbooks.git" - expect(@resource.repo).to eql("git@github.com/opcode/cookbooks.git") - end - - it "aliases git_ssh_wrapper as ssh_wrapper" do - @resource.ssh_wrapper "git_my_repo.sh" - expect(@resource.git_ssh_wrapper).to eql("git_my_repo.sh") - end - - it "has an Array attribute purge_before_symlink, default: log, tmp/pids, public/system" do - expect(@resource.purge_before_symlink).to eq(%w{ log tmp/pids public/system }) - @resource.purge_before_symlink %w{foo bar baz} - expect(@resource.purge_before_symlink).to eq(%w{foo bar baz}) - end - - it "has an Array attribute create_dirs_before_symlink, default: tmp, public, config" do - expect(@resource.create_dirs_before_symlink).to eq(%w{tmp public config}) - @resource.create_dirs_before_symlink %w{foo bar baz} - expect(@resource.create_dirs_before_symlink).to eq(%w{foo bar baz}) - end - - it 'has a Hash attribute symlinks, default: {"system" => "public/system", "pids" => "tmp/pids", "log" => "log"}' do - default = { "system" => "public/system", "pids" => "tmp/pids", "log" => "log" } - expect(@resource.symlinks).to eq(default) - @resource.symlinks "foo" => "bar/baz" - expect(@resource.symlinks).to eq({ "foo" => "bar/baz" }) - end - - it 'has a Hash attribute symlink_before_migrate, default "config/database.yml" => "config/database.yml"' do - expect(@resource.symlink_before_migrate).to eq({ "config/database.yml" => "config/database.yml" }) - @resource.symlink_before_migrate "wtf?" => "wtf is going on" - expect(@resource.symlink_before_migrate).to eq({ "wtf?" => "wtf is going on" }) - end - - resource_has_a_callback_attribute :before_migrate - resource_has_a_callback_attribute :before_symlink - resource_has_a_callback_attribute :before_restart - resource_has_a_callback_attribute :after_restart - - it "aliases restart_command as restart" do - @resource.restart "foobaz" - expect(@resource.restart_command).to eq("foobaz") - end - - it "takes a block for the restart parameter" do - restart_like_this = lambda { p :noop } - @resource.restart(&restart_like_this) - expect(@resource.restart).to eq(restart_like_this) - end - - it "allows providers to be set with a full class name" do - @resource.provider Chef::Provider::Deploy::Timestamped - expect(@resource.provider).to eq(Chef::Provider::Deploy::Timestamped) - end - - it "allows deploy providers to be set via symbol" do - @resource.provider :deploy_revision - expect(@resource.provider).to eq(Chef::Provider::Deploy::Revision) - end - - it "allows deploy providers to be set via string" do - @resource.provider "deploy_revision" - expect(@resource.provider).to eq(Chef::Provider::Deploy::Revision) - end - - it "defaults keep_releases to 5" do - expect(@resource.keep_releases).to eq(5) - end - - it "allows keep_releases to be set via integer" do - @resource.keep_releases 10 - expect(@resource.keep_releases).to eq(10) - end - - it "enforces a minimum keep_releases of 1" do - @resource.keep_releases 0 - expect(@resource.keep_releases).to eq(1) - end - - describe "when it has a timeout attribute" do - let(:ten_seconds) { 10 } - before { @resource.timeout(ten_seconds) } - it "stores this timeout" do - expect(@resource.timeout).to eq(ten_seconds) - end - end - - describe "when it has no timeout attribute" do - it "has no default timeout" do - expect(@resource.timeout).to be_nil - end - end - - describe "when it has meta application root, revision, user, group, - scm provider, repository cache, environment, simlinks and migrate" do - before do - @resource.repository("http://uri.org") - @resource.deploy_to("/") - @resource.revision("1.2.3") - @resource.user("root") - @resource.group("pokemon") - @resource.scm_provider(Chef::Provider::Git) - @resource.repository_cache("cached-copy") - @resource.environment({ "SUDO" => "TRUE" }) - @resource.symlinks({ "system" => "public/system" }) - @resource.migrate(false) - - end - - it "describes its state" do - state = @resource.state_for_resource_reporter - expect(state[:deploy_to]).to eq("/") - expect(state[:revision]).to eq("1.2.3") - end - - it "returns the repository URI as its identity" do - expect(@resource.identity).to eq("http://uri.org") - end - end - -end diff --git a/spec/unit/resource/erl_call_spec.rb b/spec/unit/resource/erl_call_spec.rb deleted file mode 100644 index 06d8b83651..0000000000 --- a/spec/unit/resource/erl_call_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -# -# Author:: Joe Williams () -# Author:: Tyler Cloke () -# Copyright:: Copyright 2009-2016, Joe Williams -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "spec_helper" - -describe Chef::Resource::ErlCall do - - before(:each) do - @resource = Chef::Resource::ErlCall.new("fakey_fakerton") - end - - it "creates a new Chef::Resource::ErlCall" do - expect(@resource).to be_a_kind_of(Chef::Resource) - expect(@resource).to be_a_kind_of(Chef::Resource::ErlCall) - end - - it "has a resource name of :erl_call" do - expect(@resource.resource_name).to eql(:erl_call) - end - - it "has a default action of run" do - expect(@resource.action).to eql([:run]) - end - - it "accepts run as an action" do - expect { @resource.action :run }.not_to raise_error - end - - it "allows you to set the code attribute" do - @resource.code "q()." - expect(@resource.code).to eql("q().") - end - - it "allows you to set the cookie attribute" do - @resource.cookie "nomnomnom" - expect(@resource.cookie).to eql("nomnomnom") - end - - it "allows you to set the distributed attribute" do - @resource.distributed true - expect(@resource.distributed).to eql(true) - end - - it "allows you to set the name_type attribute" do - @resource.name_type "sname" - expect(@resource.name_type).to eql("sname") - end - - it "allows you to set the node_name attribute" do - @resource.node_name "chef@erlang" - expect(@resource.node_name).to eql("chef@erlang") - end - - describe "when it has cookie and node_name" do - before do - @resource.code("erl-call:function()") - @resource.cookie("cookie") - @resource.node_name("raster") - end - - it "returns the code as its identity" do - expect(@resource.identity).to eq("erl-call:function()") - end - end -end diff --git a/spec/unit/resource/timestamped_deploy_spec.rb b/spec/unit/resource/timestamped_deploy_spec.rb deleted file mode 100644 index 5a2dc8ae02..0000000000 --- a/spec/unit/resource/timestamped_deploy_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# -# Author:: Daniel DeLeo () -# Copyright:: Copyright 2009-2016, Daniel DeLeo -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require "spec_helper" - -describe Chef::Resource::TimestampedDeploy, "initialize" do - - static_provider_resolution( - resource: Chef::Resource::TimestampedDeploy, - provider: Chef::Provider::Deploy::Timestamped, - name: :timestamped_deploy, - action: :deploy, - os: "linux", - platform_family: "rhel" - ) - -end -- cgit v1.2.1