summaryrefslogtreecommitdiff
path: root/lib/puppet/provider
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/provider')
-rw-r--r--lib/puppet/provider/vcsrepo.rb42
-rw-r--r--lib/puppet/provider/vcsrepo/bzr.rb93
-rw-r--r--lib/puppet/provider/vcsrepo/cvs.rb135
-rw-r--r--lib/puppet/provider/vcsrepo/dummy.rb12
-rw-r--r--lib/puppet/provider/vcsrepo/git.rb483
-rw-r--r--lib/puppet/provider/vcsrepo/hg.rb130
-rw-r--r--lib/puppet/provider/vcsrepo/p4.rb278
-rw-r--r--lib/puppet/provider/vcsrepo/svn.rb139
8 files changed, 0 insertions, 1312 deletions
diff --git a/lib/puppet/provider/vcsrepo.rb b/lib/puppet/provider/vcsrepo.rb
deleted file mode 100644
index 8793e632..00000000
--- a/lib/puppet/provider/vcsrepo.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-require 'tmpdir'
-require 'digest/md5'
-require 'fileutils'
-
-# Abstract
-class Puppet::Provider::Vcsrepo < Puppet::Provider
-
- private
-
- def set_ownership
- owner = @resource.value(:owner) || nil
- group = @resource.value(:group) || nil
- FileUtils.chown_R(owner, group, @resource.value(:path))
- end
-
- def path_exists?
- File.directory?(@resource.value(:path))
- end
-
- def path_empty?
- # Path is empty if the only entries are '.' and '..'
- d = Dir.new(@resource.value(:path))
- d.read # should return '.'
- d.read # should return '..'
- d.read.nil?
- end
-
- # Note: We don't rely on Dir.chdir's behavior of automatically returning the
- # value of the last statement -- for easier stubbing.
- def at_path(&block) #:nodoc:
- value = nil
- Dir.chdir(@resource.value(:path)) do
- value = yield
- end
- value
- end
-
- def tempdir
- @tempdir ||= File.join(Dir.tmpdir, 'vcsrepo-' + Digest::MD5.hexdigest(@resource.value(:path)))
- end
-
-end
diff --git a/lib/puppet/provider/vcsrepo/bzr.rb b/lib/puppet/provider/vcsrepo/bzr.rb
deleted file mode 100644
index 797d84d2..00000000
--- a/lib/puppet/provider/vcsrepo/bzr.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
-
-Puppet::Type.type(:vcsrepo).provide(:bzr, :parent => Puppet::Provider::Vcsrepo) do
- desc "Supports Bazaar repositories"
-
- commands :bzr => 'bzr'
- has_features :reference_tracking
-
- def create
- if !@resource.value(:source)
- create_repository(@resource.value(:path))
- else
- clone_repository(@resource.value(:revision))
- end
- end
-
- def working_copy_exists?
- File.directory?(File.join(@resource.value(:path), '.bzr'))
- end
-
- def exists?
- working_copy_exists?
- end
-
- def destroy
- FileUtils.rm_rf(@resource.value(:path))
- end
-
- def revision
- at_path do
- current_revid = bzr('version-info')[/^revision-id:\s+(\S+)/, 1]
- desired = @resource.value(:revision)
- begin
- desired_revid = bzr('revision-info', desired).strip.split(/\s+/).last
- rescue Puppet::ExecutionFailure
- # Possible revid available during update (but definitely not current)
- desired_revid = nil
- end
- if current_revid == desired_revid
- desired
- else
- current_revid
- end
- end
- end
-
- def revision=(desired)
- at_path do
- begin
- bzr('update', '-r', desired)
- rescue Puppet::ExecutionFailure
- bzr('update', '-r', desired, ':parent')
- end
- end
- update_owner
- end
-
- def latest
- at_path do
- bzr('version-info', ':parent')[/^revision-id:\s+(\S+)/, 1]
- end
- end
-
- def latest?
- at_path do
- return self.revision == self.latest
- end
- end
-
- private
-
- def create_repository(path)
- bzr('init', path)
- update_owner
- end
-
- def clone_repository(revision)
- args = ['branch']
- if revision
- args.push('-r', revision)
- end
- args.push(@resource.value(:source),
- @resource.value(:path))
- bzr(*args)
- update_owner
- end
-
- def update_owner
- if @resource.value(:owner) or @resource.value(:group)
- set_ownership
- end
- end
-end
diff --git a/lib/puppet/provider/vcsrepo/cvs.rb b/lib/puppet/provider/vcsrepo/cvs.rb
deleted file mode 100644
index 7a8f6ef3..00000000
--- a/lib/puppet/provider/vcsrepo/cvs.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
-
-Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) do
- desc "Supports CVS repositories/workspaces"
-
- commands :cvs => 'cvs'
- has_features :gzip_compression, :reference_tracking, :modules, :cvs_rsh, :user
-
- def create
- if !@resource.value(:source)
- create_repository(@resource.value(:path))
- else
- checkout_repository
- end
- update_owner
- end
-
- def exists?
- if @resource.value(:source)
- directory = File.join(@resource.value(:path), 'CVS')
- else
- directory = File.join(@resource.value(:path), 'CVSROOT')
- end
- File.directory?(directory)
- end
-
- def working_copy_exists?
- File.directory?(File.join(@resource.value(:path), 'CVS'))
- end
-
- def destroy
- FileUtils.rm_rf(@resource.value(:path))
- end
-
- def latest?
- Puppet.debug "Checking for updates because 'ensure => latest'"
- at_path do
- # We cannot use -P to prune empty dirs, otherwise
- # CVS would report those as "missing", regardless
- # if they have contents or updates.
- is_current = (runcvs('-nq', 'update', '-d').strip == "")
- if (!is_current) then Puppet.debug "There are updates available on the checkout's current branch/tag." end
- return is_current
- end
- end
-
- def latest
- # CVS does not have a conecpt like commit-IDs or change
- # sets, so we can only have the current branch name (or the
- # requested one, if that differs) as the "latest" revision.
- should = @resource.value(:revision)
- current = self.revision
- return should != current ? should : current
- end
-
- def revision
- if !@rev
- if File.exist?(tag_file)
- contents = File.read(tag_file).strip
- # Note: Doesn't differentiate between N and T entries
- @rev = contents[1..-1]
- else
- @rev = 'HEAD'
- end
- Puppet.debug "Checkout is on branch/tag '#{@rev}'"
- end
- return @rev
- end
-
- def revision=(desired)
- at_path do
- runcvs('update', '-dr', desired, '.')
- update_owner
- @rev = desired
- end
- end
-
- private
-
- def tag_file
- File.join(@resource.value(:path), 'CVS', 'Tag')
- end
-
- def checkout_repository
- dirname, basename = File.split(@resource.value(:path))
- Dir.chdir(dirname) do
- args = ['-d', @resource.value(:source)]
- if @resource.value(:compression)
- args.push('-z', @resource.value(:compression))
- end
- args.push('checkout')
- if @resource.value(:revision)
- args.push('-r', @resource.value(:revision))
- end
- args.push('-d', basename, module_name)
- runcvs(*args)
- end
- end
-
- # When the source:
- # * Starts with ':' (eg, :pserver:...)
- def module_name
- if (m = @resource.value(:module))
- m
- elsif (source = @resource.value(:source))
- source[0, 1] == ':' ? File.basename(source) : '.'
- end
- end
-
- def create_repository(path)
- runcvs('-d', path, 'init')
- end
-
- def update_owner
- if @resource.value(:owner) or @resource.value(:group)
- set_ownership
- end
- end
-
- def runcvs(*args)
- if @resource.value(:cvs_rsh)
- Puppet.debug "Using CVS_RSH = " + @resource.value(:cvs_rsh)
- e = { :CVS_RSH => @resource.value(:cvs_rsh) }
- else
- e = {}
- end
-
- if @resource.value(:user) and @resource.value(:user) != Facter['id'].value
- Puppet.debug "Running as user " + @resource.value(:user)
- Puppet::Util::Execution.execute([:cvs, *args], :uid => @resource.value(:user), :custom_environment => e)
- else
- Puppet::Util::Execution.execute([:cvs, *args], :custom_environment => e)
- end
- end
-end
diff --git a/lib/puppet/provider/vcsrepo/dummy.rb b/lib/puppet/provider/vcsrepo/dummy.rb
deleted file mode 100644
index 27bfbbed..00000000
--- a/lib/puppet/provider/vcsrepo/dummy.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
-
-Puppet::Type.type(:vcsrepo).provide(:dummy, :parent => Puppet::Provider::Vcsrepo) do
- desc "Dummy default provider"
-
- defaultfor :feature => :posix
-
- def working_copy_exists?
- providers = @resource.class.providers.map{|x| x.to_s}.sort.reject{|x| x == "dummy"}.join(", ") rescue "none"
- raise("vcsrepo resource must have a provider, available: #{providers}")
- end
-end
diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb
deleted file mode 100644
index 9d18b474..00000000
--- a/lib/puppet/provider/vcsrepo/git.rb
+++ /dev/null
@@ -1,483 +0,0 @@
-require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
-
-Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) do
- desc "Supports Git repositories"
-
- has_command(:git, 'git') do
- environment({ 'HOME' => ENV['HOME'] })
- end
-
- has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :branch, :submodules
-
- def create
- if @resource.value(:revision) and ensure_bare_or_mirror?
- fail("Cannot set a revision (#{@resource.value(:revision)}) on a bare repository")
- end
- if !@resource.value(:source)
- if @resource.value(:ensure) == :mirror
- fail("Cannot init repository with mirror option, try bare instead")
- end
-
- init_repository(@resource.value(:path))
- else
- clone_repository(default_url, @resource.value(:path))
- update_remotes
-
- if @resource.value(:revision)
- checkout
- end
- if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true
- update_submodules
- end
-
- end
- update_owner_and_excludes
- end
-
- def destroy
- FileUtils.rm_rf(@resource.value(:path))
- end
-
- # Checks to see if the current revision is equal to the revision on the
- # remote (whether on a branch, tag, or reference)
- #
- # @return [Boolean] Returns true if the repo is on the latest revision
- def latest?
- return revision == latest_revision
- end
-
- # Just gives the `should` value that we should be setting the repo to if
- # latest? returns false
- #
- # @return [String] Returns the target sha/tag/branch
- def latest
- if not @resource.value(:revision) and branch = on_branch?
- return branch
- else
- return @resource.value(:revision)
- end
- end
-
- # Get the current revision of the repo (tag/branch/sha)
- #
- # @return [String] Returns the branch/tag if the current sha matches the
- # remote; otherwise returns the current sha.
- def revision
- #HEAD is the default, but lets just be explicit here.
- get_revision('HEAD')
- end
-
- # Is passed the desired reference, whether a tag, rev, or branch. Should
- # handle transitions from a rev/branch/tag to a rev/branch/tag. Detached
- # heads should be treated like bare revisions.
- #
- # @param [String] desired The desired revision to which the repo should be
- # set.
- def revision=(desired)
- #just checkout tags and shas; fetch has already happened so they should be updated.
- checkout(desired)
- #branches require more work.
- if local_branch_revision?(desired)
- #reset instead of pull to avoid merge conflicts. assuming remote is
- #updated and authoritative.
- #TODO might be worthwhile to have an allow_local_changes param to decide
- #whether to reset or pull when we're ensuring latest.
- if @resource.value(:source)
- at_path { git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") }
- else
- at_path { git_with_identity('reset', '--hard', "#{desired}") }
- end
- end
- #TODO Would this ever reach here if it is bare?
- if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true
- update_submodules
- end
- update_owner_and_excludes
- end
-
- def bare_exists?
- bare_git_config_exists? && !working_copy_exists?
- end
-
- def ensure_bare_or_mirror?
- [:bare, :mirror].include? @resource.value(:ensure)
- end
-
- # If :source is set to a hash (for supporting multiple remotes),
- # we search for the URL for :remote. If it doesn't exist,
- # we throw an error. If :source is just a string, we use that
- # value for the default URL.
- def default_url
- if @resource.value(:source).is_a?(Hash)
- if @resource.value(:source).has_key?(@resource.value(:remote))
- @resource.value(:source)[@resource.value(:remote)]
- else
- fail("You must specify the URL for #{@resource.value(:remote)} in the :source hash")
- end
- else
- @resource.value(:source)
- end
- end
-
- def working_copy_exists?
- if @resource.value(:source) and File.exists?(File.join(@resource.value(:path), '.git', 'config'))
- File.readlines(File.join(@resource.value(:path), '.git', 'config')).grep(/#{Regexp.escape(default_url)}/).any?
- else
- File.directory?(File.join(@resource.value(:path), '.git'))
- end
- end
-
- def exists?
- working_copy_exists? || bare_exists?
- end
-
- def update_remote_url(remote_name, remote_url)
- do_update = false
- current = git_with_identity('config', '-l')
-
- unless remote_url.nil?
- # Check if remote exists at all, regardless of URL.
- # If remote doesn't exist, add it
- if not current.include? "remote.#{remote_name}.url"
- git_with_identity('remote','add', remote_name, remote_url)
- return true
-
- # If remote exists, but URL doesn't match, update URL
- elsif not current.include? "remote.#{remote_name}.url=#{remote_url}"
- git_with_identity('remote','set-url', remote_name, remote_url)
- return true
- else
- return false
- end
- end
-
- end
-
- def update_remotes
- do_update = false
-
- # If supplied source is a hash of remote name and remote url pairs, then
- # we loop around the hash. Otherwise, we assume single url specified
- # in source property
- if @resource.value(:source).is_a?(Hash)
- @resource.value(:source).keys.sort.each do |remote_name|
- remote_url = @resource.value(:source)[remote_name]
- at_path { do_update |= update_remote_url(remote_name, remote_url) }
- end
- else
- at_path { do_update |= update_remote_url(@resource.value(:remote), @resource.value(:source)) }
- end
-
- # If at least one remote was added or updated, then we must
- # call the 'git remote update' command
- if do_update == true
- at_path { git_with_identity('remote','update') }
- end
-
- end
-
- def update_references
- at_path do
- update_remotes
- git_with_identity('fetch', @resource.value(:remote))
- git_with_identity('fetch', '--tags', @resource.value(:remote))
- update_owner_and_excludes
- end
- end
-
- private
-
- def valid_repo?
- Dir.chdir(@resource.value(:path)){ system('git rev-parse > /dev/null 2>&1')}
- end
-
- def bare_git_config_exists?
- File.exist?(File.join(@resource.value(:path), 'config')) && valid_repo?
- end
-
- # @!visibility private
- def clone_repository(source, path)
- check_force
- args = ['clone']
- if @resource.value(:depth) and @resource.value(:depth).to_i > 0
- args.push('--depth', @resource.value(:depth).to_s)
- if @resource.value(:revision)
- args.push('--branch', @resource.value(:revision).to_s)
- end
- end
- if @resource.value(:branch)
- args.push('--branch', @resource.value(:branch).to_s)
- end
-
- case @resource.value(:ensure)
- when :bare then args << '--bare'
- when :mirror then args << '--mirror'
- end
-
- if @resource.value(:remote) != 'origin'
- args.push('--origin', @resource.value(:remote))
- end
- if !working_copy_exists?
- args.push(source, path)
- Dir.chdir("/") do
- git_with_identity(*args)
- end
- else
- notice "Repo has already been cloned"
- end
- end
-
- # @!visibility private
- def check_force
- if path_exists? and not path_empty?
- if @resource.value(:force) && !valid_repo?
- notice "Removing %s to replace with vcsrepo." % @resource.value(:path)
- destroy
- else
- raise Puppet::Error, "Could not create repository (non-repository at path)"
- end
- end
- end
-
- # @!visibility private
- def init_repository(path)
- check_force
- if @resource.value(:ensure) == :bare && working_copy_exists?
- convert_working_copy_to_bare
- elsif @resource.value(:ensure) == :present && bare_exists?
- convert_bare_to_working_copy
- else
- # normal init
- FileUtils.mkdir(@resource.value(:path))
- FileUtils.chown(@resource.value(:user), nil, @resource.value(:path)) if @resource.value(:user)
- args = ['init']
- if @resource.value(:ensure) == :bare
- args << '--bare'
- end
- at_path do
- git_with_identity(*args)
- end
- end
- end
-
- # Convert working copy to bare
- #
- # Moves:
- # <path>/.git
- # to:
- # <path>/
- # @!visibility private
- def convert_working_copy_to_bare
- notice "Converting working copy repository to bare repository"
- FileUtils.mv(File.join(@resource.value(:path), '.git'), tempdir)
- FileUtils.rm_rf(@resource.value(:path))
- FileUtils.mv(tempdir, @resource.value(:path))
- end
-
- # Convert bare to working copy
- #
- # Moves:
- # <path>/
- # to:
- # <path>/.git
- # @!visibility private
- def convert_bare_to_working_copy
- notice "Converting bare repository to working copy repository"
- FileUtils.mv(@resource.value(:path), tempdir)
- FileUtils.mkdir(@resource.value(:path))
- FileUtils.mv(tempdir, File.join(@resource.value(:path), '.git'))
- if commits_in?(File.join(@resource.value(:path), '.git'))
- reset('HEAD')
- git_with_identity('checkout', '--force')
- update_owner_and_excludes
- end
- end
-
- # @!visibility private
- def commits_in?(dot_git)
- Dir.glob(File.join(dot_git, 'objects/info/*'), File::FNM_DOTMATCH) do |e|
- return true unless %w(. ..).include?(File::basename(e))
- end
- false
- end
-
- # Will checkout a rev/branch/tag using the locally cached versions. Does not
- # handle upstream branch changes
- # @!visibility private
- def checkout(revision = @resource.value(:revision))
- if !local_branch_revision?(revision) && remote_branch_revision?(revision)
- #non-locally existant branches (perhaps switching to a branch that has never been checked out)
- at_path { git_with_identity('checkout', '--force', '-b', revision, '--track', "#{@resource.value(:remote)}/#{revision}") }
- else
- #tags, locally existant branches (perhaps outdated), and shas
- at_path { git_with_identity('checkout', '--force', revision) }
- end
- end
-
- # @!visibility private
- def reset(desired)
- at_path do
- git_with_identity('reset', '--hard', desired)
- end
- end
-
- # @!visibility private
- def update_submodules
- at_path do
- git_with_identity('submodule', 'update', '--init', '--recursive')
- end
- end
-
- # Determins if the branch exists at the upstream but has not yet been locally committed
- # @!visibility private
- def remote_branch_revision?(revision = @resource.value(:revision))
- # git < 1.6 returns '#{@resource.value(:remote)}/#{revision}'
- # git 1.6+ returns 'remotes/#{@resource.value(:remote)}/#{revision}'
- branch = at_path { branches.grep /(remotes\/)?#{@resource.value(:remote)}\/#{revision}$/ }
- branch unless branch.empty?
- end
-
- # Determins if the branch is already cached locally
- # @!visibility private
- def local_branch_revision?(revision = @resource.value(:revision))
- at_path { branches.include?(revision) }
- end
-
- # @!visibility private
- def tag_revision?(revision = @resource.value(:revision))
- at_path { tags.include?(revision) }
- end
-
- # @!visibility private
- def branches
- at_path { git_with_identity('branch', '-a') }.gsub('*', ' ').split(/\n/).map { |line| line.strip }
- end
-
- # git < 2.4 returns 'detached from'
- # git 2.4+ returns 'HEAD detached at'
- # @!visibility private
- def on_branch?
- at_path {
- matches = git_with_identity('branch', '-a').match /\*\s+(.*)/
- matches[1] unless matches[1].match /(\(detached from|\(HEAD detached at|\(no branch)/
- }
- end
-
- # @!visibility private
- def tags
- at_path { git_with_identity('tag', '-l') }.split(/\n/).map { |line| line.strip }
- end
-
- # @!visibility private
- def set_excludes
- # Excludes may be an Array or a String.
- at_path do
- open('.git/info/exclude', 'w') do |f|
- if @resource.value(:excludes).respond_to?(:each)
- @resource.value(:excludes).each { |ex| f.puts ex }
- else
- f.puts @resource.value(:excludes)
- end
- end
- end
- end
-
- # Finds the latest revision or sha of the current branch if on a branch, or
- # of HEAD otherwise.
- # @note Calls create which can forcibly destroy and re-clone the repo if
- # force => true
- # @see get_revision
- #
- # @!visibility private
- # @return [String] Returns the output of get_revision
- def latest_revision
- #TODO Why is create called here anyway?
- create if @resource.value(:force) && working_copy_exists?
- create if !working_copy_exists?
-
- if branch = on_branch?
- return get_revision("#{@resource.value(:remote)}/#{branch}")
- else
- return get_revision
- end
- end
-
- # Returns the current revision given if the revision is a tag or branch and
- # matches the current sha. If the current sha does not match the sha of a tag
- # or branch, then it will just return the sha (ie, is not in sync)
- #
- # @!visibility private
- #
- # @param [String] rev The revision of which to check if it is current
- # @return [String] Returns the tag/branch of the current repo if it's up to
- # date; otherwise returns the sha of the requested revision.
- def get_revision(rev = 'HEAD')
- if @resource.value(:source)
- update_references
- else
- status = at_path { git_with_identity('status')}
- is_it_new = status =~ /Initial commit/
- if is_it_new
- status =~ /On branch (.*)/
- branch = $1
- return branch
- end
- end
- current = at_path { git_with_identity('rev-parse', rev).strip }
- if @resource.value(:revision)
- if tag_revision?
- # git-rev-parse will give you the hash of the tag object itself rather
- # than the commit it points to by default. Using tag^0 will return the
- # actual commit.
- canonical = at_path { git_with_identity('rev-parse', "#{@resource.value(:revision)}^0").strip }
- elsif local_branch_revision?
- canonical = at_path { git_with_identity('rev-parse', @resource.value(:revision)).strip }
- elsif remote_branch_revision?
- canonical = at_path { git_with_identity('rev-parse', "#{@resource.value(:remote)}/#{@resource.value(:revision)}").strip }
- else
- #look for a sha (could match invalid shas)
- canonical = at_path { git_with_identity('rev-parse', '--revs-only', @resource.value(:revision)).strip }
- end
- fail("#{@resource.value(:revision)} is not a local or remote ref") if canonical.nil? or canonical.empty?
- current = @resource.value(:revision) if current == canonical
- end
- return current
- end
-
- # @!visibility private
- def update_owner_and_excludes
- if @resource.value(:owner) or @resource.value(:group)
- set_ownership
- end
- if @resource.value(:excludes)
- set_excludes
- end
- end
-
- # @!visibility private
- def git_with_identity(*args)
- if @resource.value(:identity)
- Tempfile.open('git-helper', Puppet[:statedir]) do |f|
- f.puts '#!/bin/sh'
- f.puts 'export SSH_AUTH_SOCKET='
- f.puts "exec ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -oConnectTimeout=120 -i #{@resource.value(:identity)} $*"
- f.close
-
- FileUtils.chmod(0755, f.path)
- env_save = ENV['GIT_SSH']
- ENV['GIT_SSH'] = f.path
-
- ret = git(*args)
-
- ENV['GIT_SSH'] = env_save
-
- return ret
- end
- elsif @resource.value(:user) and @resource.value(:user) != Facter['id'].value
- env = Etc.getpwnam(@resource.value(:user))
- Puppet::Util::Execution.execute("git #{args.join(' ')}", :uid => @resource.value(:user), :failonfail => true, :custom_environment => {'HOME' => env['dir']})
- else
- git(*args)
- end
- end
-end
diff --git a/lib/puppet/provider/vcsrepo/hg.rb b/lib/puppet/provider/vcsrepo/hg.rb
deleted file mode 100644
index 294c2a97..00000000
--- a/lib/puppet/provider/vcsrepo/hg.rb
+++ /dev/null
@@ -1,130 +0,0 @@
-require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
-
-Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) do
- desc "Supports Mercurial repositories"
-
- commands :hg => 'hg'
-
- has_features :reference_tracking, :ssh_identity, :user, :basic_auth
-
- def create
- if !@resource.value(:source)
- create_repository(@resource.value(:path))
- else
- clone_repository(@resource.value(:revision))
- end
- update_owner
- end
-
- def working_copy_exists?
- File.directory?(File.join(@resource.value(:path), '.hg'))
- end
-
- def exists?
- working_copy_exists?
- end
-
- def destroy
- FileUtils.rm_rf(@resource.value(:path))
- end
-
- def latest?
- at_path do
- return self.revision == self.latest
- end
- end
-
- def latest
- at_path do
- begin
- hg_wrapper('incoming', '--branch', '.', '--newest-first', '--limit', '1', { :remote => true })[/^changeset:\s+(?:-?\d+):(\S+)/m, 1]
- rescue Puppet::ExecutionFailure
- # If there are no new changesets, return the current nodeid
- self.revision
- end
- end
- end
-
- def revision
- at_path do
- current = hg_wrapper('parents')[/^changeset:\s+(?:-?\d+):(\S+)/m, 1]
- desired = @resource.value(:revision)
- if desired
- # Return the tag name if it maps to the current nodeid
- mapped = hg_wrapper('tags')[/^#{Regexp.quote(desired)}\s+\d+:(\S+)/m, 1]
- if current == mapped
- desired
- else
- current
- end
- else
- current
- end
- end
- end
-
- def revision=(desired)
- at_path do
- begin
- hg_wrapper('pull', { :remote => true })
- rescue
- end
- begin
- hg_wrapper('merge')
- rescue Puppet::ExecutionFailure
- # If there's nothing to merge, just skip
- end
- hg_wrapper('update', '--clean', '-r', desired)
- end
- update_owner
- end
-
- private
-
- def create_repository(path)
- hg_wrapper('init', path)
- end
-
- def clone_repository(revision)
- args = ['clone']
- if revision
- args.push('-u', revision)
- end
- args.push(@resource.value(:source),
- @resource.value(:path))
- args.push({ :remote => true })
- hg_wrapper(*args)
- end
-
- def update_owner
- if @resource.value(:owner) or @resource.value(:group)
- set_ownership
- end
- end
-
- def hg_wrapper(*args)
- options = { :remote => false }
- if args.length > 0 and args[-1].is_a? Hash
- options.merge!(args.pop)
- end
-
- if @resource.value(:basic_auth_username) && @resource.value(:basic_auth_password)
- args += [
- "--config", "\"auth.x.prefix=#{@resource.value(:source)}\"",
- "--config", "\"auth.x.username=#{@resource.value(:basic_auth_username)}\"",
- "--config", "\"auth.x.password=#{@resource.value(:basic_auth_password)}\"",
- "--config", "\"auth.x.schemes=http https\""
- ]
- end
-
- if options[:remote] and @resource.value(:identity)
- args += ["--ssh", "ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -i #{@resource.value(:identity)}"]
- end
- if @resource.value(:user) and @resource.value(:user) != Facter['id'].value
- args.map! { |a| if a =~ /\s/ then "'#{a}'" else a end } # Adds quotes to arguments with whitespaces.
- Puppet::Util::Execution.execute("hg #{args.join(' ')}", :uid => @resource.value(:user), :failonfail => true)
- else
- hg(*args)
- end
- end
-end
diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb
deleted file mode 100644
index b429bcbb..00000000
--- a/lib/puppet/provider/vcsrepo/p4.rb
+++ /dev/null
@@ -1,278 +0,0 @@
-require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
-
-Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) do
- desc "Supports Perforce depots"
-
- has_features :filesystem_types, :reference_tracking, :p4config
-
- def create
- # create or update client
- create_client(client_name)
-
- # if source provided, sync client
- source = @resource.value(:source)
- if source
- revision = @resource.value(:revision)
- sync_client(source, revision)
- end
-
- update_owner
- end
-
- def working_copy_exists?
- # Check if the server is there, or raise error
- p4(['info'], {:marshal => false})
-
- # Check if workspace is setup
- args = ['where']
- args.push(@resource.value(:path) + "...")
- hash = p4(args, {:raise => false})
-
- return (hash['code'] != "error")
- end
-
- def exists?
- working_copy_exists?
- end
-
- def destroy
- args = ['client']
- args.push('-d', '-f')
- args.push(client_name)
- p4(args)
- FileUtils.rm_rf(@resource.value(:path))
- end
-
- def latest?
- rev = self.revision
- if rev
- (rev >= self.latest)
- else
- true
- end
- end
-
- def latest
- args = ['changes']
- args.push('-m1', @resource.value(:source))
- hash = p4(args)
-
- return hash['change'].to_i
- end
-
- def revision
- args = ['cstat']
- args.push(@resource.value(:source))
- hash = p4(args, {:marshal => false})
- hash = marshal_cstat(hash)
-
- revision = 0
- if hash && hash['code'] != 'error'
- hash['data'].each do |c|
- if c['status'] == 'have'
- change = c['change'].to_i
- revision = change if change > revision
- end
- end
- end
- return revision
- end
-
- def revision=(desired)
- sync_client(@resource.value(:source), desired)
- update_owner
- end
-
- private
-
- def update_owner
- if @resource.value(:owner) or @resource.value(:group)
- set_ownership
- end
- end
-
- # Sync the client workspace files to head or specified revision.
- # Params:
- # +source+:: Depot path to sync
- # +revision+:: Perforce change list to sync to (optional)
- def sync_client(source, revision)
- Puppet.debug "Syncing: #{source}"
- args = ['sync']
- if revision
- args.push(source + "@#{revision}")
- else
- args.push(source)
- end
- p4(args)
- end
-
- # Returns the name of the Perforce client workspace
- def client_name
- p4config = @resource.value(:p4config)
-
- # default (generated) client name
- path = @resource.value(:path)
- host = Facter.value('hostname')
- default = "puppet-" + Digest::MD5.hexdigest(path + host)
-
- # check config for client name
- set_client = nil
- if p4config && File.file?(p4config)
- open(p4config) do |f|
- m = f.grep(/^P4CLIENT=/).pop
- p = /^P4CLIENT=(.*)$/
- set_client = p.match(m)[1] if m
- end
- end
-
- return set_client || ENV['P4CLIENT'] || default
- end
-
- # Create (or update) a client workspace spec.
- # If a client name is not provided then a hash based on the path is used.
- # Params:
- # +client+:: Name of client workspace
- # +path+:: The Root location of the Perforce client workspace
- def create_client(client)
- Puppet.debug "Creating client: #{client}"
-
- # fetch client spec
- hash = parse_client(client)
- hash['Root'] = @resource.value(:path)
- hash['Description'] = "Generated by Puppet VCSrepo"
-
- # check is source is a Stream
- source = @resource.value(:source)
- if source
- parts = source.split(/\//)
- if parts && parts.length >= 4
- source = "//" + parts[2] + "/" + parts[3]
- streams = p4(['streams', source], {:raise => false})
- if streams['code'] == "stat"
- hash['Stream'] = streams['Stream']
- notice "Streams" + streams['Stream'].inspect
- end
- end
- end
-
- # save client spec
- save_client(hash)
- end
-
-
- # Fetches a client workspace spec from Perforce and returns a hash map representation.
- # Params:
- # +client+:: name of the client workspace
- def parse_client(client)
- args = ['client']
- args.push('-o', client)
- hash = p4(args)
-
- return hash
- end
-
-
- # Saves the client workspace spec from the given hash
- # Params:
- # +hash+:: hash map of client spec
- def save_client(hash)
- spec = String.new
- view = "\nView:\n"
-
- hash.keys.sort.each do |k|
- v = hash[k]
- next if( k == "code" )
- if(k.to_s =~ /View/ )
- view += "\t#{v}\n"
- else
- spec += "#{k.to_s}: #{v.to_s}\n"
- end
- end
- spec += view
-
- args = ['client']
- args.push('-i')
- p4(args, {:input => spec, :marshal => false})
- end
-
- # Sets Perforce Configuration environment.
- # P4CLIENT generated, but overwitten if defined in config.
- def config
- p4config = @resource.value(:p4config)
-
- cfg = Hash.new
- cfg.store 'P4CONFIG', p4config if p4config
- cfg.store 'P4CLIENT', client_name
- return cfg
- end
-
- def p4(args, options = {})
- # Merge custom options with defaults
- opts = {
- :raise => true, # Raise errors
- :marshal => true, # Marshal output
- }.merge(options)
-
- cmd = ['p4']
- cmd.push '-R' if opts[:marshal]
- cmd.push args
- cmd_str = cmd.respond_to?(:join) ? cmd.join(' ') : cmd
-
- Puppet.debug "environment: #{config}"
- Puppet.debug "command: #{cmd_str}"
-
- hash = Hash.new
- Open3.popen3(config, cmd_str) do |i, o, e, t|
- # Send input stream if provided
- if(opts[:input])
- Puppet.debug "input:\n" + opts[:input]
- i.write opts[:input]
- i.close
- end
-
- if(opts[:marshal])
- hash = Marshal.load(o)
- else
- hash['data'] = o.read
- end
-
- # Raise errors, Perforce or Exec
- if(opts[:raise] && !e.eof && t.value != 0)
- raise Puppet::Error, "\nP4: #{e.read}"
- end
- if(opts[:raise] && hash['code'] == 'error' && t.value != 0)
- raise Puppet::Error, "\nP4: #{hash['data']}"
- end
- end
-
- Puppet.debug "hash: #{hash}\n"
- return hash
- end
-
- # helper method as cstat does not Marshal
- def marshal_cstat(hash)
- data = hash['data']
- code = 'error'
-
- list = Array.new
- change = Hash.new
- data.each_line do |l|
- p = /^\.\.\. (.*) (.*)$/
- m = p.match(l)
- if m
- change[m[1]] = m[2]
- if m[1] == 'status'
- code = 'stat'
- list.push change
- change = Hash.new
- end
- end
- end
-
- hash = Hash.new
- hash.store 'code', code
- hash.store 'data', list
- return hash
- end
-
-end
diff --git a/lib/puppet/provider/vcsrepo/svn.rb b/lib/puppet/provider/vcsrepo/svn.rb
deleted file mode 100644
index fccfaa5a..00000000
--- a/lib/puppet/provider/vcsrepo/svn.rb
+++ /dev/null
@@ -1,139 +0,0 @@
-require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
-
-Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) do
- desc "Supports Subversion repositories"
-
- commands :svn => 'svn',
- :svnadmin => 'svnadmin',
- :svnlook => 'svnlook'
-
- has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration, :conflict, :depth
-
- def create
- if !@resource.value(:source)
- create_repository(@resource.value(:path))
- else
- checkout_repository(@resource.value(:source),
- @resource.value(:path),
- @resource.value(:revision),
- @resource.value(:depth))
- end
- update_owner
- end
-
- def working_copy_exists?
- if File.directory?(@resource.value(:path))
- # :path is an svn checkout
- return true if File.directory?(File.join(@resource.value(:path), '.svn'))
- if File.file?(File.join(@resource.value(:path), 'format'))
- # :path is an svn server
- return true if svnlook('uuid', @resource.value(:path))
- end
- end
- false
- end
-
- def exists?
- working_copy_exists?
- end
-
- def destroy
- FileUtils.rm_rf(@resource.value(:path))
- end
-
- def latest?
- at_path do
- (self.revision >= self.latest) and (@resource.value(:source) == self.sourceurl)
- end
- end
-
- def buildargs
- args = ['--non-interactive']
- if @resource.value(:basic_auth_username) && @resource.value(:basic_auth_password)
- args.push('--username', @resource.value(:basic_auth_username))
- args.push('--password', @resource.value(:basic_auth_password))
- args.push('--no-auth-cache')
- end
-
- if @resource.value(:force)
- args.push('--force')
- end
-
- if @resource.value(:configuration)
- args.push('--config-dir', @resource.value(:configuration))
- end
-
- if @resource.value(:trust_server_cert) != :false
- args.push('--trust-server-cert')
- end
-
- args
- end
-
- def latest
- args = buildargs.push('info', '-r', 'HEAD')
- at_path do
- svn(*args)[/^Revision:\s+(\d+)/m, 1]
- end
- end
-
- def sourceurl
- args = buildargs.push('info')
- at_path do
- svn(*args)[/^URL:\s+(\S+)/m, 1]
- end
- end
-
- def revision
- args = buildargs.push('info')
- at_path do
- svn(*args)[/^Revision:\s+(\d+)/m, 1]
- end
- end
-
- def revision=(desired)
- args = if @resource.value(:source)
- buildargs.push('switch', '-r', desired, @resource.value(:source))
- else
- buildargs.push('update', '-r', desired)
- end
-
- if @resource.value(:conflict)
- args.push('--accept', @resource.value(:conflict))
- end
-
- at_path do
- svn(*args)
- end
- update_owner
- end
-
- private
-
- def checkout_repository(source, path, revision, depth)
- args = buildargs.push('checkout')
- if revision
- args.push('-r', revision)
- end
- if depth
- args.push('--depth', depth)
- end
- args.push(source, path)
- svn(*args)
- end
-
- def create_repository(path)
- args = ['create']
- if @resource.value(:fstype)
- args.push('--fs-type', @resource.value(:fstype))
- end
- args << path
- svnadmin(*args)
- end
-
- def update_owner
- if @resource.value(:owner) or @resource.value(:group)
- set_ownership
- end
- end
-end