From 411111b5ff88b682d7e9cc54a47573bccc3e3edc Mon Sep 17 00:00:00 2001 From: John Iacona Date: Wed, 28 Aug 2013 14:32:05 -0400 Subject: update git provider to handle checking out into an existing (empty) dir --- lib/puppet/provider/vcsrepo.rb | 5 +++++ lib/puppet/provider/vcsrepo/git.rb | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo.rb b/lib/puppet/provider/vcsrepo.rb index 2c026ba..05b92f8 100644 --- a/lib/puppet/provider/vcsrepo.rb +++ b/lib/puppet/provider/vcsrepo.rb @@ -17,6 +17,11 @@ class Puppet::Provider::Vcsrepo < Puppet::Provider File.directory?(@resource.value(:path)) end + def path_empty? + # Path is empty if the only entries are '.' and '..' + Dir.entries(@resource.value(:path)).size == 2 + 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: diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 58330f6..47e84d2 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -147,7 +147,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end def check_force - if path_exists? + if path_exists? and not path_empty? if @resource.value(:force) notice "Removing %s to replace with vcsrepo." % @resource.value(:path) destroy -- cgit v1.2.3 From e69c6eac89fbbbd5c459388eef30b1320ab9d826 Mon Sep 17 00:00:00 2001 From: John Iacona Date: Wed, 28 Aug 2013 16:34:57 -0400 Subject: change path_empty? to not do full directory listing --- lib/puppet/provider/vcsrepo.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo.rb b/lib/puppet/provider/vcsrepo.rb index 05b92f8..8793e63 100644 --- a/lib/puppet/provider/vcsrepo.rb +++ b/lib/puppet/provider/vcsrepo.rb @@ -19,7 +19,10 @@ class Puppet::Provider::Vcsrepo < Puppet::Provider def path_empty? # Path is empty if the only entries are '.' and '..' - Dir.entries(@resource.value(:path)).size == 2 + 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 -- cgit v1.2.3 From 2b190756260346931b8f9a0dda8afc0c815710d6 Mon Sep 17 00:00:00 2001 From: Reid Vandewiele Date: Sun, 20 Oct 2013 22:19:34 -0700 Subject: Add autorequire for Package['git'] If the git package is being managed, it stands to reason that the git package should be installed before trying to potentially manage git repositories using vcsrepo resources. This commit adds an autorequire to the vcsrepo type that reflects the above premise. --- lib/puppet/type/vcsrepo.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index 8225721..ad90ced 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -191,4 +191,8 @@ Puppet::Type.newtype(:vcsrepo) do desc "The value to be used for the CVS_RSH environment variable." end + autorequire(:package) do + ['git', 'git-core'] + end + end -- cgit v1.2.3 From c9c6d96554e546f70a289522df3f24261674cc1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=E1=BA=BDl=20Can=C3=A9vet?= Date: Sun, 24 Nov 2013 10:44:37 +0100 Subject: Don't 'su' if passed user is current user --- lib/puppet/provider/vcsrepo/git.rb | 2 +- lib/puppet/provider/vcsrepo/hg.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 47e84d2..442ea61 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -314,7 +314,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) return ret end - elsif @resource.value(:user) + elsif @resource.value(:user) and @resource.value(:user) != Facter['id'].value su(@resource.value(:user), '-c', "git #{args.join(' ')}" ) else git(*args) diff --git a/lib/puppet/provider/vcsrepo/hg.rb b/lib/puppet/provider/vcsrepo/hg.rb index 4886b7a..33f1e6a 100644 --- a/lib/puppet/provider/vcsrepo/hg.rb +++ b/lib/puppet/provider/vcsrepo/hg.rb @@ -105,7 +105,7 @@ Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) d if @resource.value(:identity) args += ["--ssh", "ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -i #{@resource.value(:identity)}"] end - if @resource.value(:user) + 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. su(@resource.value(:user), '-c', "hg #{args.join(' ')}") else -- cgit v1.2.3 From 4689c514a12764933a9cb1e2858343f0ba5923b3 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Mon, 2 Dec 2013 11:24:15 -0500 Subject: origin/HEAD is not valid; use origin/master for latest when branch == 'master' --- lib/puppet/provider/vcsrepo/git.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 47e84d2..6bc1c3d 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -39,9 +39,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) def latest branch = on_branch? - if branch == 'master' - return get_revision("#{@resource.value(:remote)}/HEAD") - elsif branch == '(no branch)' + if branch == '(no branch)' return get_revision('HEAD') else return get_revision("#{@resource.value(:remote)}/%s" % branch) -- cgit v1.2.3 From 8837be29ff114228f86d67c59337119120690e44 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Mon, 2 Dec 2013 11:38:56 -0500 Subject: Using rev-parse to determine branch name of HEAD for on_branch? method --- lib/puppet/provider/vcsrepo/git.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 6bc1c3d..17275c4 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -39,7 +39,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) def latest branch = on_branch? - if branch == '(no branch)' + if branch == '' return get_revision('HEAD') else return get_revision("#{@resource.value(:remote)}/%s" % branch) @@ -253,7 +253,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end def on_branch? - at_path { git_with_identity('branch', '-a') }.split(/\n/).grep(/\*/).first.to_s.gsub('*', '').strip + at_path { git_with_identity('rev-parse', '--abbrev-ref', 'HEAD') } end def tags -- cgit v1.2.3 From 69b93cefcdcd4a80d241dc71d5e6de90842faf11 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Tue, 3 Dec 2013 09:54:21 -0500 Subject: Stripping git on_branch? return value; contains trailing newline This commit also contains git provider `latest' method formatting changes; squashed by request. --- lib/puppet/provider/vcsrepo/git.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 17275c4..d488271 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -39,10 +39,10 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) def latest branch = on_branch? - if branch == '' + if !branch return get_revision('HEAD') else - return get_revision("#{@resource.value(:remote)}/%s" % branch) + return get_revision("#{@resource.value(:remote)}/#{branch}") end end @@ -253,7 +253,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end def on_branch? - at_path { git_with_identity('rev-parse', '--abbrev-ref', 'HEAD') } + at_path { git_with_identity('rev-parse', '--abbrev-ref', 'HEAD').chomp } end def tags -- cgit v1.2.3 From 0ea16bba47cf177dc17fa14f20d54d0091a09865 Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Thu, 2 Jan 2014 18:13:40 -0300 Subject: Add the option to shallow clones with git The new parameter used to indicate that you want a shallow clone is `:depth` --- lib/puppet/provider/vcsrepo/git.rb | 5 ++++- lib/puppet/type/vcsrepo.rb | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index d488271..af38a59 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -6,7 +6,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) ##TODO modify the commands below so that the su - is included optional_commands :git => 'git', :su => 'su' - has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user + has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth def create if !@resource.value(:source) @@ -131,6 +131,9 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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) + end if @resource.value(:ensure) == :bare args << '--bare' end diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index ad90ced..1dab2b9 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -37,6 +37,9 @@ Puppet::Type.newtype(:vcsrepo) do feature :cvs_rsh, "The provider understands the CVS_RSH environment variable" + feature :depth, + "The provider can do shallow clones" + ensurable do attr_accessor :latest @@ -191,6 +194,10 @@ Puppet::Type.newtype(:vcsrepo) do desc "The value to be used for the CVS_RSH environment variable." end + newparam :depth, :required_features => [:depth] do + desc "The value to be used to do a shallow clone." + end + autorequire(:package) do ['git', 'git-core'] end -- cgit v1.2.3 From 7845ea132b0b40a83d3e9284723cbf63e2b61a82 Mon Sep 17 00:00:00 2001 From: Miguel Di Ciurcio Filho Date: Sat, 11 Jan 2014 15:25:28 -0200 Subject: git: actually use the remote parameter When using the following sample, the provider does not use the value of remote when cloning a repository: vcsrepo {'/path/to/repo': ensure => 'present', provider => 'git', remote => 'test', source => 'git@somerepo:repo.git', } $ git remote origin This commit makes sure that the new repository has a remote with the supplied value. Closes #MODULES-430 --- lib/puppet/provider/vcsrepo/git.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index af38a59..cdae459 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -105,10 +105,10 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end def update_remote_origin_url - current = git_with_identity('config', 'remote.origin.url') + current = git_with_identity('config', "remote.#{@resource.value(:remote)}.url") unless @resource.value(:source).nil? if current.nil? or current.strip != @resource.value(:source) - git_with_identity('config', 'remote.origin.url', @resource.value(:source)) + git_with_identity('config', "remote.#{@resource.value(:remote)}.url", @resource.value(:source)) end end end @@ -137,6 +137,9 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) if @resource.value(:ensure) == :bare args << '--bare' end + if @resource.value(:remote) != 'origin' + args.push('--origin', @resource.value(:remote)) + end if !File.exist?(File.join(@resource.value(:path), '.git')) args.push(source, path) Dir.chdir("/") do -- cgit v1.2.3 From 93b73f6877f9bdfdd291e2dd5ff5b8f6247d833d Mon Sep 17 00:00:00 2001 From: jonoterc Date: Tue, 14 Jan 2014 12:31:26 -0500 Subject: fix svnlook behavior with plain directories svnlook expects a sub-directory within a repository called "format"; when using svnlook within a non-repository directory this causes it to throw an error. Adding a test for that directory before executing svnlook. --- lib/puppet/provider/vcsrepo/svn.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/svn.rb b/lib/puppet/provider/vcsrepo/svn.rb index e0d5b21..7856acd 100644 --- a/lib/puppet/provider/vcsrepo/svn.rb +++ b/lib/puppet/provider/vcsrepo/svn.rb @@ -24,8 +24,10 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) if File.directory?(@resource.value(:path)) # :path is an svn checkout return true if File.directory?(File.join(@resource.value(:path), '.svn')) - # :path is an svn server - return true if svnlook('uuid', @resource.value(:path)) + if File.directory?(File.join(@resource.value(:path), 'format')) + # :path is an svn server + return true if svnlook('uuid', @resource.value(:path)) + end end false end -- cgit v1.2.3 From 9c873e1c56f1147a8fcdd01b804f744deebb53f6 Mon Sep 17 00:00:00 2001 From: Huan Du Date: Wed, 12 Feb 2014 22:40:56 +0800 Subject: use `git rev-parse` to get tag canonical revision. --- lib/puppet/provider/vcsrepo/git.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index c96095b..b2e893b 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -52,7 +52,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) return current unless @resource.value(:revision) if tag_revision?(@resource.value(:revision)) - canonical = at_path { git_with_identity('show', @resource.value(:revision)).scan(/^commit (.*)/).to_s } + canonical = at_path { git_with_identity('rev-parse', @resource.value(:revision)).chomp } else # if it's not a tag, look for it as a local ref canonical = at_path { git_with_identity('rev-parse', '--revs-only', @resource.value(:revision)).chomp } -- cgit v1.2.3 From 744f3cc4094062ef1f6a80c644d82b6284d2f7fc Mon Sep 17 00:00:00 2001 From: Felix Krull Date: Fri, 14 Feb 2014 22:12:42 +0100 Subject: Only add ssh options to commands that actually talk to the network. At least in Mercurial 2.8.2, --ssh seems to be a command-specific parameter in contrast to a global one. As a result, local commands error when seeing a --ssh parameter. This change passes --ssh only for commands that actually talk to the network ('incoming', 'pull' and 'clone' here). --- lib/puppet/provider/vcsrepo/hg.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/hg.rb b/lib/puppet/provider/vcsrepo/hg.rb index 33f1e6a..6c6f936 100644 --- a/lib/puppet/provider/vcsrepo/hg.rb +++ b/lib/puppet/provider/vcsrepo/hg.rb @@ -37,7 +37,7 @@ Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) d def latest at_path do begin - hg_wrapper('incoming', '--branch', '.', '--newest-first', '--limit', '1')[/^changeset:\s+(?:-?\d+):(\S+)/m, 1] + 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 @@ -66,7 +66,7 @@ Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) d def revision=(desired) at_path do begin - hg_wrapper('pull') + hg_wrapper('pull', { :remote => true }) rescue end begin @@ -92,6 +92,7 @@ Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) d end args.push(@resource.value(:source), @resource.value(:path)) + args.push({ :remote => true }) hg_wrapper(*args) end @@ -102,7 +103,11 @@ Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) d end def hg_wrapper(*args) - if @resource.value(:identity) + options = { :remote => false } + if args.length > 0 and args[-1].is_a? Hash + options.merge!(args.pop) + 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 -- cgit v1.2.3 From e4be0ab189aa32967bb732a8183c142e01942e4b Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 3 Dec 2013 01:30:51 -0600 Subject: Call set_ownership from the bzr provider --- lib/puppet/provider/vcsrepo/bzr.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/bzr.rb b/lib/puppet/provider/vcsrepo/bzr.rb index 6688ce8..80b18ed 100644 --- a/lib/puppet/provider/vcsrepo/bzr.rb +++ b/lib/puppet/provider/vcsrepo/bzr.rb @@ -52,6 +52,7 @@ Puppet::Type.type(:vcsrepo).provide(:bzr, :parent => Puppet::Provider::Vcsrepo) bzr('update', '-r', desired, ':parent') end end + update_owner end def latest @@ -70,6 +71,7 @@ Puppet::Type.type(:vcsrepo).provide(:bzr, :parent => Puppet::Provider::Vcsrepo) def create_repository(path) bzr('init', path) + update_owner end def clone_repository(revision) @@ -80,6 +82,12 @@ Puppet::Type.type(:vcsrepo).provide(:bzr, :parent => Puppet::Provider::Vcsrepo) 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 -- cgit v1.2.3 From cfcd03a7c59eaa6b81de8c767bbd91e6d278c0f2 Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Tue, 13 May 2014 11:27:02 -0700 Subject: Fix issue where force=>true was not destroying repository then recreating --- lib/puppet/provider/vcsrepo/git.rb | 5 ++++- lib/puppet/type/vcsrepo.rb | 8 +++++++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index b2e893b..fafe4bf 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -140,7 +140,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) if @resource.value(:remote) != 'origin' args.push('--origin', @resource.value(:remote)) end - if !File.exist?(File.join(@resource.value(:path), '.git')) + if !working_copy_exists? args.push(source, path) Dir.chdir("/") do git_with_identity(*args) @@ -271,6 +271,9 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end def get_revision(rev) + if @resource.value(:force) && working_copy_exists? + create + end if !working_copy_exists? create end diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index 1dab2b9..3dd7bc6 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -76,7 +76,7 @@ Puppet::Type.newtype(:vcsrepo) do end newvalue :latest, :required_features => [:reference_tracking] do - if provider.exists? + if provider.exists? && !@resource.value(:force) if provider.respond_to?(:update_references) provider.update_references end @@ -97,6 +97,12 @@ Puppet::Type.newtype(:vcsrepo) do prov = @resource.provider if prov if prov.working_copy_exists? + if @resource.value(:force) + notice "Deleting current repository before recloning" + prov.destroy + notice "Create repository from latest" + prov.create + end (@should.include?(:latest) && prov.latest?) ? :latest : :present elsif prov.class.feature?(:bare_repositories) and prov.bare_exists? :bare -- cgit v1.2.3 From a213d71ec8d3e75bef909cc5c3f11aaea8b4e94d Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Thu, 15 May 2014 16:47:24 -0700 Subject: Fix detached head state --- lib/puppet/provider/vcsrepo/git.rb | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index fafe4bf..b4bafbf 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -79,12 +79,18 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) def revision=(desired) checkout(desired) - if local_branch_revision?(desired) + if local_branch_revision? # reset instead of pull to avoid merge conflicts. assuming remote is # authoritative. # might be worthwhile to have an allow_local_changes param to decide # whether to reset or pull when we're ensuring latest. - at_path { git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") } + at_path { + git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{@resource.value(:revision)}") + if detached? + git_with_identity('checkout', "#{@resource.value(:revision)}") + git_with_identity('pull') + end + } end if @resource.value(:ensure) != :bare update_submodules @@ -259,7 +265,16 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end def on_branch? - at_path { git_with_identity('rev-parse', '--abbrev-ref', 'HEAD').chomp } + at_path { + matches = git_with_identity('branch', '--list').match /\*\s+(.*)/ + matches[1] unless matches[1].match /detached/ + } + end + + def detached? + at_path { + git_with_identity('branch', '--list').match /\*\s+\(detached from.*\)/ + } end def tags -- cgit v1.2.3 From a909fe74c71e7e214087c3c95bb21e6dfd90c940 Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Thu, 15 May 2014 22:00:14 -0700 Subject: update to use -a and desired for hard reset --- lib/puppet/provider/vcsrepo/git.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index b4bafbf..61044e0 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -85,7 +85,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) # might be worthwhile to have an allow_local_changes param to decide # whether to reset or pull when we're ensuring latest. at_path { - git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{@resource.value(:revision)}") + git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") if detached? git_with_identity('checkout', "#{@resource.value(:revision)}") git_with_identity('pull') @@ -266,14 +266,14 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) def on_branch? at_path { - matches = git_with_identity('branch', '--list').match /\*\s+(.*)/ + matches = git_with_identity('branch', '-a').match /\*\s+(.*)/ matches[1] unless matches[1].match /detached/ } end def detached? at_path { - git_with_identity('branch', '--list').match /\*\s+\(detached from.*\)/ + git_with_identity('branch', '-a').match /\*\s+\(detached from.*\)/ } end -- cgit v1.2.3 From 932eb74ac487c815e51b1e99bb2f57ee82169be2 Mon Sep 17 00:00:00 2001 From: Daniele Sluijters Date: Thu, 22 May 2014 00:16:10 +0200 Subject: Un-optional the non-optional commands. --- lib/puppet/provider/vcsrepo/bzr.rb | 2 +- lib/puppet/provider/vcsrepo/cvs.rb | 2 +- lib/puppet/provider/vcsrepo/git.rb | 5 +++-- lib/puppet/provider/vcsrepo/hg.rb | 5 +++-- lib/puppet/provider/vcsrepo/svn.rb | 6 +++--- 5 files changed, 11 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/bzr.rb b/lib/puppet/provider/vcsrepo/bzr.rb index 80b18ed..797d84d 100644 --- a/lib/puppet/provider/vcsrepo/bzr.rb +++ b/lib/puppet/provider/vcsrepo/bzr.rb @@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), '..', 'vcsrepo') Puppet::Type.type(:vcsrepo).provide(:bzr, :parent => Puppet::Provider::Vcsrepo) do desc "Supports Bazaar repositories" - optional_commands :bzr => 'bzr' + commands :bzr => 'bzr' has_features :reference_tracking def create diff --git a/lib/puppet/provider/vcsrepo/cvs.rb b/lib/puppet/provider/vcsrepo/cvs.rb index 206e732..01094b1 100644 --- a/lib/puppet/provider/vcsrepo/cvs.rb +++ b/lib/puppet/provider/vcsrepo/cvs.rb @@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), '..', 'vcsrepo') Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) do desc "Supports CVS repositories/workspaces" - optional_commands :cvs => 'cvs' + commands :cvs => 'cvs' has_features :gzip_compression, :reference_tracking, :modules, :cvs_rsh def create diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 61044e0..1bccfb6 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -4,8 +4,9 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) desc "Supports Git repositories" ##TODO modify the commands below so that the su - is included - optional_commands :git => 'git', - :su => 'su' + commands :git => 'git' + optional_commands :su => 'su' + has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth def create diff --git a/lib/puppet/provider/vcsrepo/hg.rb b/lib/puppet/provider/vcsrepo/hg.rb index 6c6f936..56ca527 100644 --- a/lib/puppet/provider/vcsrepo/hg.rb +++ b/lib/puppet/provider/vcsrepo/hg.rb @@ -3,8 +3,9 @@ require File.join(File.dirname(__FILE__), '..', 'vcsrepo') Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) do desc "Supports Mercurial repositories" - optional_commands :hg => 'hg', - :su => 'su' + commands :hg => 'hg' + optional_commands :su => 'su' + has_features :reference_tracking, :ssh_identity, :user def create diff --git a/lib/puppet/provider/vcsrepo/svn.rb b/lib/puppet/provider/vcsrepo/svn.rb index 7856acd..316a3a1 100644 --- a/lib/puppet/provider/vcsrepo/svn.rb +++ b/lib/puppet/provider/vcsrepo/svn.rb @@ -3,9 +3,9 @@ require File.join(File.dirname(__FILE__), '..', 'vcsrepo') Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) do desc "Supports Subversion repositories" - optional_commands :svn => 'svn', - :svnadmin => 'svnadmin', - :svnlook => 'svnlook' + commands :svn => 'svn', + :svnadmin => 'svnadmin', + :svnlook => 'svnlook' has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration -- cgit v1.2.3 From 0d9e938e92a25673c3712866e2d2108a255b67d5 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Tue, 20 May 2014 18:15:03 -0700 Subject: Update specs and fix FM-1361 - Add install.rb for pre-suite - Add catches for failures/changes to manifest application - Correct root ssh key copying - Add sleeps for killing processes releasing ports - Fix FM-1361 --- lib/puppet/provider/vcsrepo/git.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 61044e0..f6ee407 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -9,16 +9,15 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth def create + if @resource.value(:revision) and @resource.value(:ensure) == :bare + fail("Cannot set a revision (#{@resource.value(:revision)}) on a bare repository") + end if !@resource.value(:source) init_repository(@resource.value(:path)) else clone_repository(@resource.value(:source), @resource.value(:path)) if @resource.value(:revision) - if @resource.value(:ensure) == :bare - notice "Ignoring revision for bare repository" - else - checkout - end + checkout end if @resource.value(:ensure) != :bare update_submodules -- cgit v1.2.3 From 17c91e7ab8f89453c926b432e5ff82335d280e90 Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Mon, 2 Jun 2014 23:03:19 +0100 Subject: (MODULES-1014) Adding noop mode option --- lib/puppet/type/vcsrepo.rb | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index 3dd7bc6..0e4450b 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -98,10 +98,15 @@ Puppet::Type.newtype(:vcsrepo) do if prov if prov.working_copy_exists? if @resource.value(:force) - notice "Deleting current repository before recloning" - prov.destroy - notice "Create repository from latest" - prov.create + if noop? + notice "Noop Mode - Would have deleted repository" + notice "Noop Mode - Would have created repository from latest" + else + notice "Deleting current repository before recloning" + prov.destroy + notice "Create repository from latest" + prov.create + end end (@should.include?(:latest) && prov.latest?) ? :latest : :present elsif prov.class.feature?(:bare_repositories) and prov.bare_exists? @@ -208,4 +213,12 @@ Puppet::Type.newtype(:vcsrepo) do ['git', 'git-core'] end + def noop? + if defined?(@noop) + @noop + else + Puppet[:noop] + end + end + end -- cgit v1.2.3 From d2bb24e33860090a7051ce9ef6dfbb695cf23447 Mon Sep 17 00:00:00 2001 From: Paul Allen Date: Wed, 11 Jun 2014 22:32:21 +0100 Subject: Basic Perforce provider Supports sync and client create/update --- lib/puppet/provider/vcsrepo/p4.rb | 217 ++++++++++++++++++++++++++++++++++++++ lib/puppet/type/vcsrepo.rb | 19 ++++ 2 files changed, 236 insertions(+) create mode 100644 lib/puppet/provider/vcsrepo/p4.rb (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb new file mode 100644 index 0000000..2fdae70 --- /dev/null +++ b/lib/puppet/provider/vcsrepo/p4.rb @@ -0,0 +1,217 @@ +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, :p4_config + + def create + # create or update client + create_client(client_name, @resource.value(:path)) + + # 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) + + if hash['status'] == "have" + return hash['change'].to_i + else + return 0 + end + 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) + notice "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 + path = @resource.value(:path) + client = @resource.value(:p4client) + if not client + client = "puppet-" + Digest::MD5.hexdigest(path) + end + return client + 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, path) + notice "Creating client: #{client}" + hash = parse_client(client) + hash['Root'] = path + hash['Description'] = "Generated by Puppet VCSrepo" + 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.each do |k,v| + 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 + + def config + p4port = @resource.value(:p4port) + p4user = @resource.value(:p4user) + p4charset = @resource.value(:p4charset) + p4client = @resource.value(:p4client) || client_name + + cfg = Hash.new + cfg.store 'P4USER', p4user if p4user + cfg.store 'P4PORT', p4port if p4port + cfg.store 'P4CHARSET', p4charset if p4charset + cfg.store 'P4CLIENT', p4client if p4client + + 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 + + notice "environment: #{config}" + notice "command: #{cmd_str}" + + hash = Hash.new + Open3.popen3(config, cmd_str) do |i, o, e, t| + # Send input stream if provided + if(opts[:input]) + notice "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]) + p4_err = "P4: " + hash['data'] if(hash['code'] == 'error') + raise Puppet::DevError, "#{p4_err}\n#{e.read}\nExit: #{t.value}" if(t.value != 0) + end + end + + notice "hash: #{hash}\n" + return hash + end + +end diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index 0e4450b..ad964c5 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -40,6 +40,9 @@ Puppet::Type.newtype(:vcsrepo) do feature :depth, "The provider can do shallow clones" + feature :p4_config, + "The provider understands Perforce Configuration" + ensurable do attr_accessor :latest @@ -209,6 +212,22 @@ Puppet::Type.newtype(:vcsrepo) do desc "The value to be used to do a shallow clone." end + newparam :p4port, :required_features => [:p4_config] do + desc "The Perforce P4PORT environment." + end + + newparam :p4user, :required_features => [:p4_config] do + desc "The Perforce P4USER environment." + end + + newparam :p4client, :required_features => [:p4_config] do + desc "The Perforce P4CLIENT environment." + end + + newparam :p4charset, :required_features => [:p4_config] do + desc "The Perforce P4CHARSET environment." + end + autorequire(:package) do ['git', 'git-core'] end -- cgit v1.2.3 From 8256eff1800e1377c7cf2b961ef63074a2ede0d4 Mon Sep 17 00:00:00 2001 From: Paul Allen Date: Mon, 16 Jun 2014 17:04:52 +0100 Subject: Add support for passing password/ticket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uses param ‘p4passwd’ to set P4PASSWD environment to pass a valid ticket or password. --- lib/puppet/provider/vcsrepo/p4.rb | 2 ++ lib/puppet/type/vcsrepo.rb | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb index 2fdae70..df1ec21 100644 --- a/lib/puppet/provider/vcsrepo/p4.rb +++ b/lib/puppet/provider/vcsrepo/p4.rb @@ -162,12 +162,14 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d p4port = @resource.value(:p4port) p4user = @resource.value(:p4user) p4charset = @resource.value(:p4charset) + p4passwd = @resource.value(:p4passwd) p4client = @resource.value(:p4client) || client_name cfg = Hash.new cfg.store 'P4USER', p4user if p4user cfg.store 'P4PORT', p4port if p4port cfg.store 'P4CHARSET', p4charset if p4charset + cfg.store 'P4PASSWD', p4passwd if p4passwd cfg.store 'P4CLIENT', p4client if p4client return cfg diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index ad964c5..649789a 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -227,6 +227,10 @@ Puppet::Type.newtype(:vcsrepo) do newparam :p4charset, :required_features => [:p4_config] do desc "The Perforce P4CHARSET environment." end + + newparam :p4passwd, :required_features => [:p4_config] do + desc "The Perforce P4PASSWD environment." + end autorequire(:package) do ['git', 'git-core'] -- cgit v1.2.3 From 24e2f91ffb0091bc6f67b4d90f9702690bc1179f Mon Sep 17 00:00:00 2001 From: Paul Allen Date: Fri, 20 Jun 2014 09:59:42 +0100 Subject: Detab to 2 spaces. --- lib/puppet/provider/vcsrepo/p4.rb | 388 +++++++++++++++++++------------------- 1 file changed, 194 insertions(+), 194 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb index df1ec21..de3bc7a 100644 --- a/lib/puppet/provider/vcsrepo/p4.rb +++ b/lib/puppet/provider/vcsrepo/p4.rb @@ -1,219 +1,219 @@ require File.join(File.dirname(__FILE__), '..', 'vcsrepo') Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) do - desc "Supports Perforce depots" + desc "Supports Perforce depots" - has_features :filesystem_types, :reference_tracking, :p4_config - - def create - # create or update client - create_client(client_name, @resource.value(:path)) - - # if source provided, sync client - source = @resource.value(:source) - if source - revision = @resource.value(:revision) - sync_client(source, revision) - end + has_features :filesystem_types, :reference_tracking, :p4_config + + def create + # create or update client + create_client(client_name, @resource.value(:path)) + + # if source provided, sync client + source = @resource.value(:source) + if source + revision = @resource.value(:revision) + sync_client(source, revision) + end - update_owner - 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 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 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 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? + 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 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) - - if hash['status'] == "have" - return hash['change'].to_i - else - return 0 - end - end + def revision + args = ['cstat'] + args.push(@resource.value(:source)) + hash = p4(args) + + if hash['status'] == "have" + return hash['change'].to_i + else + return 0 + end + end - def revision=(desired) - sync_client(@resource.value(:source), desired) - update_owner - end + def revision=(desired) + sync_client(@resource.value(:source), desired) + update_owner + end - private + 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: + 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) - notice "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 - path = @resource.value(:path) - client = @resource.value(:p4client) - if not client - client = "puppet-" + Digest::MD5.hexdigest(path) - end - return client - 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 + def sync_client(source, revision) + notice "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 + path = @resource.value(:path) + client = @resource.value(:p4client) + if not client + client = "puppet-" + Digest::MD5.hexdigest(path) + end + return client + 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, path) - notice "Creating client: #{client}" - hash = parse_client(client) - hash['Root'] = path - hash['Description'] = "Generated by Puppet VCSrepo" - save_client(hash) - end + def create_client(client, path) + notice "Creating client: #{client}" + hash = parse_client(client) + hash['Root'] = path + hash['Description'] = "Generated by Puppet VCSrepo" + save_client(hash) + end - # Fetches a client workspace spec from Perforce and returns a hash map representation. + # 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) + 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 + 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.each do |k,v| - 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 - - def config - p4port = @resource.value(:p4port) - p4user = @resource.value(:p4user) - p4charset = @resource.value(:p4charset) - p4passwd = @resource.value(:p4passwd) - p4client = @resource.value(:p4client) || client_name - - cfg = Hash.new - cfg.store 'P4USER', p4user if p4user - cfg.store 'P4PORT', p4port if p4port - cfg.store 'P4CHARSET', p4charset if p4charset - cfg.store 'P4PASSWD', p4passwd if p4passwd - cfg.store 'P4CLIENT', p4client if p4client - - 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 - - notice "environment: #{config}" - notice "command: #{cmd_str}" - - hash = Hash.new - Open3.popen3(config, cmd_str) do |i, o, e, t| - # Send input stream if provided - if(opts[:input]) - notice "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]) - p4_err = "P4: " + hash['data'] if(hash['code'] == 'error') - raise Puppet::DevError, "#{p4_err}\n#{e.read}\nExit: #{t.value}" if(t.value != 0) - end - end - - notice "hash: #{hash}\n" - return hash - end - + def save_client(hash) + spec = String.new + view = "\nView:\n" + + hash.each do |k,v| + 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 + + def config + p4port = @resource.value(:p4port) + p4user = @resource.value(:p4user) + p4charset = @resource.value(:p4charset) + p4passwd = @resource.value(:p4passwd) + p4client = @resource.value(:p4client) || client_name + + cfg = Hash.new + cfg.store 'P4USER', p4user if p4user + cfg.store 'P4PORT', p4port if p4port + cfg.store 'P4CHARSET', p4charset if p4charset + cfg.store 'P4PASSWD', p4passwd if p4passwd + cfg.store 'P4CLIENT', p4client if p4client + + 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 + + notice "environment: #{config}" + notice "command: #{cmd_str}" + + hash = Hash.new + Open3.popen3(config, cmd_str) do |i, o, e, t| + # Send input stream if provided + if(opts[:input]) + notice "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]) + p4_err = "P4: " + hash['data'] if(hash['code'] == 'error') + raise Puppet::DevError, "#{p4_err}\n#{e.read}\nExit: #{t.value}" if(t.value != 0) + end + end + + notice "hash: #{hash}\n" + return hash + end + end -- cgit v1.2.3 From 319f9fbe1954fd172da638f3ccd76e58c3ec8c7f Mon Sep 17 00:00:00 2001 From: Paul Allen Date: Mon, 23 Jun 2014 15:51:28 +0100 Subject: Added support for p4config. - Removed p4port, p4client, p4user to keep name space clean. - Changed notify to Puppet.debug - Updated markdown and examples - Updated unit tests --- lib/puppet/provider/vcsrepo/p4.rb | 51 +++++++++++++++++++++------------------ lib/puppet/type/vcsrepo.rb | 22 +++-------------- 2 files changed, 31 insertions(+), 42 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb index de3bc7a..ec40cf3 100644 --- a/lib/puppet/provider/vcsrepo/p4.rb +++ b/lib/puppet/provider/vcsrepo/p4.rb @@ -3,7 +3,7 @@ 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, :p4_config + has_features :filesystem_types, :reference_tracking, :p4config def create # create or update client @@ -90,7 +90,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d # +source+:: Depot path to sync # +revision+:: Perforce change list to sync to (optional) def sync_client(source, revision) - notice "Syncing: #{source}" + Puppet.debug "Syncing: #{source}" args = ['sync'] if revision args.push(source + "@" + revision) @@ -102,12 +102,23 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d # Returns the name of the Perforce client workspace def client_name + p4config = @resource.value(:p4config) + + # default (generated) client name path = @resource.value(:path) - client = @resource.value(:p4client) - if not client - client = "puppet-" + Digest::MD5.hexdigest(path) + default = "puppet-" + Digest::MD5.hexdigest(path) + + # 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 client + + return set_client || ENV['P4CLIENT'] || default end # Create (or update) a client workspace spec. @@ -116,7 +127,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d # +client+:: Name of client workspace # +path+:: The Root location of the Perforce client workspace def create_client(client, path) - notice "Creating client: #{client}" + Puppet.debug "Creating client: #{client}" hash = parse_client(client) hash['Root'] = path hash['Description'] = "Generated by Puppet VCSrepo" @@ -158,20 +169,14 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d p4(args, {:input => spec, :marshal => false}) end + # Sets Perforce Configuration environment. + # P4CLIENT generated, but overwitten if defined in config. def config - p4port = @resource.value(:p4port) - p4user = @resource.value(:p4user) - p4charset = @resource.value(:p4charset) - p4passwd = @resource.value(:p4passwd) - p4client = @resource.value(:p4client) || client_name - - cfg = Hash.new - cfg.store 'P4USER', p4user if p4user - cfg.store 'P4PORT', p4port if p4port - cfg.store 'P4CHARSET', p4charset if p4charset - cfg.store 'P4PASSWD', p4passwd if p4passwd - cfg.store 'P4CLIENT', p4client if p4client + p4config = @resource.value(:p4config) + cfg = Hash.new + cfg.store 'P4CONFIG', p4config if p4config + cfg.store 'P4CLIENT', client_name return cfg end @@ -187,14 +192,14 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d cmd.push args cmd_str = cmd.respond_to?(:join) ? cmd.join(' ') : cmd - notice "environment: #{config}" - notice "command: #{cmd_str}" + 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]) - notice "input:\n" + opts[:input] + Puppet.debug "input:\n" + opts[:input] i.write opts[:input] i.close end @@ -212,7 +217,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d end end - notice "hash: #{hash}\n" + Puppet.debug "hash: #{hash}\n" return hash end diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index 649789a..7ada022 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -40,7 +40,7 @@ Puppet::Type.newtype(:vcsrepo) do feature :depth, "The provider can do shallow clones" - feature :p4_config, + feature :p4config, "The provider understands Perforce Configuration" ensurable do @@ -212,26 +212,10 @@ Puppet::Type.newtype(:vcsrepo) do desc "The value to be used to do a shallow clone." end - newparam :p4port, :required_features => [:p4_config] do - desc "The Perforce P4PORT environment." - end - - newparam :p4user, :required_features => [:p4_config] do - desc "The Perforce P4USER environment." - end - - newparam :p4client, :required_features => [:p4_config] do - desc "The Perforce P4CLIENT environment." + newparam :p4config, :required_features => [:p4config] do + desc "The Perforce P4CONFIG environment." end - newparam :p4charset, :required_features => [:p4_config] do - desc "The Perforce P4CHARSET environment." - end - - newparam :p4passwd, :required_features => [:p4_config] do - desc "The Perforce P4PASSWD environment." - end - autorequire(:package) do ['git', 'git-core'] end -- cgit v1.2.3 From 457035ec1c15df0d53abf7232dad63b2722b1720 Mon Sep 17 00:00:00 2001 From: Paul Allen Date: Mon, 23 Jun 2014 16:22:35 +0100 Subject: Add hostname to Digest for default client name. --- lib/puppet/provider/vcsrepo/p4.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb index ec40cf3..612cc56 100644 --- a/lib/puppet/provider/vcsrepo/p4.rb +++ b/lib/puppet/provider/vcsrepo/p4.rb @@ -106,7 +106,8 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d # default (generated) client name path = @resource.value(:path) - default = "puppet-" + Digest::MD5.hexdigest(path) + host = Facter.value('hostname') + default = "puppet-" + Digest::MD5.hexdigest(path + host) # check config for client name set_client = nil -- cgit v1.2.3 From 2ff03cff1795d3e43c922f7bceb235ce69175013 Mon Sep 17 00:00:00 2001 From: Stuart Whelan Date: Sat, 21 Jun 2014 17:26:14 +1200 Subject: Added support for basic authentication to hg provider Updated unit tests Updated hg readme and added examples --- lib/puppet/provider/vcsrepo/hg.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/hg.rb b/lib/puppet/provider/vcsrepo/hg.rb index 56ca527..090f019 100644 --- a/lib/puppet/provider/vcsrepo/hg.rb +++ b/lib/puppet/provider/vcsrepo/hg.rb @@ -6,7 +6,7 @@ Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) d commands :hg => 'hg' optional_commands :su => 'su' - has_features :reference_tracking, :ssh_identity, :user + has_features :reference_tracking, :ssh_identity, :user, :basic_auth def create if !@resource.value(:source) @@ -108,6 +108,16 @@ Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) d 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 -- cgit v1.2.3 From e1aa644dd075c275dd22d85cdc03c88dda029d87 Mon Sep 17 00:00:00 2001 From: Paul Allen Date: Tue, 24 Jun 2014 13:57:30 +0100 Subject: Support streams and fix Marshal for 'p4 cstat' --- lib/puppet/provider/vcsrepo/p4.rb | 76 ++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb index 612cc56..da9c953 100644 --- a/lib/puppet/provider/vcsrepo/p4.rb +++ b/lib/puppet/provider/vcsrepo/p4.rb @@ -7,7 +7,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d def create # create or update client - create_client(client_name, @resource.value(:path)) + create_client(client_name) # if source provided, sync client source = @resource.value(:source) @@ -63,13 +63,19 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d def revision args = ['cstat'] args.push(@resource.value(:source)) - hash = p4(args) + hash = p4(args, {:marshal => false}) + hash = marshal_cstat(hash) - if hash['status'] == "have" - return hash['change'].to_i - else - return 0 + 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) @@ -93,7 +99,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d Puppet.debug "Syncing: #{source}" args = ['sync'] if revision - args.push(source + "@" + revision) + args.push(source + "@#{revision}") else args.push(source) end @@ -127,11 +133,29 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d # Params: # +client+:: Name of client workspace # +path+:: The Root location of the Perforce client workspace - def create_client(client, path) + def create_client(client) Puppet.debug "Creating client: #{client}" + + # fetch client spec hash = parse_client(client) - hash['Root'] = path + 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 @@ -212,9 +236,11 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d end # Raise errors, Perforce or Exec - if(opts[:raise]) - p4_err = "P4: " + hash['data'] if(hash['code'] == 'error') - raise Puppet::DevError, "#{p4_err}\n#{e.read}\nExit: #{t.value}" if(t.value != 0) + 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 @@ -222,4 +248,30 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d 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 -- cgit v1.2.3 From f88ae5fd6c746de3b454e38a8616f016ada8cff9 Mon Sep 17 00:00:00 2001 From: Paul Allen Date: Tue, 24 Jun 2014 14:16:05 +0100 Subject: Sort keys on hash generate same test result. Keys in the Client spec were processed out of order and failing tests. --- lib/puppet/provider/vcsrepo/p4.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb index da9c953..4f53415 100644 --- a/lib/puppet/provider/vcsrepo/p4.rb +++ b/lib/puppet/provider/vcsrepo/p4.rb @@ -179,7 +179,8 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d spec = String.new view = "\nView:\n" - hash.each do |k,v| + hash.keys.sort.each do |k| + v = hash[k] next if( k == "code" ) if(k.to_s =~ /View/ ) view += "\t#{v}\n" -- cgit v1.2.3 From 818f5298b6be3b1a25e997ba84eae237d9051be9 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Fri, 20 Jun 2014 13:48:02 -0700 Subject: Update noop to work --- lib/puppet/type/vcsrepo.rb | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index 0e4450b..42767ab 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -98,9 +98,8 @@ Puppet::Type.newtype(:vcsrepo) do if prov if prov.working_copy_exists? if @resource.value(:force) - if noop? - notice "Noop Mode - Would have deleted repository" - notice "Noop Mode - Would have created repository from latest" + if noop + notice "Noop Mode - Would have deleted repository and re-created from latest" else notice "Deleting current repository before recloning" prov.destroy @@ -212,13 +211,4 @@ Puppet::Type.newtype(:vcsrepo) do autorequire(:package) do ['git', 'git-core'] end - - def noop? - if defined?(@noop) - @noop - else - Puppet[:noop] - end - end - end -- cgit v1.2.3 From 688c3cad1a277b4cb59445750fdf402a1c1774a3 Mon Sep 17 00:00:00 2001 From: "Joshua B. Bussdieker" Date: Wed, 25 Jun 2014 16:28:04 -0700 Subject: Fix issue with node changing every checkin --- lib/puppet/provider/vcsrepo/git.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 5c878ed..5c5dd07 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -52,7 +52,9 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) return current unless @resource.value(:revision) if tag_revision?(@resource.value(:revision)) - canonical = at_path { git_with_identity('rev-parse', @resource.value(:revision)).chomp } + # 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").chomp } else # if it's not a tag, look for it as a local ref canonical = at_path { git_with_identity('rev-parse', '--revs-only', @resource.value(:revision)).chomp } -- cgit v1.2.3 From 34cc0c0d4e35fdc5a7b8381033886d160927d501 Mon Sep 17 00:00:00 2001 From: Paul Allen Date: Wed, 2 Jul 2014 12:05:35 +0100 Subject: Update Markdown with missing Perforce details. Fix tabs/spaces in p4.rb --- lib/puppet/provider/vcsrepo/p4.rb | 56 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb index 4f53415..63d3df2 100644 --- a/lib/puppet/provider/vcsrepo/p4.rb +++ b/lib/puppet/provider/vcsrepo/p4.rb @@ -68,12 +68,12 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d 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 + 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 @@ -180,7 +180,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d view = "\nView:\n" hash.keys.sort.each do |k| - v = hash[k] + v = hash[k] next if( k == "code" ) if(k.to_s =~ /View/ ) view += "\t#{v}\n" @@ -251,28 +251,28 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d # 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 + 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 + 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 -- cgit v1.2.3 From 6624f40651f44e184878a9fbb862bda886d899e8 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Wed, 18 Jun 2014 13:54:51 -0700 Subject: (MODULES-660) Correct detached HEAD on latest Previously vcsrepo detached HEAD on checkout which caused further branch revisions to fail. This corrects the behavior, and works on git 1.7, 1.8, 1.9, and 2.0 --- lib/puppet/provider/vcsrepo/git.rb | 172 +++++++++++++++++++++---------------- 1 file changed, 99 insertions(+), 73 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 5c5dd07..0a142bb 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -31,69 +31,49 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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? - at_path do - return self.revision == self.latest - end + 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 - branch = on_branch? - if !branch - return get_revision('HEAD') - else - return get_revision("#{@resource.value(:remote)}/#{branch}") - end + @resource.value(:revision) 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 - update_references - current = at_path { git_with_identity('rev-parse', 'HEAD').chomp } - return current unless @resource.value(:revision) - - if tag_revision?(@resource.value(: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").chomp } - else - # if it's not a tag, look for it as a local ref - canonical = at_path { git_with_identity('rev-parse', '--revs-only', @resource.value(:revision)).chomp } - if canonical.empty? - # git rev-parse executed properly but didn't find the ref; - # look for it in the remote - remote_ref = at_path { git_with_identity('ls-remote', '--heads', '--tags', @resource.value(:remote), @resource.value(:revision)).chomp } - if remote_ref.empty? - fail("#{@resource.value(:revision)} is not a local or remote ref") - end - - # $ git ls-remote --heads --tags origin feature/cvs - # 7d4244b35e72904e30130cad6d2258f901c16f1a refs/heads/feature/cvs - canonical = remote_ref.split.first - end - end - - if current == canonical - @resource.value(:revision) - else - current - end + #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) - if local_branch_revision? - # reset instead of pull to avoid merge conflicts. assuming remote is - # authoritative. - # might be worthwhile to have an allow_local_changes param to decide - # whether to reset or pull when we're ensuring latest. - at_path { - git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") - if detached? - git_with_identity('checkout', "#{@resource.value(:revision)}") - git_with_identity('pull') - end - } + #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. + at_path { git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") } end + #TODO Would this ever reach here if it is bare? if @resource.value(:ensure) != :bare update_submodules end @@ -132,10 +112,12 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) private + # @!visibility private def bare_git_config_exists? File.exist?(File.join(@resource.value(:path), 'config')) end + # @!visibility private def clone_repository(source, path) check_force args = ['clone'] @@ -158,6 +140,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end end + # @!visibility private def check_force if path_exists? and not path_empty? if @resource.value(:force) @@ -169,6 +152,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end end + # @!visibility private def init_repository(path) check_force if @resource.value(:ensure) == :bare && working_copy_exists? @@ -195,6 +179,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) # /.git # to: # / + # @!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) @@ -208,6 +193,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) # / # to: # /.git + # @!visibility private def convert_bare_to_working_copy notice "Converting bare repository to working copy repository" FileUtils.mv(@resource.value(:path), tempdir) @@ -220,6 +206,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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)) @@ -227,26 +214,35 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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? && remote_branch_revision? - at_path { git_with_identity('checkout', '-b', revision, '--track', "#{@resource.value(:remote)}/#{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}' @@ -254,64 +250,93 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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 + # @!visibility private def on_branch? at_path { matches = git_with_identity('branch', '-a').match /\*\s+(.*)/ - matches[1] unless matches[1].match /detached/ - } - end - - def detached? - at_path { - git_with_identity('branch', '-a').match /\*\s+\(detached from.*\)/ + matches[1] unless matches[1].match /(\(detached from|\(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 at_path { open('.git/info/exclude', 'w') { |f| @resource.value(:excludes).each { |ex| f.write(ex + "\n") }}} end - def get_revision(rev) - if @resource.value(:force) && working_copy_exists? - create - end - if !working_copy_exists? - create - end - at_path do - update_remote_origin_url - git_with_identity('fetch', @resource.value(:remote)) - git_with_identity('fetch', '--tags', @resource.value(:remote)) + # 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') + update_references current = at_path { git_with_identity('rev-parse', rev).strip } if @resource.value(:revision) - if local_branch_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 } + 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 - update_owner_and_excludes return current end + # @!visibility private def update_owner_and_excludes if @resource.value(:owner) or @resource.value(:group) set_ownership @@ -321,6 +346,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end end + # @!visibility private def git_with_identity(*args) if @resource.value(:identity) Tempfile.open('git-helper') do |f| -- cgit v1.2.3 From 27c5d5847504d6d5e295b617b1461b4727ccf1f2 Mon Sep 17 00:00:00 2001 From: Paul Chechetin Date: Wed, 20 Aug 2014 11:47:34 +0400 Subject: Change uid by Puppet execution API --- lib/puppet/provider/vcsrepo/git.rb | 4 +--- lib/puppet/provider/vcsrepo/hg.rb | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 0a142bb..9e0306b 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -3,9 +3,7 @@ require File.join(File.dirname(__FILE__), '..', 'vcsrepo') Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) do desc "Supports Git repositories" - ##TODO modify the commands below so that the su - is included commands :git => 'git' - optional_commands :su => 'su' has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth @@ -365,7 +363,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) return ret end elsif @resource.value(:user) and @resource.value(:user) != Facter['id'].value - su(@resource.value(:user), '-c', "git #{args.join(' ')}" ) + Puppet::Util::Execution.execute("git #{args.join(' ')}", :uid => @resource.value(:user), :failonfail => true) else git(*args) end diff --git a/lib/puppet/provider/vcsrepo/hg.rb b/lib/puppet/provider/vcsrepo/hg.rb index 090f019..294c2a9 100644 --- a/lib/puppet/provider/vcsrepo/hg.rb +++ b/lib/puppet/provider/vcsrepo/hg.rb @@ -4,7 +4,6 @@ Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) d desc "Supports Mercurial repositories" commands :hg => 'hg' - optional_commands :su => 'su' has_features :reference_tracking, :ssh_identity, :user, :basic_auth @@ -123,7 +122,7 @@ Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) d 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. - su(@resource.value(:user), '-c', "hg #{args.join(' ')}") + Puppet::Util::Execution.execute("hg #{args.join(' ')}", :uid => @resource.value(:user), :failonfail => true) else hg(*args) end -- cgit v1.2.3 From ead1aa855a0a6ff6ca54ffc027c585f0b6dba0f4 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Mon, 15 Sep 2014 16:03:11 -0700 Subject: (MODULES-428) Remove dummy warning Puppet started raising a warning about multiple default providers due to a change in puppet. The dummy provider exists to raise an error when `provider` is not specified because there is no way to declare `provider` as a required attribute in the type. Even passing a `provider` value did not get rid of the "multiple default providers found" warning however. This commit causes the dummy provider to be the defacto default for all resources which do not have an explicit provider declared, as the posix feature is available on basically every operating system on which vcsrepo works. (There is no way to create an "always default" provider.) --- lib/puppet/provider/vcsrepo/dummy.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/dummy.rb b/lib/puppet/provider/vcsrepo/dummy.rb index f7b4e54..27bfbbe 100644 --- a/lib/puppet/provider/vcsrepo/dummy.rb +++ b/lib/puppet/provider/vcsrepo/dummy.rb @@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), '..', 'vcsrepo') Puppet::Type.type(:vcsrepo).provide(:dummy, :parent => Puppet::Provider::Vcsrepo) do desc "Dummy default provider" - defaultfor :vcsrepo => :dummy + defaultfor :feature => :posix def working_copy_exists? providers = @resource.class.providers.map{|x| x.to_s}.sort.reject{|x| x == "dummy"}.join(", ") rescue "none" -- cgit v1.2.3 From 96d1cc90cf3caa72f6b9d69f85389b2960c27792 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sat, 13 Sep 2014 22:48:18 -0700 Subject: Remove excess whitespace --- lib/puppet/provider/vcsrepo/p4.rb | 86 +++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 43 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb index 63d3df2..b429bcb 100644 --- a/lib/puppet/provider/vcsrepo/p4.rb +++ b/lib/puppet/provider/vcsrepo/p4.rb @@ -4,11 +4,11 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d desc "Supports Perforce depots" has_features :filesystem_types, :reference_tracking, :p4config - + def create - # create or update client + # create or update client create_client(client_name) - + # if source provided, sync client source = @resource.value(:source) if source @@ -22,12 +22,12 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d 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 @@ -49,14 +49,14 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d (rev >= self.latest) else true - end + end end def latest args = ['changes'] args.push('-m1', @resource.value(:source)) hash = p4(args) - + return hash['change'].to_i end @@ -65,7 +65,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d 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| @@ -90,7 +90,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d set_ownership end end - + # Sync the client workspace files to head or specified revision. # Params: # +source+:: Depot path to sync @@ -105,16 +105,16 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d end p4(args) end - - # Returns the name of the Perforce client workspace + + # 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) @@ -124,10 +124,10 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d 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: @@ -135,13 +135,13 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d # +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 + + # check is source is a Stream source = @resource.value(:source) if source parts = source.split(/\//) @@ -154,7 +154,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d end end end - + # save client spec save_client(hash) end @@ -170,15 +170,15 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d return hash end - - - # Saves the client workspace spec from the given hash + + + # 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" ) @@ -187,40 +187,40 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d else spec += "#{k.to_s}: #{v.to_s}\n" end - end + end spec += view - + args = ['client'] args.push('-i') p4(args, {:input => spec, :marshal => false}) - end - + 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 + return cfg end - + def p4(args, options = {}) # Merge custom options with defaults - opts = { + 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 @@ -229,13 +229,13 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d i.write opts[:input] i.close end - + if(opts[:marshal]) hash = Marshal.load(o) else - hash['data'] = o.read + hash['data'] = o.read end - + # Raise errors, Perforce or Exec if(opts[:raise] && !e.eof && t.value != 0) raise Puppet::Error, "\nP4: #{e.read}" @@ -244,22 +244,22 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d 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 + if m change[m[1]] = m[2] if m[1] == 'status' code = 'stat' @@ -268,11 +268,11 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d end end end - + hash = Hash.new hash.store 'code', code hash.store 'data', list return hash end - + end -- cgit v1.2.3 From 0e7c0b06e952d5133bd7f9f055d680cb704e213e Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sat, 13 Sep 2014 23:27:25 -0700 Subject: Handle both Array/Enumerable and String values for excludes parameter Thanks to @revhazroot for identifying the problem that excludes with a string or single-element array fails on Ruby >= 1.9. --- lib/puppet/provider/vcsrepo/git.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 0a142bb..48bbe7d 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -281,7 +281,16 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) # @!visibility private def set_excludes - at_path { open('.git/info/exclude', 'w') { |f| @resource.value(:excludes).each { |ex| f.write(ex + "\n") }}} + # 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 -- cgit v1.2.3 From ecf02352a371e3c4a9c72bf94297f047bc400aa7 Mon Sep 17 00:00:00 2001 From: Jon Fautley Date: Tue, 28 Oct 2014 16:21:48 +0000 Subject: Add `user` feature support to CVS provider --- lib/puppet/provider/vcsrepo/cvs.rb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/cvs.rb b/lib/puppet/provider/vcsrepo/cvs.rb index 01094b1..891a5c6 100644 --- a/lib/puppet/provider/vcsrepo/cvs.rb +++ b/lib/puppet/provider/vcsrepo/cvs.rb @@ -4,7 +4,7 @@ Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) desc "Supports CVS repositories/workspaces" commands :cvs => 'cvs' - has_features :gzip_compression, :reference_tracking, :modules, :cvs_rsh + has_features :gzip_compression, :reference_tracking, :modules, :cvs_rsh, :user def create if !@resource.value(:source) @@ -125,13 +125,11 @@ Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) e = {} end - # The location of withenv changed from Puppet 2.x to 3.x - withenv = Puppet::Util.method(:withenv) if Puppet::Util.respond_to?(:withenv) - withenv = Puppet::Util::Execution.method(:withenv) if Puppet::Util::Execution.respond_to?(:withenv) - fail("Cannot set custom environment #{e}") if e && !withenv - - withenv.call e do - Puppet.debug cvs *args + if @resource.value(:user) and @resource.value(:user) != Facter['id'].value + debug "Running as user " + @resource.value(:user) + Puppet.debug Puppet::Util::Execution.execute("cvs #{args.join(' ')}", :uid => @resource.value(:user), :custom_environment => e) + else + Puppet.debug Puppet::Util::Execution.execute("cvs #{args.join(' ')}", :custom_environment => e) end end end -- cgit v1.2.3 From f40255377ce41653d69f0b91c5b1a8f7d36883c1 Mon Sep 17 00:00:00 2001 From: Jon Fautley Date: Wed, 29 Oct 2014 10:55:42 +0000 Subject: Revamp debugging output --- lib/puppet/provider/vcsrepo/cvs.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/cvs.rb b/lib/puppet/provider/vcsrepo/cvs.rb index 891a5c6..7a8f6ef 100644 --- a/lib/puppet/provider/vcsrepo/cvs.rb +++ b/lib/puppet/provider/vcsrepo/cvs.rb @@ -33,13 +33,13 @@ Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) end def latest? - debug "Checking for updates because 'ensure => 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 debug "There are updates available on the checkout's current branch/tag." end + if (!is_current) then Puppet.debug "There are updates available on the checkout's current branch/tag." end return is_current end end @@ -62,7 +62,7 @@ Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) else @rev = 'HEAD' end - debug "Checkout is on branch/tag '#{@rev}'" + Puppet.debug "Checkout is on branch/tag '#{@rev}'" end return @rev end @@ -119,17 +119,17 @@ Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) def runcvs(*args) if @resource.value(:cvs_rsh) - debug "Using CVS_RSH = " + @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 - debug "Running as user " + @resource.value(:user) - Puppet.debug Puppet::Util::Execution.execute("cvs #{args.join(' ')}", :uid => @resource.value(:user), :custom_environment => e) + Puppet.debug "Running as user " + @resource.value(:user) + Puppet::Util::Execution.execute([:cvs, *args], :uid => @resource.value(:user), :custom_environment => e) else - Puppet.debug Puppet::Util::Execution.execute("cvs #{args.join(' ')}", :custom_environment => e) + Puppet::Util::Execution.execute([:cvs, *args], :custom_environment => e) end end end -- cgit v1.2.3 From 35cfd4b5d46f6c144ccaddfb948203ccde6b9521 Mon Sep 17 00:00:00 2001 From: Farzad FARID Date: Sat, 13 Dec 2014 16:24:49 +0100 Subject: Fix for MODULES-1597: "format" is a file not a directory The "format" entry in a SVN directory is a file, not a directory. --- lib/puppet/provider/vcsrepo/svn.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/svn.rb b/lib/puppet/provider/vcsrepo/svn.rb index 316a3a1..a1b1714 100644 --- a/lib/puppet/provider/vcsrepo/svn.rb +++ b/lib/puppet/provider/vcsrepo/svn.rb @@ -24,7 +24,7 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) if File.directory?(@resource.value(:path)) # :path is an svn checkout return true if File.directory?(File.join(@resource.value(:path), '.svn')) - if File.directory?(File.join(@resource.value(:path), 'format')) + if File.file?(File.join(@resource.value(:path), 'format')) # :path is an svn server return true if svnlook('uuid', @resource.value(:path)) end -- cgit v1.2.3 From 56f25d57dfa26de618416e9bdd4a853296ffcbc1 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Fri, 26 Dec 2014 15:27:20 -0800 Subject: MODULES-1596 - Repository repeatedly destroyed/created with force The `retrieve` method was calling `create` and `destroy` on every run with `force => true`. Retrieve should not be making any changes to the system, so removed that code, and updated `working_copy_exists` to make sure that the directory not only contains a `.git` directory, but also if `source` is specified it also matches `#{path}/.git/config` so that it will overwrite a git repo with a different source. Updated tests to not check for the old broken behavior. Added a regression test. --- lib/puppet/provider/vcsrepo/git.rb | 6 +++++- lib/puppet/type/vcsrepo.rb | 10 ---------- 2 files changed, 5 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 1c6588c..b1e556d 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -83,7 +83,11 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end def working_copy_exists? - File.directory?(File.join(@resource.value(:path), '.git')) + if @resource.value(:source) and File.exists?(File.join(@resource.value(:path), '.git', 'config')) + File.readlines(File.join(@resource.value(:path), '.git', 'config')).grep(/#{@resource.value(:source)}/).any? + else + File.directory?(File.join(@resource.value(:path), '.git')) + end end def exists? diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index f678389..b8836d4 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -100,16 +100,6 @@ Puppet::Type.newtype(:vcsrepo) do prov = @resource.provider if prov if prov.working_copy_exists? - if @resource.value(:force) - if noop - notice "Noop Mode - Would have deleted repository and re-created from latest" - else - notice "Deleting current repository before recloning" - prov.destroy - notice "Create repository from latest" - prov.create - end - end (@should.include?(:latest) && prov.latest?) ? :latest : :present elsif prov.class.feature?(:bare_repositories) and prov.bare_exists? :bare -- cgit v1.2.3 From dfe5f9cc316a43793da2cb1c4adbc66503907460 Mon Sep 17 00:00:00 2001 From: dduvnjak Date: Sun, 18 Jan 2015 10:49:03 +0100 Subject: Add submodules feature to git provider --- lib/puppet/provider/vcsrepo/git.rb | 4 ++-- lib/puppet/type/vcsrepo.rb | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 1c6588c..9e1903c 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -5,7 +5,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) commands :git => 'git' - has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth + has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :submodules def create if @resource.value(:revision) and @resource.value(:ensure) == :bare @@ -18,7 +18,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) if @resource.value(:revision) checkout end - if @resource.value(:ensure) != :bare + if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true update_submodules end end diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index f678389..3f34c57 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -43,6 +43,9 @@ Puppet::Type.newtype(:vcsrepo) do feature :p4config, "The provider understands Perforce Configuration" + feature :submodules, + "The repository contains submodules which can be optionally initialized" + ensurable do attr_accessor :latest @@ -215,6 +218,12 @@ Puppet::Type.newtype(:vcsrepo) do desc "The Perforce P4CONFIG environment." end + newparam :submodules, :required_features => [:submodules] do + desc "Initialize and update each submodule in the repository." + newvalues(:true, :false) + defaultto true + end + autorequire(:package) do ['git', 'git-core'] end -- cgit v1.2.3 From 5d6ef988af1ff90b4625b0426301cb6fad0268b8 Mon Sep 17 00:00:00 2001 From: Jonathan Tripathy Date: Tue, 20 Jan 2015 23:12:20 -0800 Subject: Implemented multiple remotes feature for git provider. --- lib/puppet/provider/vcsrepo/git.rb | 70 +++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 13e0793..9d3f7f3 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -14,13 +14,16 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) if !@resource.value(:source) init_repository(@resource.value(:path)) else - clone_repository(@resource.value(:source), @resource.value(:path)) + clone_repository(default_url, @resource.value(:path)) + update_remotes + if @resource.value(:revision) checkout end if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true update_submodules end + end update_owner_and_excludes end @@ -82,9 +85,25 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) bare_git_config_exists? && !working_copy_exists? 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(/#{@resource.value(:source)}/).any? + File.readlines(File.join(@resource.value(:path), '.git', 'config')).grep(/#{default_url}/).any? else File.directory?(File.join(@resource.value(:path), '.git')) end @@ -94,18 +113,53 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) working_copy_exists? || bare_exists? end - def update_remote_origin_url - current = git_with_identity('config', "remote.#{@resource.value(:remote)}.url") - unless @resource.value(:source).nil? - if current.nil? or current.strip != @resource.value(:source) - git_with_identity('config', "remote.#{@resource.value(:remote)}.url", @resource.value(:source)) + 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).each do |remote_name, remote_url| + 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_remote_origin_url + update_remotes git_with_identity('fetch', @resource.value(:remote)) git_with_identity('fetch', '--tags', @resource.value(:remote)) update_owner_and_excludes -- cgit v1.2.3 From 28f8646e4669bacf7a87ffc8694715333355cd32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C5=82odzimierz=20Gajda?= Date: Wed, 22 Oct 2014 10:02:29 +0200 Subject: Use branch parameter --- lib/puppet/provider/vcsrepo/git.rb | 5 ++++- lib/puppet/type/vcsrepo.rb | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 9d3f7f3..8a8c12f 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -5,7 +5,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) commands :git => 'git' - has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :submodules + has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :branch, :submodules def create if @resource.value(:revision) and @resource.value(:ensure) == :bare @@ -180,6 +180,9 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) if @resource.value(:depth) and @resource.value(:depth).to_i > 0 args.push('--depth', @resource.value(:depth).to_s) end + if @resource.value(:branch) + args.push('--branch', @resource.value(:branch).to_s) + end if @resource.value(:ensure) == :bare args << '--bare' end diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index 3bf4029..fdcf9ab 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -40,6 +40,9 @@ Puppet::Type.newtype(:vcsrepo) do feature :depth, "The provider can do shallow clones" + feature :branch, + "The name of the branch" + feature :p4config, "The provider understands Perforce Configuration" @@ -204,6 +207,10 @@ Puppet::Type.newtype(:vcsrepo) do desc "The value to be used to do a shallow clone." end + newparam :branch, :required_features => [:branch] do + desc "The name of the branch to clone." + end + newparam :p4config, :required_features => [:p4config] do desc "The Perforce P4CONFIG environment." end -- cgit v1.2.3 From cf5c8e6e9fb46115d59ec4e3b5d433e29168fe00 Mon Sep 17 00:00:00 2001 From: Ernesto Ruy Sanchez Date: Fri, 30 Jan 2015 10:46:59 -0800 Subject: Added submodules true condition before update_submodules on revision method --- lib/puppet/provider/vcsrepo/git.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 9d3f7f3..e31a76c 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -20,7 +20,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) if @resource.value(:revision) checkout end - if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true + if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true && @resource.value(:submodules) == :true update_submodules end @@ -75,7 +75,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) at_path { git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") } end #TODO Would this ever reach here if it is bare? - if @resource.value(:ensure) != :bare + if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true update_submodules end update_owner_and_excludes -- cgit v1.2.3 From 56852e9cbf93c3f6f5db7dcdd40b3d364b548182 Mon Sep 17 00:00:00 2001 From: Ernesto Ruy Sanchez Date: Fri, 30 Jan 2015 11:01:01 -0800 Subject: Bugfix: removed duplicated condition --- lib/puppet/provider/vcsrepo/git.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index e31a76c..dde9bf0 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -20,7 +20,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) if @resource.value(:revision) checkout end - if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true && @resource.value(:submodules) == :true + if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true update_submodules end -- cgit v1.2.3 From 7fdfa1b4047e134053f6df95f414cb3fc44796cd Mon Sep 17 00:00:00 2001 From: Daniel DiSisto Date: Fri, 6 Mar 2015 17:01:38 +1100 Subject: (MODULES-1551) Add support for SVN conflict handling --- lib/puppet/provider/vcsrepo/svn.rb | 7 ++++++- lib/puppet/type/vcsrepo.rb | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/svn.rb b/lib/puppet/provider/vcsrepo/svn.rb index a1b1714..905d5ad 100644 --- a/lib/puppet/provider/vcsrepo/svn.rb +++ b/lib/puppet/provider/vcsrepo/svn.rb @@ -7,7 +7,7 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) :svnadmin => 'svnadmin', :svnlook => 'svnlook' - has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration + has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration, :conflict def create if !@resource.value(:source) @@ -92,6 +92,11 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) else buildargs.push('update', '-r', desired) end + + if @resource.value(:conflict) + args.push('--accept', @resource.value(:conflict)) + end + at_path do svn(*args) end diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index 3bf4029..52eace8 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -46,6 +46,9 @@ Puppet::Type.newtype(:vcsrepo) do feature :submodules, "The repository contains submodules which can be optionally initialized" + feature :conflict, + "The provider supports automatic conflict resolution" + ensurable do attr_accessor :latest @@ -214,6 +217,10 @@ Puppet::Type.newtype(:vcsrepo) do defaultto true end + newparam :conflict do + desc "The action to take if conflicts exist between repository and working copy" + end + autorequire(:package) do ['git', 'git-core'] end -- cgit v1.2.3 From d27759141ec5592fd5d76861efa77a55d07c90a8 Mon Sep 17 00:00:00 2001 From: Colleen Murphy Date: Wed, 25 Mar 2015 12:04:16 -0700 Subject: Fix remote hash ordering for unit tests Without this commit, the unit tests for the git provider changing multiple remotes mocks the remotes in a particular order. While in practice it doesn't matter which remote the update_remotes method updates first, the unit tests must be able to mock them in the correct order. For ruby 1.8.7, a Hash will not necessarily produce key value pairs in the same order on each run, which causes intermittent failures in the unit tests. This change sorts the :source property values before trying to update them, and updates the unit tests to expect the values in alphabetical order. --- lib/puppet/provider/vcsrepo/git.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 9d3f7f3..000032e 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -142,7 +142,8 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) # we loop around the hash. Otherwise, we assume single url specified # in source property if @resource.value(:source).is_a?(Hash) - @resource.value(:source).each do |remote_name, remote_url| + @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 -- cgit v1.2.3 From 7f97a76f4682a7c1d5bfbbc3cd5a6dd9523b1d96 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Wed, 13 May 2015 15:39:01 -0700 Subject: (MODULES-821) Don't use /tmp Very often /tmp is mounted noexec for security reasons related to it being writable by all users. This stopped vcsrepo's git provider from working. This pull request uses puppet's statedir as it is not writable by all users and is a good candidate for transient state like the git provider's identity script for the $GIT_SSH command. An alternative in the future that wouldn't require a temporary file is to set $GIT_SSH_COMMAND instead of $GIT_SSH, except this was added in git 2.3 and is too new to depend on. --- lib/puppet/provider/vcsrepo/git.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 8101253..44e4d04 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -418,7 +418,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) # @!visibility private def git_with_identity(*args) if @resource.value(:identity) - Tempfile.open('git-helper') do |f| + Tempfile.open('git-helper', Puppet[:statedir]) do |f| f.puts '#!/bin/sh' f.puts "exec ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -oConnectTimeout=120 -i #{@resource.value(:identity)} $*" f.close -- cgit v1.2.3 From ae60f5ccb7c00a0e162a06ba05d247688ffbce4b Mon Sep 17 00:00:00 2001 From: Jonathan Tripathy Date: Mon, 22 Jun 2015 15:22:16 +0100 Subject: MODULES-2131 Git provider now takes account of revision property when using depth property. --- lib/puppet/provider/vcsrepo/git.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 13e0793..4603029 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -125,6 +125,9 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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(:ensure) == :bare args << '--bare' -- cgit v1.2.3 From b3cddcbd57639acbf0c4a7fa671a70f787e010da Mon Sep 17 00:00:00 2001 From: Samuel Keeley Date: Mon, 29 Jun 2015 12:01:10 -0700 Subject: fix for detached HEAD on git 2.4+ --- lib/puppet/provider/vcsrepo/git.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 8074950..bf11f3d 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -329,11 +329,13 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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|\(no branch)/ + matches[1] unless matches[1].match /(\(detached from|\(HEAD detached at|\(no branch)/ } end -- cgit v1.2.3 From 2a498ae29cd2d4eeac52fa123bb97e5e2d5b1c90 Mon Sep 17 00:00:00 2001 From: Alex Vandiver Date: Wed, 22 Jul 2015 11:51:37 -0700 Subject: Explitly unset SSH_AUTH_SOCK; it is preferred to the -i flag Even if the -i flag is explicitly passed via the command line, openssh ignores the identity file if an socket exists to an SSH authentication agent. In cases where puppet has been configured to use an explicit identity file, altering behavior based on the calling environment of puppet violates the principle of least surprise, and can lead to inconsistent deployments. Work around this odd corner case of ssh by explicitly unsetting SSH_AUTH_SOCK inside the ssh wrapper. --- lib/puppet/provider/vcsrepo/git.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index bf11f3d..7e921a9 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -425,6 +425,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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 -- cgit v1.2.3 From d68402d1f930d5a30f1ec9224ac3791b6d9d29b9 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Mon, 3 Aug 2015 16:49:01 -0700 Subject: MODULES-1800 - fix case where ensure => latest and no revision specified This would explode when revision was unspecified when you were on a branch. Use the branch you're currently on when updating. --- lib/puppet/provider/vcsrepo/git.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index bf11f3d..f13802b 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -45,7 +45,11 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) # # @return [String] Returns the target sha/tag/branch def latest - @resource.value(:revision) + 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) @@ -281,7 +285,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) # handle upstream branch changes # @!visibility private def checkout(revision = @resource.value(:revision)) - if !local_branch_revision? && remote_branch_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 -- cgit v1.2.3 From 14c05f5d6c589bebc9f93eb117105c14ce7be6f1 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Thu, 13 Aug 2015 16:02:22 -0700 Subject: MODULES-2125 - Allow revision to be passed without source Will also work with empty repositories. --- lib/puppet/provider/vcsrepo/git.rb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index f13802b..7617b13 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -76,7 +76,11 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) #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. - at_path { git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") } + 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 @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true @@ -392,7 +396,17 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) # @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') - update_references + 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? -- cgit v1.2.3 From 6b01539dfee074b798f7e96cb228a42ae6a42c8b Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Sat, 15 Aug 2015 15:45:39 +0200 Subject: Autorequire Package['mercurial'] Along the lines of 2b190756260346931b8f9a0dda8afc0c815710d6, if the Mercurial package is being managed, it stands to reason that the Mercurial package should be installed before trying to potentially manage Mercurial repositories using vcsrepo resources. This commit adds an autorequire to the vcsrepo type that reflects the above premise. --- lib/puppet/type/vcsrepo.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index e5dfbb5..ed5d55a 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -229,6 +229,6 @@ Puppet::Type.newtype(:vcsrepo) do end autorequire(:package) do - ['git', 'git-core'] + ['git', 'git-core', 'mercurial'] end end -- cgit v1.2.3 From f385df10c57a0a09fa316004e6af18acd56df710 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Mon, 17 Aug 2015 12:14:18 -0700 Subject: MODULES-2326 - Run Regexp.escape on the source URL The URL can have special characters, making the regex match fail. --- lib/puppet/provider/vcsrepo/git.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 7617b13..4623f8e 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -111,7 +111,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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(/#{default_url}/).any? + 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 -- cgit v1.2.3 From ba9d0cf6c1d98ea70270faa5cf4e70997ea75595 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Mon, 24 Aug 2015 17:07:37 -0700 Subject: MODULES-1232 Make sure HOME is set correctly --- lib/puppet/provider/vcsrepo/git.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 4623f8e..a34b154 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -3,7 +3,9 @@ require File.join(File.dirname(__FILE__), '..', 'vcsrepo') Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) do desc "Supports Git repositories" - commands :git => 'git' + has_command(:git, 'git') do + environment({ 'HOME' => ENV['HOME'] }) + end has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :branch, :submodules @@ -457,7 +459,8 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) return ret end elsif @resource.value(:user) and @resource.value(:user) != Facter['id'].value - Puppet::Util::Execution.execute("git #{args.join(' ')}", :uid => @resource.value(:user), :failonfail => true) + 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 -- cgit v1.2.3 From 7758331f503a9198921362761079cbfd941c625e Mon Sep 17 00:00:00 2001 From: monai Date: Wed, 9 Sep 2015 19:20:58 +0300 Subject: Add feature depth and param trust_server_cert to svn added param trust server cert updated depth feature updated README.markdown trust_server_cert is not feature trust_server_cert default value should be false add test for depth and trust_server_cert --- lib/puppet/provider/vcsrepo/svn.rb | 14 +++++++++++--- lib/puppet/type/vcsrepo.rb | 8 +++++++- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/svn.rb b/lib/puppet/provider/vcsrepo/svn.rb index 905d5ad..ba77464 100644 --- a/lib/puppet/provider/vcsrepo/svn.rb +++ b/lib/puppet/provider/vcsrepo/svn.rb @@ -7,7 +7,7 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) :svnadmin => 'svnadmin', :svnlook => 'svnlook' - has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration, :conflict + has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration, :conflict, :depth def create if !@resource.value(:source) @@ -15,7 +15,8 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) else checkout_repository(@resource.value(:source), @resource.value(:path), - @resource.value(:revision)) + @resource.value(:revision), + @resource.value(:depth)) end update_owner end @@ -62,6 +63,10 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) args.push('--config-dir', @resource.value(:configuration)) end + if @resource.value(:trust_server_cert) + args.push('--trust-server-cert') + end + args end @@ -105,11 +110,14 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) private - def checkout_repository(source, path, revision) + 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 diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index e5dfbb5..dfc2ec8 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -38,7 +38,7 @@ Puppet::Type.newtype(:vcsrepo) do "The provider understands the CVS_RSH environment variable" feature :depth, - "The provider can do shallow clones" + "The provider can do shallow clones or set scope limit" feature :branch, "The name of the branch" @@ -227,6 +227,12 @@ Puppet::Type.newtype(:vcsrepo) do newparam :conflict do desc "The action to take if conflicts exist between repository and working copy" end + + newparam :trust_server_cert do + desc "Trust server certificate" + newvalues(:true, :false) + defaultto false + end autorequire(:package) do ['git', 'git-core'] -- cgit v1.2.3 From bf0f40ae4efa9095ca9a877acefdb781e1fbf1cd Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Thu, 15 Oct 2015 10:42:01 -0700 Subject: Fix :false to be default value false is not a valid value; only :false is. --- lib/puppet/provider/vcsrepo/svn.rb | 2 +- lib/puppet/type/vcsrepo.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/svn.rb b/lib/puppet/provider/vcsrepo/svn.rb index ba77464..fccfaa5 100644 --- a/lib/puppet/provider/vcsrepo/svn.rb +++ b/lib/puppet/provider/vcsrepo/svn.rb @@ -63,7 +63,7 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) args.push('--config-dir', @resource.value(:configuration)) end - if @resource.value(:trust_server_cert) + if @resource.value(:trust_server_cert) != :false args.push('--trust-server-cert') end diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index da1dcde..290bdad 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -231,7 +231,7 @@ Puppet::Type.newtype(:vcsrepo) do newparam :trust_server_cert do desc "Trust server certificate" newvalues(:true, :false) - defaultto false + defaultto :false end autorequire(:package) do -- cgit v1.2.3 From 7fe9cb225b6458e468469597a54753f1ea621e00 Mon Sep 17 00:00:00 2001 From: godlikeachilles Date: Wed, 2 Dec 2015 15:07:15 +1100 Subject: fix branch existence determintaion functionality this will stop failing in case there is a tag which is a substring of an existing branch name. for example if there is a tag 'release' and a branch 'release/integration' current code will match 'release/integration' with pattern 'release' and decide that a branch checkout is needed. but release branch does not exist so it will fail. this simple fix resolves the issue. --- lib/puppet/provider/vcsrepo/git.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 3b20a83..0249a3c 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -319,7 +319,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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 = at_path { branches.grep /(remotes\/)?#{@resource.value(:remote)}\/#{revision}$/ } branch unless branch.empty? end -- cgit v1.2.3 From b8f25cea95317a4b2a622e2799f1aa7ba159bdca Mon Sep 17 00:00:00 2001 From: "Strech (Sergey Fedorov)" Date: Tue, 22 Dec 2015 23:02:26 +0100 Subject: Add mirror option for git cloning Example: vcsrepo { '/path/to/repo': ensure => mirror, provider => git, source => 'git://example.com/repo.git', } --- lib/puppet/provider/vcsrepo/git.rb | 21 ++++++++++++++++----- lib/puppet/type/vcsrepo.rb | 10 +++++++++- 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 0249a3c..63986ab 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -10,10 +10,14 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :branch, :submodules def create - if @resource.value(:revision) and @resource.value(:ensure) == :bare + 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)) @@ -22,7 +26,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) if @resource.value(:revision) checkout end - if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true + if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true update_submodules end @@ -85,7 +89,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) end end #TODO Would this ever reach here if it is bare? - if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true + if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true update_submodules end update_owner_and_excludes @@ -95,6 +99,10 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) 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 @@ -197,9 +205,12 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) if @resource.value(:branch) args.push('--branch', @resource.value(:branch).to_s) end - if @resource.value(:ensure) == :bare - args << '--bare' + + 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 diff --git a/lib/puppet/type/vcsrepo.rb b/lib/puppet/type/vcsrepo.rb index 290bdad..e2ef0b7 100644 --- a/lib/puppet/type/vcsrepo.rb +++ b/lib/puppet/type/vcsrepo.rb @@ -69,6 +69,8 @@ Puppet::Type.newtype(:vcsrepo) do end when :bare return is == :bare + when :mirror + return is == :mirror end end @@ -83,6 +85,12 @@ Puppet::Type.newtype(:vcsrepo) do end end + newvalue :mirror, :required_features => [:bare_repositories] do + if !provider.exists? + provider.create + end + end + newvalue :absent do provider.destroy end @@ -227,7 +235,7 @@ Puppet::Type.newtype(:vcsrepo) do newparam :conflict do desc "The action to take if conflicts exist between repository and working copy" end - + newparam :trust_server_cert do desc "Trust server certificate" newvalues(:true, :false) -- cgit v1.2.3