Skip to content

Commit

Permalink
vcsrepo: add mode option
Browse files Browse the repository at this point in the history
Signed-off-by: Robin H. Johnson <[email protected]>
Reference: puppetlabs#598
  • Loading branch information
robbat2 committed Jul 1, 2023
1 parent 6462c93 commit 5b15ff6
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 24 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org).

## UNRELEASED

### Added

- support for directory modes for repos [\#599](https://github.com/puppetlabs/puppetlabs-vcsrepo/issues/599) ([robbat2](https://github.com/robbat2))

## [v6.1.0](https://github.com/puppetlabs/puppetlabs-vcsrepo/tree/v6.1.0) - 2023-06-13

[Full Changelog](https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/v6.0.1...v6.1.0)
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -797,37 +797,37 @@ For information on the classes and types, see the [REFERENCE.md](https://github.

Features: `bare_repositories`, `depth`, `multiple_remotes`, `reference_tracking`, `ssh_identity`, `submodules`, `user`

Parameters: `depth`, `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `remote`, `revision`, `source`, `user`
Parameters: `depth`, `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `remote`, `revision`, `source`, `user`, `mode`

##### `bzr` - Supports the Bazaar VCS.

Features: `reference_tracking`

Parameters: `ensure`, `excludes`, `force`, `group`, `owner`, `path`, `provider`, `revision`, `source`
Parameters: `ensure`, `excludes`, `force`, `group`, `owner`, `path`, `provider`, `revision`, `source`, `mode`

##### `cvs` - Supports the CVS VCS.

Features: `cvs_rsh`, `gzip_compression`, `modules`, `reference_tracking`, `user`

Parameters: `compression`, `cvs_rsh`, `ensure`, `excludes`, `force`, `group`, `module`, `owner`, `path`, `provider`
Parameters: `compression`, `cvs_rsh`, `ensure`, `excludes`, `force`, `group`, `module`, `owner`, `path`, `provider`, `mode`

##### `hg` - Supports the Mercurial VCS.

Features: `reference_tracking`, `ssh_identity`, `user`

Parameters: `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `revision`, `source`, `user`
Parameters: `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `revision`, `source`, `user`, `mode`

##### `p4` - Supports the Perforce VCS.

Features: `p4config`, `reference_tracking`

Parameters: `ensure`, `excludes`, `force`, `group`, `owner`, `p4config`, `path`, `provider`, `revision`, `source`
Parameters: `ensure`, `excludes`, `force`, `group`, `owner`, `p4config`, `path`, `provider`, `revision`, `source`, `mode`

##### `svn` - Supports the Subversion VCS.

Features: `basic_auth`, `configuration`, `conflict`, `depth`, `filesystem_types`, `reference_tracking`

Parameters: `basic_auth_password`, `basic_auth_username`, `configuration`, `conflict`, `ensure`, `excludes`, `force`, `fstype`, `group`, `includes`, `owner`, `path`, `provider`, `revision`, `source`, `trust_server_cert`
Parameters: `basic_auth_password`, `basic_auth_username`, `configuration`, `conflict`, `ensure`, `excludes`, `force`, `fstype`, `group`, `includes`, `owner`, `path`, `provider`, `revision`, `source`, `trust_server_cert`, `mode`

<a id="features"></a>
#### Features
Expand Down
4 changes: 4 additions & 0 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ The following parameters are available in the `vcsrepo` type.
* [`trust_server_cert`](#trust_server_cert)
* [`umask`](#umask)
* [`user`](#user)
* [`mode`](#mode)

##### <a name="basic_auth_password"></a>`basic_auth_password`

Expand Down Expand Up @@ -280,3 +281,6 @@ Sets the umask to be used for all repo operations

The user to run for repository operations

##### <a name="mode"></a>`mode`

Sets the mode for the repository directory (non-recursive).
14 changes: 11 additions & 3 deletions lib/puppet/provider/vcsrepo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,26 @@ def check_force

private

def set_ownership
def set_ownership_and_permissions
owner = @resource.value(:owner) || nil
group = @resource.value(:group) || nil
mode = @resource.value(:mode) || nil
excludes = @resource.value(:excludes) || nil
# Change the permission on the repo itself.
# The VCS should maintain permissions on files within the checkout.
FileUtils.chmod(mode, @resource.value(:path)) unless mode.nil?
# We might have no work to do, and this makes it easier for the callers.
return if owner.nil? && group.nil?

if excludes.nil? || excludes.empty?
FileUtils.chown_R(owner, group, @resource.value(:path))
FileUtils.chown_R(owner, group, @resource.value(:path)) unless owner.nil? && group.nil?
else
FileUtils.chown(owner, group, files)
FileUtils.chown(owner, group, files) unless owner.nil? && group.nil?
end
end

def files
# Expensive on large repos
excludes = @resource.value(:excludes)
path = @resource.value(:path)
Dir["#{path}/**/*"].reject { |f| excludes.any? { |p| f.start_with?("#{path}/#{p}") } }
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/provider/vcsrepo/bzr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,6 @@ def clone_repository(revision)
end

def update_owner
set_ownership if @resource.value(:owner) || @resource.value(:group)
set_ownership_and_permissions if @resource.value(:owner) || @resource.value(:group) || @resource.value(:mode)
end
end
2 changes: 1 addition & 1 deletion lib/puppet/provider/vcsrepo/cvs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def create_repository(path)
end

def update_owner
set_ownership if @resource.value(:owner) || @resource.value(:group)
set_ownership_and_permissions if @resource.value(:owner) || @resource.value(:group) || @resource.value(:mode)
end

def runcvs(*args)
Expand Down
23 changes: 15 additions & 8 deletions lib/puppet/provider/vcsrepo/git.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def create
init_repository
self.skip_hooks = @resource.value(:skip_hooks) unless @resource.value(:skip_hooks).nil?
end
update_owner_and_excludes
update_owner_permission_and_excludes
end

def destroy
Expand Down Expand Up @@ -87,8 +87,10 @@ def revision=(desired)
end
end
# TODO: Would this ever reach here if it is bare?
update_submodules if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true
update_owner_and_excludes
if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true
update_submodules
end
update_owner_permission_and_excludes
end

def bare_exists?
Expand Down Expand Up @@ -228,7 +230,7 @@ def update_references
at_path do
git_remote_action('fetch', @resource.value(:remote))
git_remote_action(*fetch_tags_args, @resource.value(:remote))
update_owner_and_excludes
update_owner_permission_and_excludes
end
end

Expand All @@ -246,6 +248,8 @@ def convert_working_copy_to_bare
FileUtils.mv(File.join(@resource.value(:path), '.git'), tempdir)
FileUtils.rm_rf(@resource.value(:path))
FileUtils.mv(tempdir, @resource.value(:path))
FileUtils.chown(@resource.value(:user), @resource.value(:group), @resource.value(:path)) if @resource.value(:user) || @resource.value(:group)
FileUtils.chmod(@resource.value(:mode), @resource.value(:path)) if @resource.value(:mode)
at_path do
exec_git('config', '--local', '--bool', 'core.bare', 'true')
return unless @resource.value(:ensure) == :mirror
Expand All @@ -266,13 +270,15 @@ def convert_bare_to_working_copy
notice 'Converting bare repository to working copy repository'
FileUtils.mv(@resource.value(:path), tempdir)
FileUtils.mkdir(@resource.value(:path))
FileUtils.chown(@resource.value(:user), @resource.value(:group), @resource.value(:path)) if @resource.value(:user) || @resource.value(:group)
FileUtils.chmod(@resource.value(:mode), @resource.value(:path)) if @resource.value(:mode)
FileUtils.mv(tempdir, File.join(@resource.value(:path), '.git'))
if commits?
at_path do
exec_git('config', '--local', '--bool', 'core.bare', 'false')
reset('HEAD')
git_with_identity('checkout', '--force')
update_owner_and_excludes
update_owner_permission_and_excludes
end
end
set_no_mirror if mirror?
Expand Down Expand Up @@ -398,7 +404,8 @@ def init_repository
else
# normal init
FileUtils.mkdir(@resource.value(:path))
FileUtils.chown(@resource.value(:user), nil, @resource.value(:path)) if @resource.value(:user)
FileUtils.chown(@resource.value(:user), @resource.value(:group), @resource.value(:path)) if @resource.value(:user) || @resource.value(:group)
FileUtils.chmod(@resource.value(:mode), @resource.value(:path)) if @resource.value(:mode)
args = ['init']
args << '--bare' if @resource.value(:ensure) == :bare
at_path do
Expand Down Expand Up @@ -580,8 +587,8 @@ def get_revision(rev = 'HEAD')
end

# @!visibility private
def update_owner_and_excludes
set_ownership if @resource.value(:owner) || @resource.value(:group)
def update_owner_permission_and_excludes
set_ownership_and_permissions if @resource.value(:owner) || @resource.value(:group) || @resource.value(:mode)
set_excludes if @resource.value(:excludes)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/provider/vcsrepo/hg.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def clone_repository(revision)
end

def update_owner
set_ownership if @resource.value(:owner) || @resource.value(:group)
set_ownership_and_permissions if @resource.value(:owner) || @resource.value(:group) || @resource.value(:mode)
end

def sensitive?
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/provider/vcsrepo/p4.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def source=(_desired)
private

def update_owner
set_ownership if @resource.value(:owner) || @resource.value(:group)
set_ownership_and_permissions if @resource.value(:owner) || @resource.value(:group) || @resource.value(:mode)
end

# Sync the client workspace files to head or specified revision.
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/provider/vcsrepo/svn.rb
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def create_repository(path)
end

def update_owner
set_ownership if @resource.value(:owner) || @resource.value(:group)
set_ownership_and_permissions if @resource.value(:owner) || @resource.value(:group) || @resource.value(:mode)
end

def update_includes(paths)
Expand Down
4 changes: 4 additions & 0 deletions lib/puppet/type/vcsrepo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ def insync?(is)
desc 'The group/gid that owns the repository files'
end

newparam :mode do
desc 'The permission for the repository directory itself (not recursive)'
end

newparam :user do
desc 'The user to run for repository operations'
end
Expand Down
21 changes: 21 additions & 0 deletions spec/acceptance/clone_repo_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -636,4 +636,25 @@
it { is_expected.to be_mode '664' }
end
end

context 'with mode' do
pp = <<-MANIFEST
vcsrepo { "#{tmpdir}/testrepo_mode":
ensure => present,
provider => git,
source => "file://#{tmpdir}/testrepo.git",
mode => 'u=rwX,g=rX,o=X',
}
MANIFEST
it 'clones a repo' do
# Run it twice and test for idempotency
idempotent_apply(pp)
end

describe file("#{tmpdir}/testrepo_mode") do
# NOTE: '0664' is not supported by 'be_mode'; this must be three digits
# unless the first octet is non-zero.
it { is_expected.to be_mode '751' }
end
end
end
4 changes: 2 additions & 2 deletions spec/unit/puppet/provider/vcsrepo/git_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ def branch_a_list(include_branch = nil?)
.with('config', '--local', '--bool', 'core.bare', 'false').and_return(true)
expect(provider).to receive(:reset).with('HEAD').and_return(true)
expect(provider).to receive(:git_with_identity).with('checkout', '--force').and_return(true)
expect(provider).to receive(:update_owner_and_excludes).and_return(true)
expect(provider).to receive(:update_owner_permission_and_excludes).and_return(true)
expect(provider).to receive(:mirror?).and_return(false)
provider.instance_eval { convert_bare_to_working_copy }
end
Expand All @@ -330,7 +330,7 @@ def branch_a_list(include_branch = nil?)
.with('config', '--local', '--bool', 'core.bare', 'false').and_return(true)
expect(provider).to receive(:reset).with('HEAD').and_return(true)
expect(provider).to receive(:git_with_identity).with('checkout', '--force').and_return(true)
expect(provider).to receive(:update_owner_and_excludes).and_return(true)
expect(provider).to receive(:update_owner_permission_and_excludes).and_return(true)
expect(provider).to receive(:exec_git).with('config', '--unset', 'remote.origin.mirror')
expect(provider).to receive(:mirror?).and_return(true)
provider.instance_eval { convert_bare_to_working_copy }
Expand Down

0 comments on commit 5b15ff6

Please sign in to comment.