【问题标题】:How do I conditionally cleanup releases using Capistrano?如何使用 Capistrano 有条件地清理版本?
【发布时间】:2019-05-17 16:41:26
【问题描述】:

我知道我可以使用keep_releases 来保留特定数量 的版本,但我有一系列带有符号链接的版本。例如,我有:

http://www.example.com/version/1.0.0 是某个版本的符号链接,例如 /var/www/example.com/releases/2019050101。我还有一系列我称之为“瞬态”的版本,它们使用/current/ 链接。当部署这些“临时”版本之一时,/current 符号链接将被覆盖到最新版本。这相当于有些版本没有符号链接。

我想做的是指定 Capistrano 只保留这些 transient 版本的keep_releases 数量。换句话说,应始终保留从根目录符号链接的所有版本。

有人可以帮我提供一个 Capistrano 食谱来完成这个吗?

【问题讨论】:

  • 您必须在部署后执行的自定义 rake 任务中自己定义此过程,以清除不需要的版本。基本上遍历发布目录并找到所有非符号链接的目录,然后对它们进行排序并删除最旧的目录>您要保留的数字

标签: ruby capistrano


【解决方案1】:

我最终使用了以下配方,它主要是 the cleanup recipe in the Capistrano source 的副本,除了一些额外的逻辑来确定和跳过符号链接目录:

desc "Clean up old releases"
  task :cleanup do
    on release_roles :all do |host|
      releases = capture(:ls, "-x", releases_path).split
      kept_paths = []
      within release_path.parent.parent do
        root_path = release_path.parent.parent
        links = capture(:ls, "-l", "|", "grep", "^l").split("\n")
        links.each { |x|
          next_link_target = x.split("->")[1]
          next_link_target = next_link_target.gsub("/build", "")
          target_components = next_link_target.split("/")
          next_link_target = target_components[target_components.size - 1]
          kept_paths.push(next_link_target)
        }
      end

      valid, invalid = releases.partition { |e| /^\d{14}$/ =~ e }

      warn t(:skip_cleanup, host: host.to_s) if invalid.any?

      valid, invalid = valid.partition { |v|
        split_path = v.split("/")
        !kept_paths.include? split_path[split_path.size - 1]
      }

      if invalid.any?
        info "Skipping cleanup of releases: #{invalid} because they are symlinked in the root directory"
      end

      if valid.count >= fetch(:keep_releases)
        info t(:keeping_releases, host: host.to_s, keep_releases: fetch(:keep_releases), releases: valid.count)
        directories = (valid - valid.last(fetch(:keep_releases))).map do |release|
          releases_path.join(release).to_s
        end
        if test("[ -d #{current_path} ]")
          current_release = capture(:readlink, current_path).to_s
          if directories.include?(current_release)
            warn t(:wont_delete_current_release, host: host.to_s)
            directories.delete(current_release)
          end
        else
          debug t(:no_current_release, host: host.to_s)
        end
        if directories.any?
          execute :rm, "-rf", *directories
        else
          info t(:no_old_releases, host: host.to_s, keep_releases: fetch(:keep_releases))
        end
      end
    end
  end

【讨论】:

    猜你喜欢
    • 2011-01-08
    • 2013-01-07
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多