diff --git a/Puppetfile b/Puppetfile index f73002e6e..5cde4cecf 100644 --- a/Puppetfile +++ b/Puppetfile @@ -199,7 +199,7 @@ mod 'trove', :git => 'https://github.com/stackforge/puppet-trove' mod 'vcsrepo', - :commit => '6f7507a2a48ff0a58c7db026760a2eb84e382a77', + :commit => 'b394f6961d984190a9ead8a3465f360ae5c6d365', :git => 'https://github.com/puppetlabs/puppetlabs-vcsrepo.git' mod 'vlan', diff --git a/vcsrepo/.gitignore b/vcsrepo/.gitignore index ddd2d45d2..b5db85e05 100644 --- a/vcsrepo/.gitignore +++ b/vcsrepo/.gitignore @@ -1,4 +1,9 @@ -coverage -.DS_Store -.#* -\#* +pkg/ +Gemfile.lock +vendor/ +spec/fixtures/ +.vagrant/ +.bundle/ +coverage/ +.idea/ +*.iml diff --git a/vcsrepo/.sync.yml b/vcsrepo/.sync.yml new file mode 100644 index 000000000..6fa460a29 --- /dev/null +++ b/vcsrepo/.sync.yml @@ -0,0 +1,7 @@ +--- +.travis.yml: + script: "\"bundle exec rake spec SPEC_OPTS='--format documentation'\"" +Rakefile: + unmanaged: true +spec/spec_helper.rb: + unmanaged: true diff --git a/vcsrepo/.travis.yml b/vcsrepo/.travis.yml index 5e3f7442c..8cfaf2319 100644 --- a/vcsrepo/.travis.yml +++ b/vcsrepo/.travis.yml @@ -1,34 +1,17 @@ --- -branches: - only: - - master -notifications: - email: false language: ruby -script: -- 'bundle exec gem list' -- 'bundle exec rake spec' -after_success: -- git clone -q git://github.com/puppetlabs/ghpublisher.git .forge-releng -- .forge-releng/publish -rvm: -- 1.8.7 -- 1.9.3 -- 2.0.0 -env: - matrix: - - PUPPET_VERSION=2.6.18 - - PUPPET_VERSION=2.7.22 - - PUPPET_VERSION=3.2.1 - global: - - PUBLISHER_LOGIN=puppetlabs - - secure: |- - ZiIkYd9+CdPzpwSjFPnVkCx1FIlipxpbdyD33q94h2Tj5zXjNb1GXizVy0NR - kVxGhU5Ld8y9z8DTqKRgCI1Yymg3H//OU++PKLOQj/X5juWVR4URBNPeBOzu - IJBDl1MADKA4i1+jAZPpz4mTvTtKS4pWKErgCSmhSfsY1hs7n6c= +bundler_args: --without system_tests +script: "bundle exec rake spec SPEC_OPTS='--format documentation'" matrix: - exclude: + fast_finish: true + include: + - rvm: 1.8.7 + env: PUPPET_GEM_VERSION="~> 2.7.0" FACTER_GEM_VERSION="~> 1.6.0" + - rvm: 1.8.7 + env: PUPPET_GEM_VERSION="~> 2.7.0" FACTER_GEM_VERSION="~> 1.7.0" - rvm: 1.9.3 - env: PUPPET_VERSION=2.6.18 + env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 2.0.0 - env: PUPPET_VERSION=2.6.18 + env: PUPPET_GEM_VERSION="~> 3.0" +notifications: + email: false diff --git a/vcsrepo/CHANGELOG.md b/vcsrepo/CHANGELOG.md new file mode 100644 index 000000000..5b8f7d1e2 --- /dev/null +++ b/vcsrepo/CHANGELOG.md @@ -0,0 +1,110 @@ +##2014-11-04 - Supported Release 1.2.0 +###Summary + +This release includes some improvements for git, mercurial, and cvs providers, and fixes the bug where there were warnings about multiple default providers. + +####Features +- Update git and mercurial providers to set UID with `Puppet::Util::Execution.execute` instead of `su` +- Allow git excludes to be string or array +- Add `user` feature to cvs provider + +####Bugfixes +- No more warnings about multiple default providers! (MODULES-428) + +##2014-07-14 - Supported Release 1.1.0 +###Summary +This release adds a Perforce provider* and corrects the git provider behavior +when using `ensure => latest`. + +*(Only git provider is currently supported.) + +####Features +- New Perforce provider + +####Bugfixes +- (MODULES-660) Fix behavior with `ensure => latest` and detached HEAD +- Spec test fixes + +##2014-06-30 - Supported Release 1.0.2 +###Summary +This supported release adds SLES 11 to the list of compatible OSs and +documentation updates for support. + +##2014-06-17 - Supported Release 1.0.1 +###Summary +This release is the first supported release of vcsrepo. The readme has been +greatly improved. + +####Features +- Updated and expanded readme to follow readme template + +####Fixes +- Remove SLES from compatability metadata +- Unpin rspec development dependencies +- Update acceptance level testing + +##2014-06-04 - Version 1.0.0 +###Summary + +This release focuses on a number of bugfixes, and also has some +new features for Bzr and Git. + +####Features +- Bzr: + - Call set_ownership +- Git: + - Add ability for shallow clones + - Use -a and desired for HARD resets + - Use rev-parse to get tag canonical revision + +####Fixes +- HG: + - Only add ssh options when it's talking to the network +- Git: + - Fix for issue with detached HEAD + - force => true will now destroy and recreate repo + - Actually use the remote parameter + - Use origin/master instead of origin/HEAD when on master +- SVN: + - Fix svnlook behavior with plain directories + +##2013-11-13 - Version 0.2.0 +###Summary + +This release mainly focuses on a number of bugfixes, which should +significantly improve the reliability of Git and SVN. Thanks to +our many contributors for all of these fixes! + +####Features +- Git: + - Add autorequire for Package['git'] +- HG: + - Allow user and identity properties. +- Bzr: + - "ensure => latest" support. +- SVN: + - Added configuration parameter. + - Add support for master svn repositories. +- CVS: + - Allow for setting the CVS_RSH environment variable. + +####Fixes +- Handle Puppet::Util[::Execution].withenv for 2.x and 3.x properly. +- Change path_empty? to not do full directory listing. +- Overhaul spec tests to work with rspec2. +- Git: + - Improve Git SSH usage documentation. + - Add ssh session timeouts to prevent network issues from blocking runs. + - Fix git provider checkout of a remote ref on an existing repo. + - Allow unlimited submodules (thanks to --recursive). + - Use git checkout --force instead of short -f everywhere. + - Update git provider to handle checking out into an existing (empty) dir. +- SVN: + - Handle force property. for svn. + - Adds support for changing upstream repo url. + - Check that the URL of the WC matches the URL from the manifest. + - Changed from using "update" to "switch". + - Handle revision update without source switch. + - Fix svn provider to look for '^Revision:' instead of '^Last Changed Rev:'. +- CVS: + - Documented the "module" attribute. diff --git a/vcsrepo/CONTRIBUTING.md b/vcsrepo/CONTRIBUTING.md new file mode 100644 index 000000000..f1cbde4bb --- /dev/null +++ b/vcsrepo/CONTRIBUTING.md @@ -0,0 +1,220 @@ +Checklist (and a short version for the impatient) +================================================= + + * Commits: + + - Make commits of logical units. + + - Check for unnecessary whitespace with "git diff --check" before + committing. + + - Commit using Unix line endings (check the settings around "crlf" in + git-config(1)). + + - Do not check in commented out code or unneeded files. + + - The first line of the commit message should be a short + description (50 characters is the soft limit, excluding ticket + number(s)), and should skip the full stop. + + - Associate the issue in the message. The first line should include + the issue number in the form "(#XXXX) Rest of message". + + - The body should provide a meaningful commit message, which: + + - uses the imperative, present tense: "change", not "changed" or + "changes". + + - includes motivation for the change, and contrasts its + implementation with the previous behavior. + + - Make sure that you have tests for the bug you are fixing, or + feature you are adding. + + - Make sure the test suites passes after your commit: + `bundle exec rspec spec/acceptance` More information on [testing](#Testing) below + + - When introducing a new feature, make sure it is properly + documented in the README.md + + * Submission: + + * Pre-requisites: + + - Make sure you have a [GitHub account](https://github.com/join) + + - [Create a ticket](https://tickets.puppetlabs.com/secure/CreateIssue!default.jspa), or [watch the ticket](https://tickets.puppetlabs.com/browse/) you are patching for. + + * Preferred method: + + - Fork the repository on GitHub. + + - Push your changes to a topic branch in your fork of the + repository. (the format ticket/1234-short_description_of_change is + usually preferred for this project). + + - Submit a pull request to the repository in the puppetlabs + organization. + +The long version +================ + + 1. Make separate commits for logically separate changes. + + Please break your commits down into logically consistent units + which include new or changed tests relevant to the rest of the + change. The goal of doing this is to make the diff easier to + read for whoever is reviewing your code. In general, the easier + your diff is to read, the more likely someone will be happy to + review it and get it into the code base. + + If you are going to refactor a piece of code, please do so as a + separate commit from your feature or bug fix changes. + + We also really appreciate changes that include tests to make + sure the bug is not re-introduced, and that the feature is not + accidentally broken. + + Describe the technical detail of the change(s). If your + description starts to get too long, that is a good sign that you + probably need to split up your commit into more finely grained + pieces. + + Commits which plainly describe the things which help + reviewers check the patch and future developers understand the + code are much more likely to be merged in with a minimum of + bike-shedding or requested changes. Ideally, the commit message + would include information, and be in a form suitable for + inclusion in the release notes for the version of Puppet that + includes them. + + Please also check that you are not introducing any trailing + whitespace or other "whitespace errors". You can do this by + running "git diff --check" on your changes before you commit. + + 2. Sending your patches + + To submit your changes via a GitHub pull request, we _highly_ + recommend that you have them on a topic branch, instead of + directly on "master". + It makes things much easier to keep track of, especially if + you decide to work on another thing before your first change + is merged in. + + GitHub has some pretty good + [general documentation](http://help.github.com/) on using + their site. They also have documentation on + [creating pull requests](http://help.github.com/send-pull-requests/). + + In general, after pushing your topic branch up to your + repository on GitHub, you can switch to the branch in the + GitHub UI and click "Pull Request" towards the top of the page + in order to open a pull request. + + + 3. Update the related GitHub issue. + + If there is a GitHub issue associated with the change you + submitted, then you should update the ticket to include the + location of your branch, along with any other commentary you + may wish to make. + +Testing +======= + +Getting Started +--------------- + +Our puppet modules provide [`Gemfile`](./Gemfile)s which can tell a ruby +package manager such as [bundler](http://bundler.io/) what Ruby packages, +or Gems, are required to build, develop, and test this software. + +Please make sure you have [bundler installed](http://bundler.io/#getting-started) +on your system, then use it to install all dependencies needed for this project, +by running + +```shell +% bundle install +Fetching gem metadata from https://rubygems.org/........ +Fetching gem metadata from https://rubygems.org/.. +Using rake (10.1.0) +Using builder (3.2.2) +-- 8><-- many more --><8 -- +Using rspec-system-puppet (2.2.0) +Using serverspec (0.6.3) +Using rspec-system-serverspec (1.0.0) +Using bundler (1.3.5) +Your bundle is complete! +Use `bundle show [gemname]` to see where a bundled gem is installed. +``` + +NOTE some systems may require you to run this command with sudo. + +If you already have those gems installed, make sure they are up-to-date: + +```shell +% bundle update +``` + +With all dependencies in place and up-to-date we can now run the tests: + +```shell +% rake spec +``` + +This will execute all the [rspec tests](http://rspec-puppet.com/) tests +under [spec/defines](./spec/defines), [spec/classes](./spec/classes), +and so on. rspec tests may have the same kind of dependencies as the +module they are testing. While the module defines in its [Modulefile](./Modulefile), +rspec tests define them in [.fixtures.yml](./fixtures.yml). + +Some puppet modules also come with [beaker](https://github.com/puppetlabs/beaker) +tests. These tests spin up a virtual machine under +[VirtualBox](https://www.virtualbox.org/)) with, controlling it with +[Vagrant](http://www.vagrantup.com/) to actually simulate scripted test +scenarios. In order to run these, you will need both of those tools +installed on your system. + +You can run them by issuing the following command + +```shell +% rake spec_clean +% rspec spec/acceptance +``` + +This will now download a pre-fabricated image configured in the [default node-set](./spec/acceptance/nodesets/default.yml), +install puppet, copy this module and install its dependencies per [spec/spec_helper_acceptance.rb](./spec/spec_helper_acceptance.rb) +and then run all the tests under [spec/acceptance](./spec/acceptance). + +Writing Tests +------------- + +XXX getting started writing tests. + +If you have commit access to the repository +=========================================== + +Even if you have commit access to the repository, you will still need to +go through the process above, and have someone else review and merge +in your changes. The rule is that all changes must be reviewed by a +developer on the project (that did not write the code) to ensure that +all changes go through a code review process. + +Having someone other than the author of the topic branch recorded as +performing the merge is the record that they performed the code +review. + + +Additional Resources +==================== + +* [Getting additional help](http://puppetlabs.com/community/get-help) + +* [Writing tests](http://projects.puppetlabs.com/projects/puppet/wiki/Development_Writing_Tests) + +* [Patchwork](https://patchwork.puppetlabs.com) + +* [General GitHub documentation](http://help.github.com/) + +* [GitHub pull request documentation](http://help.github.com/send-pull-requests/) + diff --git a/vcsrepo/Gemfile b/vcsrepo/Gemfile index e6e114d25..62c569397 100644 --- a/vcsrepo/Gemfile +++ b/vcsrepo/Gemfile @@ -1,5 +1,31 @@ -source 'https://rubygems.org' -gem 'rake', '~> 0.8.7' -gem 'rspec', '~> 1.3' -gem 'mocha', '~> 0.12.9', :require => false -gem 'puppet', "~> #{ENV['PUPPET_VERSION'] || '2.7.22'}" +source ENV['GEM_SOURCE'] || "https://rubygems.org" + +group :development, :unit_tests do + gem 'rake', :require => false + gem 'rspec-core', '3.1.7', :require => false + gem 'rspec-puppet', '~> 1.0', :require => false + gem 'puppetlabs_spec_helper', :require => false + gem 'puppet-lint', :require => false + gem 'simplecov', :require => false + gem 'puppet_facts', :require => false + gem 'json', :require => false +end + +group :system_tests do + gem 'beaker-rspec', :require => false + gem 'serverspec', :require => false +end + +if facterversion = ENV['FACTER_GEM_VERSION'] + gem 'facter', facterversion, :require => false +else + gem 'facter', :require => false +end + +if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false +else + gem 'puppet', :require => false +end + +# vim:ft=ruby diff --git a/vcsrepo/Modulefile b/vcsrepo/Modulefile deleted file mode 100644 index 5d95183b4..000000000 --- a/vcsrepo/Modulefile +++ /dev/null @@ -1,4 +0,0 @@ -name 'puppetlabs/vcsrepo' -version '0.1.2' -summary 'Manage repositories from various version control systems' -description 'Manage repositories from various version control systems' diff --git a/vcsrepo/README.BZR.markdown b/vcsrepo/README.BZR.markdown deleted file mode 100644 index cc257e9fd..000000000 --- a/vcsrepo/README.BZR.markdown +++ /dev/null @@ -1,47 +0,0 @@ -Using vcsrepo with Bazaar -========================= - -To create a blank repository ----------------------------- - -Define a `vcsrepo` without a `source` or `revision`: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => bzr - } - -To branch from an existing repository -------------------------------------- - -Provide the `source` location: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => bzr, - source => 'lp:myproj' - } - -For a specific revision, use `revision` with a valid revisionspec -(see `bzr help revisionspec` for more information on formatting a revision): - - vcsrepo { "/path/to/repo": - ensure => present, - provider => bzr, - source => 'lp:myproj', - revision => 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x' - } - -For sources that use SSH (eg, `bzr+ssh://...`, `sftp://...`) ------------------------------------------------------------- - -Manage your SSH keys with Puppet and use `require` in your `vcsrepo` -to ensure they are present. For more information, see the `require` -metaparameter documentation[1]. - -More Examples -------------- - -For examples you can run, see `examples/bzr/` - -[1]: http://docs.puppetlabs.com/references/stable/metaparameter.html#require diff --git a/vcsrepo/README.CVS.markdown b/vcsrepo/README.CVS.markdown deleted file mode 100644 index 10121a78f..000000000 --- a/vcsrepo/README.CVS.markdown +++ /dev/null @@ -1,56 +0,0 @@ -Using vcsrepo with CVS -====================== - -To create a blank repository ----------------------------- - -Define a `vcsrepo` without a `source` or `revision`: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => cvs - } - -To checkout/update from a repository ------------------------------------- - -To get the current mainline: - - vcsrepo { "/path/to/workspace": - ensure => present, - provider => cvs, - source => ":pserver:anonymous@example.com:/sources/myproj" - } - -You can use the `compression` parameter (it works like CVS `-z`): - - vcsrepo { "/path/to/workspace": - ensure => present, - provider => cvs, - compression => 3, - source => ":pserver:anonymous@example.com:/sources/myproj" - } - -For a specific tag, use `revision`: - - vcsrepo { "/path/to/workspace": - ensure => present, - provider => cvs, - compression => 3, - source => ":pserver:anonymous@example.com:/sources/myproj", - revision => "SOMETAG" - } - -For sources that use SSH ------------------------- - -Manage your SSH keys with Puppet and use `require` in your `vcsrepo` -to ensure they are present. For more information, see the `require` -metaparameter documentation[1]. - -More Examples -------------- - -For examples you can run, see `examples/cvs/` - -[1]: http://docs.puppetlabs.com/references/stable/metaparameter.html#require diff --git a/vcsrepo/README.GIT.markdown b/vcsrepo/README.GIT.markdown deleted file mode 100644 index 846bdcc29..000000000 --- a/vcsrepo/README.GIT.markdown +++ /dev/null @@ -1,95 +0,0 @@ -Using vcsrepo with Git -====================== - -To create a blank repository ----------------------------- - -Define a `vcsrepo` without a `source` or `revision`: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => git - } - -If you're defining this for a central/"official" repository, you'll -probably want to make it a "bare" repository. Do this by setting -`ensure` to `bare` instead of `present`: - - vcsrepo { "/path/to/repo": - ensure => bare, - provider => git - } - -To clone/pull a repository ----------------------------- - -To get the current [master] HEAD: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => git, - source => "git://example.com/repo.git" - } - -For a specific revision or branch (can be a commit SHA, tag or branch name): - - vcsrepo { "/path/to/repo": - ensure => present, - provider => git, - source => 'git://example.com/repo.git', - revision => '0c466b8a5a45f6cd7de82c08df2fb4ce1e920a31' - } - - vcsrepo { "/path/to/repo": - ensure => present, - provider => git, - source => 'git://example.com/repo.git', - revision => '1.1.2rc1' - } - - vcsrepo { "/path/to/repo": - ensure => present, - provider => git, - source => 'git://example.com/repo.git', - revision => 'development' - } - -Check out as a user: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => git, - source => 'git://example.com/repo.git', - revision => '0c466b8a5a45f6cd7de82c08df2fb4ce1e920a31', - user => 'someUser' - } - -Keep the repository at the latest revision (note: this will always overwrite local changes to the repository): - - vcsrepo { "/path/to/repo": - ensure => latest, - provider => git, - source => 'git://example.com/repo.git', - revision => 'master', - } - -For sources that use SSH (eg, `username@server:...`) ----------------------------------------------------- - -If your SSH key is associated with a user, simply fill the `user` parameter to use his keys. - -Example: - - user => 'toto' # will use toto's $HOME/.ssh setup - - -Otherwise, manage your SSH keys with Puppet and use `require` in your `vcsrepo` to ensure they are present. -For more information, see the `require` metaparameter documentation[1]. - -More Examples -------------- - -For examples you can run, see `examples/git/` - -[1]: http://docs.puppetlabs.com/references/stable/metaparameter.html#require - diff --git a/vcsrepo/README.HG.markdown b/vcsrepo/README.HG.markdown deleted file mode 100644 index 55ceef4ac..000000000 --- a/vcsrepo/README.HG.markdown +++ /dev/null @@ -1,73 +0,0 @@ -Using vcsrepo with Mercurial -============================ - -To create a blank repository ----------------------------- - -Define a `vcsrepo` without a `source` or `revision`: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => hg - } - -To clone/pull & update a repository ------------------------------------ - -To get the default branch tip: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => hg, - source => "http://hg.example.com/myrepo" - } - -For a specific changeset, use `revision`: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => hg, - source => "http://hg.example.com/myrepo", - revision => '21ea4598c962' - } - -You can also set `revision` to a tag: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => hg, - source => "http://hg.example.com/myrepo", - revision => '1.1.2' - } - -Check out as a user: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => hg, - source => "http://hg.example.com/myrepo", - user => 'user' - } - -Specify an SSH identity key: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => hg, - source => "ssh://hg@hg.example.com/myrepo", - identity => "/home/user/.ssh/id_dsa, - } - -For sources that use SSH (eg, `ssh://...`) ------------------------------------------- - -Manage your SSH keys with Puppet and use `require` in your `vcsrepo` -to ensure they are present. For more information, see the `require` -metaparameter documentation[1]. - -More Examples -------------- - -For examples you can run, see `examples/hg/` - -[1]: http://docs.puppetlabs.com/references/stable/metaparameter.html#require diff --git a/vcsrepo/README.SVN.markdown b/vcsrepo/README.SVN.markdown deleted file mode 100644 index f374094c1..000000000 --- a/vcsrepo/README.SVN.markdown +++ /dev/null @@ -1,62 +0,0 @@ -Using vcsrepo with Subversion -============================= - -To create a blank repository ----------------------------- - -To create a blank repository suitable for use as a central repository, -define a `vcsrepo` without a `source` or `revision`: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => svn - } - -To checkout from a repository ------------------------------ - -Provide a `source` qualified to the branch/tag you want: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => svn, - source => "svn://svnrepo/hello/branches/foo" - } - -You can provide a specific `revision`: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => svn, - source => "svn://svnrepo/hello/branches/foo", - revision => '1234' - } - - -Using a specified Subversion configuration directory ------------------------------ - -Provide a `configuration` parameter which should be a directory path on the local system where your svn configuration -files are. Typically, it is /path/to/.subversion: - - vcsrepo { "/path/to/repo": - ensure => present, - provider => svn, - source => "svn://svnrepo/hello/branches/foo", - configuration => "/path/to/.subversion" - } - - -For sources that use SSH (eg, `svn+ssh://...`) ----------------------------------------------- - -Manage your SSH keys with Puppet and use `require` in your `vcsrepo` -to ensure they are present. For more information, see the `require` -metaparameter documentation[1]. - -More Examples -------------- - -For examples you can run, see `examples/svn/` - -[1]: http://docs.puppetlabs.com/references/stable/metaparameter.html#require diff --git a/vcsrepo/README.markdown b/vcsrepo/README.markdown index 848725630..34a51e207 100644 --- a/vcsrepo/README.markdown +++ b/vcsrepo/README.markdown @@ -1,32 +1,591 @@ -vcsrepo -======= +#vcsrepo [![Build Status](https://travis-ci.org/puppetlabs/puppetlabs-vcsrepo.png?branch=master)](https://travis-ci.org/puppetlabs/puppetlabs-vcsrepo) -Purpose -------- +####Table of Contents -This provides a single type, `vcsrepo`. +1. [Overview](#overview) +2. [Module Description - What the module does and why it is useful](#module-description) +3. [Setup - The basics of getting started with vcsrepo](#setup) + * [Beginning with vcsrepo](#beginning-with-vcsrepo) +4. [Usage - Configuration options and additional functionality](#usage) + * [Bazaar](#bazaar) + * [CVS](#cvs) + * [Git](#git) + * [Mercurial](#mercurial) + * [Perforce](#perforce) + * [Subversion](#subversion) +5. [Reference - An under-the-hood peek at what the module is doing and how](#reference) + * [Type: vcsrepo](#type-vcsrepo) + * [Providers](#providers) + * [Features](#features) + * [Parameters](#parameters) + * [Features and Parameters by Provider](#features-and-parameters-by-provider) +5. [Limitations - OS compatibility, etc.](#limitations) +6. [Development - Guide for contributing to the module](#development) -This type can be used to describe: +##Overview + +The vcsrepo module allows you to use Puppet to easily deploy content from your version control system (VCS). + +##Module Description + +This module provides a single type with providers for each VCS, which can be used to describe: * A working copy checked out from a (remote or local) source, at an arbitrary revision -* A "blank" working copy not associated with a source (when it makes +* A blank working copy not associated with a source (when it makes sense for the VCS being used) -* A "blank" central repository (when the distinction makes sense for the VCS - being used) +* A blank central repository (when the distinction makes sense for the VCS + being used) + +##Setup + +Before you begin using vcsrepo, it's worth keeping in mind that this module will not install VCS software for you. If you are going to use this module, you must have already installed your preferred VCS. + +Also, this module, like Puppet generally, will not create parent directories for you. You will need to have your parent directories in place before you begin. + +###Beginning with vcsrepo + +To get started with the vcsrepo module, you must simply define the type `vcsrepo` with a path to your repository and the [type of VCS](#Usage) you're using in `provider` (in the below example, Git). + + vcsrepo { "/path/to/repo": + ensure => present, + provider => git, + } + +##Usage + +The vcsrepo module works with the following VCSs: + +* [Git (git)](#git)* +* [Bazaar (bzr)](#bazaar) +* [CVS (cvs)](#cvs) +* [Mercurial (hg)](#mercurial) +* [Perforce (p4)](#perforce) +* [Subversion (svn)](#subversion) + +**Note:** Git is the only VCS provider officially [supported](https://forge.puppetlabs.com/supported) by Puppet Labs. + + +###Git + +#####To create a blank repository + +To create a blank repository suitable for use as a central repository, +define `vcsrepo` without `source` or `revision`. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => git, + } + +If you're defining `vcsrepo` for a central or official repository, you may want to make it a bare repository. You do this by setting `ensure` to 'bare' rather than 'present'. + + vcsrepo { "/path/to/repo": + ensure => bare, + provider => git, + } + +#####To clone/pull a repository + +To get the current HEAD on the master branch, + + vcsrepo { "/path/to/repo": + ensure => present, + provider => git, + source => "git://example.com/repo.git", + } + +To get a specific revision or branch (can be a commit SHA, tag, or branch name), + + **SHA** + + vcsrepo { "/path/to/repo": + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => '0c466b8a5a45f6cd7de82c08df2fb4ce1e920a31', + } + +**Tag** + + vcsrepo { "/path/to/repo": + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => '1.1.2rc1', + } + +**Branch name** + + vcsrepo { "/path/to/repo": + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => 'development', + } + +To check out a branch as a specific user, + + vcsrepo { "/path/to/repo": + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => '0c466b8a5a45f6cd7de82c08df2fb4ce1e920a31', + user => 'someUser', + } + +To keep the repository at the latest revision (**WARNING:** this will always overwrite local changes to the repository), + + vcsrepo { "/path/to/repo": + ensure => latest, + provider => git, + source => 'git://example.com/repo.git', + revision => 'master', + } + +To clone the repository but skip initialiazing submodules, + + vcsrepo { "/path/to/repo": + ensure => latest, + provider => git, + source => 'git://example.com/repo.git', + submodules => false, + } + +##### Using multiple remotes with a repository +Instead of specifying a single string in the 'source' property, you can specify a hash with multiple name => URL mappings, + + vcsrepo { "/path/to/repo": + ensure => present, + provider => git, + source => { + "origin" => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", + "other_remote" => "https://github.com/other_user/puppetlabs-vcsrepo.git" + }, + } + +It is important to note that you must specify a mapping for the remote that is specified in the 'remote' property - this is set to 'origin' by default. + +#####Sources that use SSH + +When your source uses SSH, such as 'username@server:…', you can manage your SSH keys with Puppet using the [require](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter in `vcsrepo` to ensure they are present. + +For SSH keys associated with a user, enter the username in the `user` parameter. Doing so will use that user's keys. + + user => 'toto' # will use toto's $HOME/.ssh setup + +#####Further Examples + +For more examples using Git, see `examples/git/`. + +###Bazaar + +#####Create a blank repository + +To create a blank repository suitable for use as a central repository, +define `vcsrepo` without `source` or `revision`. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => bzr, + } + +#####Branch from an existing repository + +Provide the `source` location to branch from an existing repository. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => bzr, + source => 'lp:myproj', + } + +For a specific revision, use `revision` with a valid revisionspec +(see `bzr help revisionspec` for more information on formatting a revision). + + vcsrepo { "/path/to/repo": + ensure => present, + provider => bzr, + source => 'lp:myproj', + revision => 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x', + } + +#####Sources that use SSH + +When your source uses SSH, for instance 'bzr+ssh://...' or 'sftp://...,' +you can manage your SSH keys with Puppet using the [require](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter in `vcsrepo` to ensure they are present. + +#####Further examples + +For more examples using Bazaar, see `examples/bzr/`. + +###CVS + +#####To create a blank repository + +To create a blank repository suitable for use as a central repository, +define `vcsrepo` without `source` or `revision`. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => cvs, + } + +#####To checkout/update from a repository + +To get the current mainline, + + vcsrepo { "/path/to/workspace": + ensure => present, + provider => cvs, + source => ":pserver:anonymous@example.com:/sources/myproj", + } + +To get a specific module on the current mainline, + + vcsrepo {"/vagrant/lockss-daemon-source": + ensure => present, + provider => cvs, + source => ":pserver:anonymous@lockss.cvs.sourceforge.net:/cvsroot/lockss", + module => "lockss-daemon", + } + + +You can use the `compression` parameter to set the GZIP compression levels for your repository history. + + vcsrepo { "/path/to/workspace": + ensure => present, + provider => cvs, + compression => 3, + source => ":pserver:anonymous@example.com:/sources/myproj", + } + +For a specific tag, use `revision`. + + vcsrepo { "/path/to/workspace": + ensure => present, + provider => cvs, + compression => 3, + source => ":pserver:anonymous@example.com:/sources/myproj", + revision => "SOMETAG", + } + +#####Sources that use SSH + +When your source uses SSH, you can manage your SSH keys with Puppet using the [require](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter in `vcsrepo` to ensure they are present. + +#####Further examples + +For for more examples using CVS, see `examples/cvs/`. + +###Mercurial + +#####To create a blank repository + +To create a blank repository suitable for use as a central repository, +define `vcsrepo` without `source` or `revision`. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => hg, + } + +#####To clone/pull & update a repository + +To get the default branch tip, + + vcsrepo { "/path/to/repo": + ensure => present, + provider => hg, + source => "http://hg.example.com/myrepo", + } + +For a specific changeset, use `revision`. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => hg, + source => "http://hg.example.com/myrepo", + revision => '21ea4598c962', + } + +You can also set `revision` to a tag. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => hg, + source => "http://hg.example.com/myrepo", + revision => '1.1.2', + } + +To check out as a specific user, + + vcsrepo { "/path/to/repo": + ensure => present, + provider => hg, + source => "http://hg.example.com/myrepo", + user => 'user', + } + +To specify an SSH identity key, + + vcsrepo { "/path/to/repo": + ensure => present, + provider => hg, + source => "ssh://hg@hg.example.com/myrepo", + identity => "/home/user/.ssh/id_dsa, + } + +To specify a username and password for HTTP Basic authentication, + + vcsrepo { "/path/to/repo": + ensure => latest, + provider => hg, + source => 'http://hg.example.com/myrepo', + basic_auth_username => 'hgusername', + basic_auth_password => 'hgpassword', + } + +#####Sources that use SSH + +When your source uses SSH, such as 'ssh://...', you can manage your SSH keys with Puppet using the [require](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter in `vcsrepo` to ensure they are present. + +#####Further Examples + +For more examples using Mercurial, see `examples/hg/`. + +###Perforce + +#####To create an empty Workspace + +To create an empty Workspace, define a `vcsrepo` without a `source` or `revision`. The +Environment variables P4PORT, P4USER, etc... are used to define the Perforce server +connection settings. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => p4 + } + +If no `P4CLIENT` environment name is provided a workspace generated name is calculated +based on the Digest of path and hostname. For example: + + puppet-91bc00640c4e5a17787286acbe2c021c + +A Perforce configuration file can be used by setting the `P4CONFIG` environment or +defining `p4config`. If a configuration is defined, then the environment variable for +`P4CLIENT` is replaced. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => p4, + p4config => '.p4config' + } + +#####To create/update and sync a Perforce workspace + +To sync a depot path to head, ensure `latest`: + + vcsrepo { "/path/to/repo": + ensure => latest, + provider => p4, + source => '//depot/branch/...' + } + +For a specific changelist, ensure `present` and specify a `revision`: + + vcsrepo { "/path/to/repo": + ensure => present, + provider => p4, + source => '//depot/branch/...', + revision => '2341' + } + +You can also set `revision` to a label: + + vcsrepo { "/path/to/repo": + ensure => present, + provider => p4, + source => '//depot/branch/...', + revision => 'my_label' + } + +#####To authenticate against the Perforce server + +Either set the environment variables `P4USER` and `P4PASSWD` or use a configuration file. +For secure servers set the `P4PASSWD` with a valid ticket generated using `p4 login -p`. + +#####Further Examples + +For examples you can run, see `examples/p4/` + +###Subversion + +#####To create a blank repository + +To create a blank repository suitable for use as a central repository, +define `vcsrepo` without `source` or `revision`. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => svn, + } + +#####To check out from a repository + +Provide a `source` pointing to the branch/tag you want to check out from a repository. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => svn, + source => "svn://svnrepo/hello/branches/foo", + } + +You can also provide a specific revision. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => svn, + source => "svn://svnrepo/hello/branches/foo", + revision => '1234', + } + +#####Using a specific Subversion configuration directory + +To use a specific configuration directory, provide a `configuration` parameter which should be a directory path on the local system where your svn configuration files are. Typically, it is '/path/to/.subversion'. + + vcsrepo { "/path/to/repo": + ensure => present, + provider => svn, + source => "svn://svnrepo/hello/branches/foo", + configuration => "/path/to/.subversion", + } + +#####Sources that use SSH + +When your source uses SSH, such as 'svn+ssh://...', you can manage your SSH keys with Puppet using the [require](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter in `vcsrepo` to ensure they are present. + +####Further examples + +For more examples using Subversion, see `examples/svn/`. + +##Reference + +###Type: vcsrepo + +The vcsrepo module is slightly unusual in that it is simply a type and providers. Each provider abstracts a different VCS, and a series of features are available to each provider based on its specific needs. + +####Providers + +**Note**: Not all features are available with all providers. + +* `git` - Supports the Git VCS. (Contains features: `bare_repositories`, `depth`, `multiple_remotes`, `reference_tracking`, `ssh_identity`, `user`.) +* `bar` - Supports the Bazaar VCS. (Contains features: `reference_tracking`.) +* `cvs` - Supports the CVS VCS. (Contains features: `cvs_rsh`, `gzip_compression`, `modules`, `reference_tracking`, `user`.) +* `dummy` - +* `hg` - Supports the Mercurial VCS. (Contains features: `reference_tracking`, `ssh_identity`, `user`.) +* `p4` - Supports the Perforce VCS. (Contains features: `reference_tracking`, `filesystem_types`, `p4config`.) +* `svn` - Supports the Subversion VCS. (Contains features: `basic_auth`, `configuration`, `filesystem_types`, `reference_tracking`.) + +####Features + +**Note**: Not all features are available with all providers. + +* `bare_repositories` - The provider differentiates between bare repositories and those with working copies. (Available with `git`.) +* `basic_auth` - The provider supports HTTP Basic Authentication. (Available with `svn`.) +* `configuration` - The provider supports setting the configuration path.(Available with `svn`.) +* `cvs_rsh` - The provider understands the CVS_RSH environment variable. (Available with `cvs`.) +* `depth` - The provider can do shallow clones. (Available with `git`.) +* `filesystem_types` - The provider supports different filesystem types. (Available with `svn`.) +* `gzip_compression` - The provider supports explicit GZip compression levels. (Available with `cvs`.) +* `modules` - The provider allows specific repository modules to be chosen. (Available with `cvs`.) +* `multiple_remotes` - The repository tracks multiple remote repositories. (Available with `git`.) +* `reference_tracking` - The provider supports tracking revision references that can change over time (e.g. some VCS tags and branch names). (Available with `bar`, `cvs`, `git`, `hg`, `svn`.) +* `ssh_identity` - The provider supports a configurable SSH identity file. (Available with `git` and `hg`.) +* `user` - The provider can run as a different user. (Available with `git`, `hg` and `cvs`.) +* `p4config` - The provider support setting the P4CONFIG environment. (Available with `p4`.) +* `submodules` - The provider supports repository submodules which can be optionally initialized. (Available with `git`.) + +####Parameters + +* `basic_auth_password` - Specifies the HTTP Basic Authentication password. (Requires the `basic_auth` feature.) +* `basic_auth_username` - Specifies the HTTP Basic Authentication username. (Requires the `basic_auth` feature.) +* `compression` - Set the GZIP compression levels for your repository history. (Requires the `gzip_compression` feature.) +* `configuration` - Sets the configuration directory to use. (Requires the `configuration` feature.) +* `cvs_rsh` - The value to be used for the CVS_RSH environment variable. (Requires the `cvs_rsh` feature.) +* `depth` - The value to be used to do a shallow clone. (Requires the `depth` feature.) +* `ensure` - Determines the state of the repository. Valid values are 'present', 'bare', 'absent', 'latest'. +* `excludes` - Lists any files to be excluded from the repository. Can be an array or string. +* `force` - Forces repository creation. Valid values are 'true' and 'false'. **WARNING** Forcing will destroy any files in the path. +* `fstype` - Sets the filesystem type. (Requires the `filesystem_types` feature.) +* `group` - Determines the group/gid that owns the repository files. +* `identity` - Specifies the SSH identity file. (Requires the `ssh_identity` feature.) +* `module` - Specifies the repository module to manage. (Requires the `modules` feature.) +* `owner` - Specifies the user/uid that owns the repository files. +* `path` - Specifies the absolute path to the repository. If omitted, the value defaults to the resource's title. +* `provider` - Specifies the backend to use for this vcsrepo resource. +* `remote` - Specifies the remote repository to track. (Requires the `multiple_remotes` feature.) +* `revision` - Sets the revision of the repository. Values can match /^\S+$/. +* `source` - Specifies the source URI for the repository. +* `user` - Specifies the user to run as for repository operations. +* `p4config` - Specifies the P4CONFIG environment used for Perforce connection configuration. + +####Features and Parameters by Provider + +#####`git` +**Features**: `bare_repositories`, `depth`, `multiple_remotes`, `reference_tracking`, `ssh_identity`, `user`, `submodules` + +**Parameters**: `depth`, `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `remote`, `revision`, `source`, `user`, `submodules` + +#####`bzr` +**Features**: `reference_tracking` + +**Parameters**: `ensure`, `excludes`, `force`, `group`, `owner`, `path`, `provider`, `revision`, `source`, `user` + +#####`cvs` +**Features**: `cvs_rsh`, `gzip_compression`, `modules`, `reference_tracking`, `revision` + +**Parameters**: `compression`, `cvs_rsh`, `ensure`, `excludes`, `force`, `group`, `module`, `owner`, `path`, `provider`, `revision`, `source`, `user` + +#####`hg` +**Features**: `reference_tracking`, `ssh_identity`, `user` + +**Parameters**: `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `revision`, `source`, `user` + +#####`p4` +**Features**: `reference_tracking`, `filesystem_types`, `p4config` + +**Parameters**: `ensure`, `group`, `owner`, `path`, `provider`, `revision`, `source`, `p4config` + +#####`svn` +**Features**: `basic_auth`, `configuration`, `filesystem_types`, `reference_tracking` + +**Parameters**: `basic_auth_password`, `basic_auth_username`, `configuration`, `ensure`, `excludes`, `force`, `fstype`, `group`, `owner`, `path`, `provider`, `revision`, `source`, `user` + +##Limitations + +Git is the only VCS provider officially [supported](https://forge.puppetlabs.com/supported) by Puppet Labs. + +This module has been built on and tested against Puppet 2.7 and higher. + +The module has been tested on: + +RedHat Enterprise Linux 5/6 +Debian 6/7 +CentOS 5/6 +Ubuntu 12.04 +Gentoo +Arch Linux +FreeBSD -Supported Version Control Systems ---------------------------------- +Testing on other platforms has been light and cannot be guaranteed. -This module supports a wide range of VCS types, each represented by a -separate provider. +##Development -For information on how to use this module with a specific VCS, see -`README..markdown`. +Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad of hardware, software, and deployment configurations that Puppet is intended to serve. -License -------- +We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. -See LICENSE. +You can read the complete module contribution guide on the Puppet Labs wiki. diff --git a/vcsrepo/Rakefile b/vcsrepo/Rakefile old mode 100644 new mode 100755 index 3e005fffb..cb80defc3 --- a/vcsrepo/Rakefile +++ b/vcsrepo/Rakefile @@ -1,13 +1,78 @@ -require 'spec/rake/spectask' -Spec::Rake::SpecTask.new(:spec) do |spec| - spec.libs << 'lib' << 'spec' - spec.spec_files = FileList['spec/**/*_spec.rb'] +require 'puppetlabs_spec_helper/rake_tasks' +require 'rake' + +desc "Run beaker-rspec and beaker tests" +task 'beaker:test:all',[:host,:type] => ["rake:beaker:rspec:test", "rake:beaker:test"] do |t,args| +end + +desc "Run beaker-rspec tests" +task 'beaker:rspec:test',[:host,:type] => [:set_beaker_variables] do |t,args| + Rake::Task['beaker-rspec:test'].invoke(args) +end + +desc "Run beaker tests" +task 'beaker:test',[:host,:type] => [:set_beaker_variables] do |t,args| + sh(build_beaker_command args) +end + +desc "Run beaker rspec tasks against pe" +RSpec::Core::RakeTask.new('beaker-rspec:test',[:host,:type]=>:set_beaker_variables) do |t,args| + t.pattern = 'spec/acceptance' + t.rspec_opts = '--color' + t.verbose = true end -Spec::Rake::SpecTask.new(:rcov) do |spec| - spec.libs << 'lib' << 'spec' - spec.pattern = 'spec/**/*_spec.rb' - spec.rcov = true +desc "Run beaker and beaker-rspec tasks" +task 'beaker:test:pe',:host do |t,args| + args.with_defaults(:type=> 'pe') + Rake::Task['beaker:test'].invoke(args[:host],args[:type]) end -task :default => :spec +task 'beaker:test:git',:host do |t,args| + args.with_defaults({:type=> 'git'}) + Rake::Task['beaker:test'].invoke(args[:host],args[:type]) +end + +task :set_beaker_variables do |t,args| + puts 'Setting environment variables for testing' + if args[:host] + ENV['BEAKER_set'] = args[:host] + puts "Host to test #{ENV['BEAKER_set']}" + end + ENV['BEAKER_IS_PE'] = args[:type] == 'pe'? "true": "false" + if ENV['BEAKER_setfile'] + @hosts_config = ENV['BEAKER_setfile'] + end + if File.exists?(check_args_for_keyfile(args.extras)) + ENV['BEAKER_keyfile'] = check_args_for_keyfile(args.extras) + end +end + +def build_beaker_command(args) + cmd = ["beaker"] + cmd << "--type #{args[:type]}" unless !args[:type] + if File.exists?("./.beaker-#{args[:type]}.cfg") + cmd << "--options-file ./.beaker-#{args[:type]}.cfg" + end + if File.exists?(@hosts_config) + cmd << "--hosts #{@hosts_config}" + end + if File.exists?('./spec/acceptance/beaker_helper.rb') + cmd << "--pre-suite ./spec/acceptance/beaker_helper.rb" + end + if File.exists?("./spec/acceptance/beaker") + cmd << "--tests ./spec/acceptance/beaker" + end + if File.exists?(check_args_for_keyfile(args.extras)) + cmd << "--keyfile #{check_args_for_keyfile(args.extras)}" + end + cmd.join(" ") +end + +def check_args_for_keyfile(extra_args) + keyfile = '' + extra_args.each do |a| + keyfile = a unless (`ssh-keygen -l -f #{a}`.gsub(/\n/,"").match(/is not a .*key file/)) + end + return keyfile +end diff --git a/vcsrepo/examples/hg/clone_basic_auth.pp b/vcsrepo/examples/hg/clone_basic_auth.pp new file mode 100644 index 000000000..984f8eafd --- /dev/null +++ b/vcsrepo/examples/hg/clone_basic_auth.pp @@ -0,0 +1,7 @@ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => 'hg', + source => 'http://hg.example.com/myrepo', + basic_auth_username => 'hgusername', + basic_auth_password => 'hgpassword', +} diff --git a/vcsrepo/examples/p4/create_client.pp b/vcsrepo/examples/p4/create_client.pp new file mode 100644 index 000000000..0f8233aa1 --- /dev/null +++ b/vcsrepo/examples/p4/create_client.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => present, + provider => 'p4', +} diff --git a/vcsrepo/examples/p4/delete_client.pp b/vcsrepo/examples/p4/delete_client.pp new file mode 100644 index 000000000..1e305f126 --- /dev/null +++ b/vcsrepo/examples/p4/delete_client.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => absent, + provider => 'p4', +} diff --git a/vcsrepo/examples/p4/latest_client.pp b/vcsrepo/examples/p4/latest_client.pp new file mode 100644 index 000000000..a7caeb68d --- /dev/null +++ b/vcsrepo/examples/p4/latest_client.pp @@ -0,0 +1,5 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => latest, + provider => 'p4', + source => '//depot/...', +} diff --git a/vcsrepo/examples/p4/sync_client.pp b/vcsrepo/examples/p4/sync_client.pp new file mode 100644 index 000000000..fc0e29c22 --- /dev/null +++ b/vcsrepo/examples/p4/sync_client.pp @@ -0,0 +1,6 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => present, + provider => 'p4', + source => '//depot/...', + revision => '30', +} diff --git a/vcsrepo/lib/puppet/provider/vcsrepo.rb b/vcsrepo/lib/puppet/provider/vcsrepo.rb index 2c026ba86..8793e632c 100644 --- a/vcsrepo/lib/puppet/provider/vcsrepo.rb +++ b/vcsrepo/lib/puppet/provider/vcsrepo.rb @@ -17,6 +17,14 @@ def path_exists? File.directory?(@resource.value(:path)) end + def path_empty? + # Path is empty if the only entries are '.' and '..' + d = Dir.new(@resource.value(:path)) + d.read # should return '.' + d.read # should return '..' + d.read.nil? + end + # Note: We don't rely on Dir.chdir's behavior of automatically returning the # value of the last statement -- for easier stubbing. def at_path(&block) #:nodoc: diff --git a/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb b/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb index 6688ce87b..797d84d2c 100644 --- a/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb +++ b/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb @@ -3,7 +3,7 @@ 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 @@ -52,6 +52,7 @@ def revision=(desired) bzr('update', '-r', desired, ':parent') end end + update_owner end def latest @@ -70,6 +71,7 @@ def latest? def create_repository(path) bzr('init', path) + update_owner end def clone_repository(revision) @@ -80,6 +82,12 @@ def clone_repository(revision) args.push(@resource.value(:source), @resource.value(:path)) bzr(*args) + update_owner end + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end end diff --git a/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb b/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb index 206e73295..7a8f6ef32 100644 --- a/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb +++ b/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb @@ -3,8 +3,8 @@ Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) do desc "Supports CVS repositories/workspaces" - optional_commands :cvs => 'cvs' - has_features :gzip_compression, :reference_tracking, :modules, :cvs_rsh + commands :cvs => 'cvs' + has_features :gzip_compression, :reference_tracking, :modules, :cvs_rsh, :user def create if !@resource.value(:source) @@ -33,13 +33,13 @@ def destroy 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 @@ def revision else @rev = 'HEAD' end - debug "Checkout is on branch/tag '#{@rev}'" + Puppet.debug "Checkout is on branch/tag '#{@rev}'" end return @rev end @@ -119,19 +119,17 @@ def update_owner 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 - # 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 + Puppet.debug "Running as user " + @resource.value(:user) + Puppet::Util::Execution.execute([:cvs, *args], :uid => @resource.value(:user), :custom_environment => e) + else + Puppet::Util::Execution.execute([:cvs, *args], :custom_environment => e) end end end diff --git a/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb b/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb index f7b4e54b8..27bfbbed7 100644 --- a/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb +++ b/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb @@ -3,7 +3,7 @@ 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" diff --git a/vcsrepo/lib/puppet/provider/vcsrepo/git.rb b/vcsrepo/lib/puppet/provider/vcsrepo/git.rb index 58330f653..9d3f7f34e 100644 --- a/vcsrepo/lib/puppet/provider/vcsrepo/git.rb +++ b/vcsrepo/lib/puppet/provider/vcsrepo/git.rb @@ -3,26 +3,27 @@ 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 - optional_commands :git => 'git', - :su => 'su' - has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user + commands :git => 'git' + + has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :submodules 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)) + clone_repository(default_url, @resource.value(:path)) + update_remotes + 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 + if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true update_submodules end + end update_owner_and_excludes end @@ -31,63 +32,49 @@ def destroy FileUtils.rm_rf(@resource.value(:path)) end + # Checks to see if the current revision is equal to the revision on the + # remote (whether on a branch, tag, or reference) + # + # @return [Boolean] Returns true if the repo is on the latest revision def latest? - 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 == 'master' - return get_revision("#{@resource.value(:remote)}/HEAD") - elsif branch == '(no branch)' - return get_revision('HEAD') - else - return get_revision("#{@resource.value(:remote)}/%s" % 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)) - canonical = at_path { git_with_identity('show', @resource.value(:revision)).scan(/^commit (.*)/).to_s } - 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) + #branches require more work. if local_branch_revision?(desired) - # 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. + #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 @@ -98,26 +85,81 @@ def bare_exists? 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? - 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(/#{default_url}/).any? + else + File.directory?(File.join(@resource.value(:path), '.git')) + end end def exists? working_copy_exists? || bare_exists? end - def update_remote_origin_url - current = git_with_identity('config', 'remote.origin.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)) + 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 @@ -126,17 +168,25 @@ def update_references 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'] + 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 - if !File.exist?(File.join(@resource.value(:path), '.git')) + if @resource.value(:remote) != 'origin' + args.push('--origin', @resource.value(:remote)) + end + if !working_copy_exists? args.push(source, path) Dir.chdir("/") do git_with_identity(*args) @@ -146,8 +196,9 @@ def clone_repository(source, path) end end + # @!visibility private 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 @@ -157,6 +208,7 @@ def check_force end end + # @!visibility private def init_repository(path) check_force if @resource.value(:ensure) == :bare && working_copy_exists? @@ -183,6 +235,7 @@ def init_repository(path) # /.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) @@ -196,6 +249,7 @@ def convert_working_copy_to_bare # / # to: # /.git + # @!visibility private def convert_bare_to_working_copy notice "Converting bare repository to working copy repository" FileUtils.mv(@resource.value(:path), tempdir) @@ -208,6 +262,7 @@ def convert_bare_to_working_copy 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)) @@ -215,26 +270,35 @@ def commits_in?(dot_git) 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}' @@ -242,52 +306,102 @@ def remote_branch_revision?(revision = @resource.value(:revision)) branch unless branch.empty? end + # Determins if the branch is already cached locally + # @!visibility private def local_branch_revision?(revision = @resource.value(:revision)) at_path { branches.include?(revision) } end + # @!visibility private def tag_revision?(revision = @resource.value(:revision)) at_path { tags.include?(revision) } end + # @!visibility private def branches at_path { git_with_identity('branch', '-a') }.gsub('*', ' ').split(/\n/).map { |line| line.strip } end + # @!visibility private def on_branch? - at_path { git_with_identity('branch', '-a') }.split(/\n/).grep(/\*/).first.to_s.gsub('*', '').strip + at_path { + matches = git_with_identity('branch', '-a').match /\*\s+(.*)/ + 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") }}} + # 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 - def get_revision(rev) - 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 @@ -297,6 +411,7 @@ def update_owner_and_excludes end end + # @!visibility private def git_with_identity(*args) if @resource.value(:identity) Tempfile.open('git-helper') do |f| @@ -314,8 +429,8 @@ def git_with_identity(*args) return ret end - elsif @resource.value(:user) - su(@resource.value(:user), '-c', "git #{args.join(' ')}" ) + elsif @resource.value(:user) and @resource.value(:user) != Facter['id'].value + Puppet::Util::Execution.execute("git #{args.join(' ')}", :uid => @resource.value(:user), :failonfail => true) else git(*args) end diff --git a/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb b/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb index 4886b7a1f..294c2a977 100644 --- a/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb +++ b/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb @@ -3,9 +3,9 @@ Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) do desc "Supports Mercurial repositories" - optional_commands :hg => 'hg', - :su => 'su' - has_features :reference_tracking, :ssh_identity, :user + commands :hg => 'hg' + + has_features :reference_tracking, :ssh_identity, :user, :basic_auth def create if !@resource.value(:source) @@ -37,7 +37,7 @@ def latest? 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 @@ def revision def revision=(desired) at_path do begin - hg_wrapper('pull') + hg_wrapper('pull', { :remote => true }) rescue end begin @@ -92,6 +92,7 @@ def clone_repository(revision) end args.push(@resource.value(:source), @resource.value(:path)) + args.push({ :remote => true }) hg_wrapper(*args) end @@ -102,12 +103,26 @@ def update_owner 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 @resource.value(:basic_auth_username) && @resource.value(:basic_auth_password) + args += [ + "--config", "\"auth.x.prefix=#{@resource.value(:source)}\"", + "--config", "\"auth.x.username=#{@resource.value(:basic_auth_username)}\"", + "--config", "\"auth.x.password=#{@resource.value(:basic_auth_password)}\"", + "--config", "\"auth.x.schemes=http https\"" + ] + end + + if options[:remote] and @resource.value(:identity) args += ["--ssh", "ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -i #{@resource.value(:identity)}"] end - if @resource.value(:user) + 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 diff --git a/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb b/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb new file mode 100644 index 000000000..b429bcbb3 --- /dev/null +++ b/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb @@ -0,0 +1,278 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Perforce depots" + + has_features :filesystem_types, :reference_tracking, :p4config + + def create + # create or update client + create_client(client_name) + + # if source provided, sync client + source = @resource.value(:source) + if source + revision = @resource.value(:revision) + sync_client(source, revision) + end + + update_owner + end + + def working_copy_exists? + # Check if the server is there, or raise error + p4(['info'], {:marshal => false}) + + # Check if workspace is setup + args = ['where'] + args.push(@resource.value(:path) + "...") + hash = p4(args, {:raise => false}) + + return (hash['code'] != "error") + end + + def exists? + working_copy_exists? + end + + def destroy + args = ['client'] + args.push('-d', '-f') + args.push(client_name) + p4(args) + FileUtils.rm_rf(@resource.value(:path)) + end + + def latest? + rev = self.revision + if rev + (rev >= self.latest) + else + true + end + end + + def latest + args = ['changes'] + args.push('-m1', @resource.value(:source)) + hash = p4(args) + + return hash['change'].to_i + end + + def revision + args = ['cstat'] + args.push(@resource.value(:source)) + hash = p4(args, {:marshal => false}) + hash = marshal_cstat(hash) + + revision = 0 + if hash && hash['code'] != 'error' + hash['data'].each do |c| + if c['status'] == 'have' + change = c['change'].to_i + revision = change if change > revision + end + end + end + return revision + end + + def revision=(desired) + sync_client(@resource.value(:source), desired) + update_owner + end + + private + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end + + # Sync the client workspace files to head or specified revision. + # Params: + # +source+:: Depot path to sync + # +revision+:: Perforce change list to sync to (optional) + def sync_client(source, revision) + Puppet.debug "Syncing: #{source}" + args = ['sync'] + if revision + args.push(source + "@#{revision}") + else + args.push(source) + end + p4(args) + end + + # Returns the name of the Perforce client workspace + def client_name + p4config = @resource.value(:p4config) + + # default (generated) client name + path = @resource.value(:path) + host = Facter.value('hostname') + default = "puppet-" + Digest::MD5.hexdigest(path + host) + + # check config for client name + set_client = nil + if p4config && File.file?(p4config) + open(p4config) do |f| + m = f.grep(/^P4CLIENT=/).pop + p = /^P4CLIENT=(.*)$/ + set_client = p.match(m)[1] if m + end + end + + return set_client || ENV['P4CLIENT'] || default + end + + # Create (or update) a client workspace spec. + # If a client name is not provided then a hash based on the path is used. + # Params: + # +client+:: Name of client workspace + # +path+:: The Root location of the Perforce client workspace + def create_client(client) + Puppet.debug "Creating client: #{client}" + + # fetch client spec + hash = parse_client(client) + hash['Root'] = @resource.value(:path) + hash['Description'] = "Generated by Puppet VCSrepo" + + # check is source is a Stream + source = @resource.value(:source) + if source + parts = source.split(/\//) + if parts && parts.length >= 4 + source = "//" + parts[2] + "/" + parts[3] + streams = p4(['streams', source], {:raise => false}) + if streams['code'] == "stat" + hash['Stream'] = streams['Stream'] + notice "Streams" + streams['Stream'].inspect + end + end + end + + # save client spec + save_client(hash) + end + + + # Fetches a client workspace spec from Perforce and returns a hash map representation. + # Params: + # +client+:: name of the client workspace + def parse_client(client) + args = ['client'] + args.push('-o', client) + hash = p4(args) + + return hash + end + + + # Saves the client workspace spec from the given hash + # Params: + # +hash+:: hash map of client spec + def save_client(hash) + spec = String.new + view = "\nView:\n" + + hash.keys.sort.each do |k| + v = hash[k] + next if( k == "code" ) + if(k.to_s =~ /View/ ) + view += "\t#{v}\n" + else + spec += "#{k.to_s}: #{v.to_s}\n" + end + end + spec += view + + args = ['client'] + args.push('-i') + p4(args, {:input => spec, :marshal => false}) + end + + # Sets Perforce Configuration environment. + # P4CLIENT generated, but overwitten if defined in config. + def config + p4config = @resource.value(:p4config) + + cfg = Hash.new + cfg.store 'P4CONFIG', p4config if p4config + cfg.store 'P4CLIENT', client_name + return cfg + end + + def p4(args, options = {}) + # Merge custom options with defaults + opts = { + :raise => true, # Raise errors + :marshal => true, # Marshal output + }.merge(options) + + cmd = ['p4'] + cmd.push '-R' if opts[:marshal] + cmd.push args + cmd_str = cmd.respond_to?(:join) ? cmd.join(' ') : cmd + + Puppet.debug "environment: #{config}" + Puppet.debug "command: #{cmd_str}" + + hash = Hash.new + Open3.popen3(config, cmd_str) do |i, o, e, t| + # Send input stream if provided + if(opts[:input]) + Puppet.debug "input:\n" + opts[:input] + i.write opts[:input] + i.close + end + + if(opts[:marshal]) + hash = Marshal.load(o) + else + hash['data'] = o.read + end + + # Raise errors, Perforce or Exec + if(opts[:raise] && !e.eof && t.value != 0) + raise Puppet::Error, "\nP4: #{e.read}" + end + if(opts[:raise] && hash['code'] == 'error' && t.value != 0) + raise Puppet::Error, "\nP4: #{hash['data']}" + end + end + + Puppet.debug "hash: #{hash}\n" + return hash + end + + # helper method as cstat does not Marshal + def marshal_cstat(hash) + data = hash['data'] + code = 'error' + + list = Array.new + change = Hash.new + data.each_line do |l| + p = /^\.\.\. (.*) (.*)$/ + m = p.match(l) + if m + change[m[1]] = m[2] + if m[1] == 'status' + code = 'stat' + list.push change + change = Hash.new + end + end + end + + hash = Hash.new + hash.store 'code', code + hash.store 'data', list + return hash + end + +end diff --git a/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb b/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb index bfc9b76e7..a1b1714a5 100644 --- a/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb +++ b/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb @@ -3,9 +3,9 @@ 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 @@ -24,8 +24,10 @@ def working_copy_exists? if File.directory?(@resource.value(:path)) # :path is an svn checkout return true if File.directory?(File.join(@resource.value(:path), '.svn')) - # :path is an svn server - return true if svnlook('uuid', @resource.value(:path)) + if File.file?(File.join(@resource.value(:path), 'format')) + # :path is an svn server + return true if svnlook('uuid', @resource.value(:path)) + end end false end @@ -66,7 +68,7 @@ def buildargs def latest args = buildargs.push('info', '-r', 'HEAD') at_path do - svn(*args)[/^Last Changed Rev:\s+(\d+)/m, 1] + svn(*args)[/^Revision:\s+(\d+)/m, 1] end end @@ -80,7 +82,7 @@ def sourceurl def revision args = buildargs.push('info') at_path do - svn(*args)[/^Last Changed Rev:\s+(\d+)/m, 1] + svn(*args)[/^Revision:\s+(\d+)/m, 1] end end diff --git a/vcsrepo/lib/puppet/type/vcsrepo.rb b/vcsrepo/lib/puppet/type/vcsrepo.rb index 8225721ad..3bf40294f 100644 --- a/vcsrepo/lib/puppet/type/vcsrepo.rb +++ b/vcsrepo/lib/puppet/type/vcsrepo.rb @@ -37,6 +37,15 @@ feature :cvs_rsh, "The provider understands the CVS_RSH environment variable" + feature :depth, + "The provider can do shallow clones" + + feature :p4config, + "The provider understands Perforce Configuration" + + feature :submodules, + "The repository contains submodules which can be optionally initialized" + ensurable do attr_accessor :latest @@ -73,7 +82,7 @@ def insync?(is) 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 @@ -191,4 +200,21 @@ def retrieve 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 + + newparam :p4config, :required_features => [:p4config] 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 end diff --git a/vcsrepo/metadata.json b/vcsrepo/metadata.json new file mode 100644 index 000000000..242583a57 --- /dev/null +++ b/vcsrepo/metadata.json @@ -0,0 +1,80 @@ +{ + "name": "puppetlabs-vcsrepo", + "version": "1.2.0", + "author": "Puppet Labs", + "summary": "Puppet module providing a type to manage repositories from various version control systems", + "license": "GPLv2", + "source": "https://github.com/puppetlabs/puppetlabs-vcsrepo", + "project_page": "https://github.com/puppetlabs/puppetlabs-vcsrepo", + "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "OracleLinux", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "Scientific", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "SLES", + "operatingsystemrelease": [ + "10 SP4", + "11 SP1", + "12" + ] + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "6", + "7" + ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "10.04", + "12.04", + "14.04" + ] + } + ], + "requirements": [ + { + "name": "pe", + "version_requirement": "3.x" + }, + { + "name": "puppet", + "version_requirement": "3.x" + } + ], + "dependencies": [ + + ] +} diff --git a/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb b/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb new file mode 100644 index 000000000..421c5f063 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb @@ -0,0 +1,69 @@ +test_name 'C3492 - checkout with basic auth (http protocol)' +skip_test 'HTTP not supported yet for basic auth using git. See FM-1331' + +# Globals +repo_name = 'testrepo_checkout' +user = 'foo' +password = 'bar' +http_server_script = 'basic_auth_http_daemon.rb' + +hosts.each do |host| + ruby = '/opt/puppet/bin/ruby' if host.is_pe? || 'ruby' + gem = '/opt/puppet/bin/gem' if host.is_pe? || 'gem' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + script =<<-EOF + require 'sinatra' + + set :bind, '0.0.0.0' + set :static, true + set :public_folder, '#{tmpdir}' + + + use Rack::Auth::Basic do |username, password| + username == '#{user}' && password == '#{password}' + end + EOF + create_remote_file(host, "#{tmpdir}/#{http_server_script}", script) + on(host, "#{gem} install sinatra") + on(host, "#{ruby} #{tmpdir}/#{http_server_script} &") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} #{tmpdir}/#{http_server_script}' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout with puppet using basic auth' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:4567/testrepo.git", + provider => git, + basic_auth_username => '#{user}', + basic_auth_password => '#{password}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb b/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb new file mode 100644 index 000000000..753e50ca2 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb @@ -0,0 +1,77 @@ +test_name 'C3493 - checkout with basic auth (https protocol)' +skip_test 'waiting for CA trust solution' + +# Globals +repo_name = 'testrepo_checkout' +user = 'foo' +password = 'bar' +http_server_script = 'basic_auth_https_daemon.rb' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start https server' do + script =<<-EOF + require 'webrick' + require 'webrick/https' + + authenticate = Proc.new do |req, res| + WEBrick::HTTPAuth.basic_auth(req, res, '') do |user, password| + user == '#{user}' && password == '#{password}' + end + end + + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :DocumentRootOptions=> {:HandlerCallback => authenticate}, + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, "#{tmpdir}/#{http_server_script}", script) + on(host, "#{ruby} #{tmpdir}/#{http_server_script}") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} #{tmpdir}/#{http_server_script}' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout with puppet using basic auth' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8443/testrepo.git", + provider => git, + basic_auth_username => '#{user}', + basic_auth_password => '#{password}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb b/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb new file mode 100644 index 000000000..3b47c485b --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb @@ -0,0 +1,53 @@ +test_name 'C3494 - checkout with basic auth (git protocol)' + +# Globals +repo_name = 'testrepo_checkout' +user = 'foo' +password = 'bar' +http_server_script = 'basic_auth_http_daemon.rb' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'checkout with puppet using basic auth' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + basic_auth_username => '#{user}', + basic_auth_password => '#{password}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout (silent error for basic auth using git protocol)" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb new file mode 100644 index 000000000..3d2131c27 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb @@ -0,0 +1,48 @@ +test_name 'C3438 - checkout a branch (file protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb new file mode 100644 index 000000000..49b034e3e --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb @@ -0,0 +1,48 @@ +test_name 'C3437 - checkout a branch (file path)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb new file mode 100644 index 000000000..9557de85f --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb @@ -0,0 +1,53 @@ +test_name 'C3436 - checkout a branch (git protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb new file mode 100644 index 000000000..fec60e2a9 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb @@ -0,0 +1,61 @@ +test_name 'C3441 - checkout a branch (http protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb new file mode 100644 index 000000000..3474c73d1 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb @@ -0,0 +1,68 @@ +test_name 'C3442 - checkout a branch (https protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb new file mode 100644 index 000000000..493b3f498 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb @@ -0,0 +1,59 @@ +test_name 'C3439 - checkout a branch (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb new file mode 100644 index 000000000..5195ab8cd --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb @@ -0,0 +1,59 @@ +test_name 'C3440 - checkout a branch (ssh protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb new file mode 100644 index 000000000..7b9e64d7e --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb @@ -0,0 +1,46 @@ +test_name 'C3609 - checkout a branch that does not exist' + +# Globals +repo_name = 'testrepo_branch_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout branch that does not exist with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => 'non_existent_branch', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify that master branch is checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb b/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb new file mode 100644 index 000000000..45413a967 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb @@ -0,0 +1,46 @@ +test_name 'C3427 - clone (file protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb b/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb new file mode 100644 index 000000000..a57e05a4c --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb @@ -0,0 +1,46 @@ +test_name 'C3426 - clone (file path)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb b/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb new file mode 100644 index 000000000..3bceb5dd2 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb @@ -0,0 +1,51 @@ +test_name 'C3425 - clone (git protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb b/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb new file mode 100644 index 000000000..f545dab3d --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb @@ -0,0 +1,59 @@ +test_name 'C3430 - clone (http protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb b/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb new file mode 100644 index 000000000..8758435a2 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb @@ -0,0 +1,66 @@ +test_name 'C3431 - clone (https protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb b/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb new file mode 100644 index 000000000..3bc3e3048 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb @@ -0,0 +1,49 @@ +test_name 'C3511 - clone over an existing repo with force' + +# Globals +repo_name = 'testrepo_already_exists' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + on(host, "mkdir #{tmpdir}/#{repo_name}") + on(host, "cd #{tmpdir}/#{repo_name} && git init") + on(host, "cd #{tmpdir}/#{repo_name} && touch a && git add a && git commit -m 'a'") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone over existing repo with force using puppet' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + @existing_sha = res.stdout + end + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + force => true, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify new repo has replaced old one' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + fail_test('original repo not replaced by force') if res.stdout.include? "#{@existing_sha}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb b/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb new file mode 100644 index 000000000..dec275fab --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb @@ -0,0 +1,46 @@ +test_name 'C3507 - clone repo with excludes in repo' + +# Globals +repo_name = 'testrepo_with_excludes_in_repo' +exclude1 = 'file1.txt' +exclude2 ='file2.txt' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone repo with excludes in repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + excludes => [ '#{exclude1}', '#{exclude2}' ], + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify exludes are known to git' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/info/exclude") do |res| + fail_test('exclude not found') unless res.stdout.include? "#{exclude1}" + fail_test('exclude not found') unless res.stdout.include? "#{exclude2}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb b/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb new file mode 100644 index 000000000..ba3793092 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb @@ -0,0 +1,46 @@ +test_name 'C3508 - clone repo with excludes not in repo' + +# Globals +repo_name = 'testrepo_with_excludes_not_in_repo' +exclude1 = 'worh02o' +exclude2 ='ho398b' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone repo with excludes not in repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + excludes => [ '#{exclude1}', '#{exclude2}' ], + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify exludes are known to git' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/info/exclude") do |res| + fail_test('exclude not found') unless res.stdout.include? "#{exclude1}" + fail_test('exclude not found') unless res.stdout.include? "#{exclude2}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb b/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb new file mode 100644 index 000000000..59370ebdd --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb @@ -0,0 +1,57 @@ +test_name 'C3428 - clone (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb b/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb new file mode 100644 index 000000000..5bc06ec8f --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb @@ -0,0 +1,57 @@ +test_name 'C3429 - clone (ssh protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb b/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb new file mode 100644 index 000000000..1e3b4bb52 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb @@ -0,0 +1,47 @@ +test_name 'C3482 - clone over an existing repo' + +# Globals +repo_name = 'testrepo_already_exists' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + on(host, "mkdir #{tmpdir}/#{repo_name}") + on(host, "cd #{tmpdir}/#{repo_name} && git init") + on(host, "cd #{tmpdir}/#{repo_name} && touch a && git add a && git commit -m 'a'") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone over existing repo using puppet' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + @existing_sha = res.stdout + end + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify original repo was not replaced' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + fail_test('original repo was replaced without force') unless res.stdout.include? "#{@existing_sha}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb b/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb new file mode 100644 index 000000000..98053555e --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb @@ -0,0 +1,45 @@ +test_name 'C3509 - clone repo with excludes not in repo' +skip_test 'expectations not defined' + +# Globals +repo_name = 'testrepo_with_excludes_not_in_repo' +exclude1 = "`exec \"rm -rf /tmp\"`" + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone repo with excludes not in repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + excludes => [ '#{exclude1}' ], + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify excludes are known to git' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/info/exclude") do |res| + fail_test('exclude not found') unless res.stdout.include? "#{exclude1}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb new file mode 100644 index 000000000..7ac4c4a00 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3495 - checkout with compression 0' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 0 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 0, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb new file mode 100644 index 000000000..8b7455d84 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3496 - checkout with compression 1' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 1 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb new file mode 100644 index 000000000..81d32c3f5 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3497 - checkout with compression 2' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 2 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 2, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb new file mode 100644 index 000000000..12b60a37b --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3498 - checkout with compression 3' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 3 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 3, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb new file mode 100644 index 000000000..66d2d5eb9 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3499 - checkout with compression 4' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 4 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 4, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb new file mode 100644 index 000000000..b60a9f7f6 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3500 - checkout with compression 5' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 5 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 5, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb new file mode 100644 index 000000000..2f6b075a9 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3501 - checkout with compression 6' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 6 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 6, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb new file mode 100644 index 000000000..e74cca924 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3503 - checkout with compression 7' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 7 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 7, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb new file mode 100644 index 000000000..59aaf2193 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3505 - checkout with compression alpha' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression alpha with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => abcde, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb new file mode 100644 index 000000000..b989e586d --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3504 - checkout with compression 10-5' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 10-5 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 10-5, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb new file mode 100644 index 000000000..e1373afbb --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3506 - checkout with compression exec' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression exec with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => "exec 'rm -rf /tmp'", + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb b/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb new file mode 100644 index 000000000..1253db1d3 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3502 - checkout with compression -1' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression -1 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => -1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb b/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb new file mode 100644 index 000000000..ccb8a7072 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb @@ -0,0 +1,40 @@ +test_name 'C3472 - create bare repo that already exists' + +# Globals +repo_name = 'testrepo_bare_repo_already_exists.git' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create bare repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + on(host, "mkdir #{tmpdir}/#{repo_name}") + on(host, "cd #{tmpdir}/#{repo_name} && git --bare init") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'create bare repo that already exists using puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => bare, + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify repo does not contain .git directory' do + on(host, "ls -al #{tmpdir}/#{repo_name}") do |res| + fail_test "found .git for #{repo_name}" if res.stdout.include? ".git" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb b/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb new file mode 100644 index 000000000..8fb85435e --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb @@ -0,0 +1,42 @@ +test_name 'C3470 - create repo that already exists' + +# Globals +repo_name = 'testrepo_already_exists' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + on(host, "cd #{tmpdir} && git clone file://#{tmpdir}/testrepo.git #{repo_name}") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'create repo that already exists using puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify repo is on master branch' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + assert_match(/ref: refs\/heads\/master/, stdout, "Git checkout not on master on #{host}") + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb b/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb new file mode 100644 index 000000000..5b789df14 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb @@ -0,0 +1,38 @@ +test_name 'C3473 - create bare repo specifying revision' + +# Globals +repo_name = 'testrepo_bare.git' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'create bare repo specifying revision using puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => bare, + revision => master, + provider => git, + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify repo does not contain .git directory' do + on(host, "ls -al #{tmpdir}") do |res| + fail_test "found repo for #{repo_name}" if res.stdout.include? repo_name + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb new file mode 100644 index 000000000..beea7b80b --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb @@ -0,0 +1,53 @@ +test_name 'C3487 - checkout as a group (file protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb new file mode 100644 index 000000000..319a8e749 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb @@ -0,0 +1,53 @@ +test_name 'C3486 - checkout as a group (file path)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb new file mode 100644 index 000000000..e5b9cf29e --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb @@ -0,0 +1,58 @@ +test_name 'C3485 - checkout as a group (git protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb new file mode 100644 index 000000000..bf86f2eb5 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb @@ -0,0 +1,66 @@ +test_name 'C3490 - checkout as a group (http protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb new file mode 100644 index 000000000..c4c645f91 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb @@ -0,0 +1,73 @@ +test_name 'C3491 - checkout as a group (https protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb new file mode 100644 index 000000000..c65acc431 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb @@ -0,0 +1,64 @@ +test_name 'C3488 - checkout as a group (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb new file mode 100644 index 000000000..cccad19cd --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb @@ -0,0 +1,64 @@ +test_name 'C3489 - checkout as a group (ssh protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb b/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb new file mode 100644 index 000000000..081642d91 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb @@ -0,0 +1,51 @@ +test_name 'C3484 - checkout as a group that is not on system' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - delete group' do + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step "verify git checkout is NOT owned by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') if res.stdout.include? ":#{group}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb new file mode 100644 index 000000000..85f1fcc06 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb @@ -0,0 +1,46 @@ +test_name 'C3614 - checkout a revision that does not exist' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout revision that does not exist with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '11111111111111111', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify that master revision is checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb new file mode 100644 index 000000000..b17dc73d5 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb @@ -0,0 +1,53 @@ +test_name 'C3452 - checkout a revision (file protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify repo is checked out to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb new file mode 100644 index 000000000..c80eb81b2 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb @@ -0,0 +1,53 @@ +test_name 'C3451 - checkout a revision (file path)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify repo is checked out to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb new file mode 100644 index 000000000..69a7fe22f --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb @@ -0,0 +1,58 @@ +test_name 'C3450 - checkout a revision (git protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb new file mode 100644 index 000000000..7cac163d1 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb @@ -0,0 +1,66 @@ +test_name 'C3455 - checkout a revision (http protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb new file mode 100644 index 000000000..1c705a5ea --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb @@ -0,0 +1,74 @@ +test_name 'C3456 - checkout a revision (https protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get revision sha from repo' do + on(host, "git clone https://github.com/johnduarte/testrepo.git #{tmpdir}/foo") + on(host, "git --git-dir=#{tmpdir}/foo/.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb new file mode 100644 index 000000000..b5dbd244b --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb @@ -0,0 +1,64 @@ +test_name 'C3453 - checkout a revision (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb new file mode 100644 index 000000000..222653e44 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb @@ -0,0 +1,64 @@ +test_name 'C3454 - checkout a revision (ssh protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb new file mode 100644 index 000000000..f01a488e0 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb @@ -0,0 +1,43 @@ +test_name 'C3608 - shallow clone repo depth hostile input' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (bad input ignored, full clone checkedout)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => "exec 'rm -rf /tmp'", + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') if res.stdout.include? "shallow" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb new file mode 100644 index 000000000..47fb338be --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb @@ -0,0 +1,44 @@ +test_name 'C3475 - shallow clone repo minimal depth = 1 (file path protocol)' +skip_test 'Not currently supported. See FM-1285' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'git does not support shallow clone via file path: verify checkout is NOT created' do + on(host, "ls #{tmpdir}") do |res| + fail_test('checkout found') if res.stdout.include? "#{repo_name}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb new file mode 100644 index 000000000..723a0b622 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb @@ -0,0 +1,55 @@ +test_name 'C3479 - shallow clone repo minimal depth = 1 (http protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'ps ax | grep "#{ruby} /tmp/http_daemon.rb" | grep -v grep | awk \'{print "kill -9 " $1}\' | sh ; sleep 1') + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'git does not support shallow clone via HTTP: verify checkout is NOT created' do + on(host, "ls #{tmpdir}") do |res| + fail_test('checkout found') if res.stdout.include? "#{repo_name}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb new file mode 100644 index 000000000..869620d21 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb @@ -0,0 +1,43 @@ +test_name 'C3607 - shallow clone repo depth = -1' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (bad input ignored, full clone checkedout)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => -1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') if res.stdout.include? "shallow" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb new file mode 100644 index 000000000..5da9fd7e5 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb @@ -0,0 +1,45 @@ +test_name 'C3606 - shallow clone repo depth overflow 64bit integer' + +# Globals +repo_name = 'testrepo_shallow_clone' + +pending_test("The overflow can't be handled on some git versions") + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (bad input ignored, full clone checkedout)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => 18446744073709551616, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') if res.stdout.include? "shallow" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb new file mode 100644 index 000000000..9e2abe283 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb @@ -0,0 +1,47 @@ +test_name 'C3476 - shallow clone repo minimal depth = 1 (file protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb new file mode 100644 index 000000000..49683d24d --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb @@ -0,0 +1,52 @@ +test_name 'C3474 - shallow clone repo minimal depth = 1 (git protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb new file mode 100644 index 000000000..239272872 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb @@ -0,0 +1,68 @@ +test_name 'C3480 - shallow clone repo minimal depth = 1 (https protocol)' +skip_test 'Not currently supported. See FM-1286' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'ps ax | grep "#{ruby} /tmp/https_daemon.rb" | grep -v grep | awk \'{print "kill -9 " $1}\' | sh ; sleep 1') + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb new file mode 100644 index 000000000..1d5b35a16 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb @@ -0,0 +1,58 @@ +test_name 'C3478 - shallow clone repo minimal depth = 1 (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'shallow clone repo with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb new file mode 100644 index 000000000..0f00b30e8 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb @@ -0,0 +1,58 @@ +test_name 'C3477 - shallow clone repo minimal depth = 1 (ssh protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb new file mode 100644 index 000000000..34c624f7d --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb @@ -0,0 +1,43 @@ +test_name 'C3404 - shallow clone repo depth = 0 non shallow' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (zero depth means not shallow)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => 0, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow found') if res.stdout.include? "shallow" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb new file mode 100644 index 000000000..1849f0295 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb @@ -0,0 +1,47 @@ +test_name 'C3612 - checkout a tag that does not exist' + +# Globals +repo_name = 'testrepo_tag_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout tag that does not exist with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + tag => '11111111111111111', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify that master tag is checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb new file mode 100644 index 000000000..9c7448552 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb @@ -0,0 +1,48 @@ +test_name 'C3445 - checkout a tag (file protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb new file mode 100644 index 000000000..01f319cb0 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb @@ -0,0 +1,48 @@ +test_name 'C3444 - checkout a tag (file path)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb new file mode 100644 index 000000000..42e689c86 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb @@ -0,0 +1,59 @@ +test_name 'C3443 - checkout a tag (git protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb new file mode 100644 index 000000000..3ea363c40 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb @@ -0,0 +1,67 @@ +test_name 'C3448 - checkout a tag (http protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb new file mode 100644 index 000000000..d508c4363 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb @@ -0,0 +1,74 @@ +test_name 'C3449 - checkout a tag (https protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb new file mode 100644 index 000000000..cb96b4e2e --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb @@ -0,0 +1,65 @@ +test_name 'C3446 - checkout a tag (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb new file mode 100644 index 000000000..bc416e8eb --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb @@ -0,0 +1,65 @@ +test_name 'C3447 - checkout a tag (ssh protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb b/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb new file mode 100644 index 000000000..245e17511 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb @@ -0,0 +1,51 @@ +test_name 'C3483 - checkout as a user that is not on system' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - delete user' do + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step "verify git checkout is NOT owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') if res.stdout.include? "#{user}:" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb new file mode 100644 index 000000000..ccd9ad445 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb @@ -0,0 +1,53 @@ +test_name 'C3459 - checkout as a user (file protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb new file mode 100644 index 000000000..602769de3 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb @@ -0,0 +1,53 @@ +test_name 'C3458 - checkout as a user (file path)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb new file mode 100644 index 000000000..af2ffb714 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb @@ -0,0 +1,58 @@ +test_name 'C3457 - checkout as a user (git protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb new file mode 100644 index 000000000..e8713e5bf --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb @@ -0,0 +1,66 @@ +test_name 'C3462 - checkout as a user (http protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb new file mode 100644 index 000000000..4e633d78c --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb @@ -0,0 +1,73 @@ +test_name 'C3463 - checkout as a user (https protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb new file mode 100644 index 000000000..98efb4621 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb @@ -0,0 +1,64 @@ +test_name 'C3460 - checkout as a user (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb new file mode 100644 index 000000000..cfd521ec0 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb @@ -0,0 +1,64 @@ +test_name 'C3461 - checkout as a user (ssh protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/vcsrepo/spec/acceptance/beaker_helper.rb b/vcsrepo/spec/acceptance/beaker_helper.rb new file mode 100644 index 000000000..4d2320471 --- /dev/null +++ b/vcsrepo/spec/acceptance/beaker_helper.rb @@ -0,0 +1,51 @@ +test_name "Installing Puppet and vcsrepo module" do + step 'install puppet' do + if @options[:provision] + # This will fail if puppet is already installed, ie --no-provision + if hosts.first.is_pe? + install_pe + else + install_puppet + on hosts, "mkdir -p #{hosts.first['distmoduledir']}" + end + end + end + + step 'Ensure we can install our module' do + hosts.each do |host| + # We ask the host to interpolate it's distmoduledir because we don't + # actually know it on Windows until we've let it redirect us (depending + # on whether we're running as a 32/64 bit process on 32/64 bit Windows + moduledir = on(host, "echo #{host['distmoduledir']}").stdout.chomp + on host, "mkdir -p #{moduledir}" + end + end + + step 'install module' do + hosts.each do |host| + proj_root = File.expand_path(File.join(File.dirname(__FILE__),'..','..')) + + # This require beaker 1.15 + copy_module_to(host, :source => proj_root, :module_name => 'vcsrepo') + + case fact_on(host, 'osfamily') + when 'RedHat' + install_package(host, 'git') + when 'Debian' + install_package(host, 'git-core') + else + if !check_for_package(host, 'git') + puts "Git package is required for this module" + exit + end + end + + gitconfig = <<-EOS +[user] + email = root@localhost + name = root +EOS + create_remote_file(host, "/root/.gitconfig", gitconfig) + end + end +end diff --git a/vcsrepo/spec/acceptance/clone_repo_spec.rb b/vcsrepo/spec/acceptance/clone_repo_spec.rb new file mode 100644 index 000000000..2cca06129 --- /dev/null +++ b/vcsrepo/spec/acceptance/clone_repo_spec.rb @@ -0,0 +1,510 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + scp_to(default, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + shell("cd #{tmpdir} && ./create_git_repo.sh") + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo.git") + end + + context 'get the current master HEAD' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/testrepo/.git/HEAD") do + it { is_expected.to contain 'ref: refs/heads/master' } + end + end + + context 'using a commit SHA' do + let (:sha) do + shell("git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1").stdout.chomp + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo_sha") + end + + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_sha": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => "#{sha}", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_sha/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/testrepo_sha/.git/HEAD") do + it { is_expected.to contain sha } + end + end + + context 'using a tag' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_tag": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => '0.0.2', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_tag/.git") do + it { is_expected.to be_directory } + end + + it 'should have the tag as the HEAD' do + shell("git --git-dir=#{tmpdir}/testrepo_tag/.git name-rev HEAD | grep '0.0.2'") + end + end + + context 'using a branch name' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_branch": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => 'a_branch', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_branch/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/testrepo_branch/.git/HEAD") do + it { is_expected.to contain 'ref: refs/heads/a_branch' } + end + end + + context 'ensure latest with branch specified' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_latest": + ensure => latest, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => 'a_branch', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'verifies the HEAD commit SHA on remote and local match' do + remote_commit = shell("git ls-remote file://#{tmpdir}/testrepo_latest HEAD | head -1").stdout + local_commit = shell("git --git-dir=#{tmpdir}/testrepo_latest/.git rev-parse HEAD").stdout.chomp + expect(remote_commit).to include(local_commit) + end + end + + context 'ensure latest with branch unspecified' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_latest": + ensure => latest, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'verifies the HEAD commit SHA on remote and local match' do + remote_commit = shell("git ls-remote file://#{tmpdir}/testrepo_latest HEAD | head -1").stdout + local_commit = shell("git --git-dir=#{tmpdir}/testrepo_latest/.git rev-parse HEAD").stdout.chomp + expect(remote_commit).to include(local_commit) + end + end + + context 'with shallow clone' do + it 'does a shallow clone' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_shallow": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + depth => '1', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_shallow/.git/shallow") do + it { is_expected.to be_file } + end + end + + context 'path is not empty and not a repository' do + before(:all) do + shell("mkdir #{tmpdir}/not_a_repo", :acceptable_exit_codes => [0,1]) + shell("touch #{tmpdir}/not_a_repo/file1.txt", :acceptable_exit_codes => [0,1]) + end + + it 'should raise an exception' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/not_a_repo": + ensure => present, + provider => git + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_failures => true) + end + end + + context 'with an owner' do + pp = <<-EOS + user { 'vagrant': + ensure => present, + } + EOS + + apply_manifest(pp, :catch_failures => true) + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_owner": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + owner => 'vagrant', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_owner") do + it { is_expected.to be_directory } + it { is_expected.to be_owned_by 'vagrant' } + end + end + + context 'with a group' do + pp = <<-EOS + group { 'vagrant': + ensure => present, + } + EOS + + apply_manifest(pp, :catch_failures => true) + + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "/#{tmpdir}/testrepo_group": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + group => 'vagrant', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_group") do + it { is_expected.to be_directory } + it { is_expected.to be_grouped_into 'vagrant' } + end + end + + context 'with excludes' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_excludes": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + excludes => ['exclude1.txt', 'exclude2.txt'], + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_excludes/.git/info/exclude") do + describe '#content' do + subject { super().content } + it { is_expected.to match /exclude1.txt/ } + end + + describe '#content' do + subject { super().content } + it { is_expected.to match /exclude2.txt/ } + end + end + end + + context 'with force' do + before(:all) do + shell("mkdir -p #{tmpdir}/testrepo_force/folder") + shell("touch #{tmpdir}/testrepo_force/temp.txt") + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_force": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + force => true, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_force/folder") do + it { is_expected.not_to be_directory } + end + + describe file("#{tmpdir}/testrepo_force/temp.txt") do + it { is_expected.not_to be_file } + end + + describe file("#{tmpdir}/testrepo_force/.git") do + it { is_expected.to be_directory } + end + + context 'and noop' do + before(:all) do + shell("mkdir #{tmpdir}/testrepo_already_exists") + shell("cd #{tmpdir}/testrepo_already_exists && git init") + shell("cd #{tmpdir}/testrepo_already_exists && touch a && git add a && git commit -m 'a'") + end + after(:all) do + shell("rm -rf #{tmpdir}/testrepo_already_exists") + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_already_exists": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + force => true, + noop => true, + } + EOS + + apply_manifest(pp, :catch_changes => true) + end + end + end + + context 'as a user' do + before(:all) do + shell("chmod 707 #{tmpdir}") + pp = <<-EOS + group { 'testuser': + ensure => present, + } + user { 'testuser': + ensure => present, + groups => 'testuser', + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + user => 'testuser', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_user") do + it { is_expected.to be_directory } + it { is_expected.to be_owned_by 'testuser' } + end + + describe file("#{tmpdir}/testrepo_user") do + it { is_expected.to be_directory } + it { is_expected.to be_grouped_into 'testuser' } + end + end + + context 'non-origin remote name' do + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_remote": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + remote => 'testorigin', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'remote name is "testorigin"' do + shell("git --git-dir=#{tmpdir}/testrepo_remote/.git remote | grep 'testorigin'") + end + + after(:all) do + pp = 'user { "testuser": ensure => absent }' + apply_manifest(pp, :catch_failures => true) + end + end + + context 'as a user with ssh' do + before(:all) do + # create user + pp = <<-EOS + group { 'testuser-ssh': + ensure => present, + } + user { 'testuser-ssh': + ensure => present, + groups => 'testuser-ssh', + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + + # create ssh keys + shell('mkdir -p /home/testuser-ssh/.ssh') + shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys') + shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config') + shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh') + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user_ssh": + ensure => present, + provider => git, + source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git", + user => 'testuser-ssh', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + after(:all) do + pp = <<-EOS + user { 'testuser-ssh': + ensure => absent, + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + end + + context 'using an identity file' do + before(:all) do + # create user + pp = <<-EOS + user { 'testuser-ssh': + ensure => present, + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + + # create ssh keys + shell('mkdir -p /home/testuser-ssh/.ssh') + shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys') + shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config') + shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh') + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user_ssh_id": + ensure => present, + provider => git, + source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git", + identity => '/home/testuser-ssh/.ssh/id_rsa', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + end +end diff --git a/vcsrepo/spec/acceptance/create_repo_spec.rb b/vcsrepo/spec/acceptance/create_repo_spec.rb new file mode 100644 index 000000000..db0cd2954 --- /dev/null +++ b/vcsrepo/spec/acceptance/create_repo_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'create a repo' do + context 'without a source' do + it 'creates a blank repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_blank_repo": + ensure => present, + provider => git, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_blank_repo/") do + it 'should have zero files' do + shell("ls -1 #{tmpdir}/testrepo_blank_repo | wc -l") do |r| + expect(r.stdout).to match(/^0\n$/) + end + end + end + + describe file("#{tmpdir}/testrepo_blank_repo/.git") do + it { is_expected.to be_directory } + end + end + + context 'bare repo' do + it 'creates a bare repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_bare_repo": + ensure => bare, + provider => git, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_bare_repo/config") do + it { is_expected.to contain 'bare = true' } + end + + describe file("#{tmpdir}/testrepo_bare_repo/.git") do + it { is_expected.not_to be_directory } + end + end + + context 'bare repo with a revision' do + it 'does not create a bare repo when a revision is defined' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_bare_repo_rev": + ensure => bare, + provider => git, + revision => 'master', + } + EOS + + apply_manifest(pp, :expect_failures => true) + end + + describe file("#{tmpdir}/testrepo_bare_repo_rev") do + it { is_expected.not_to be_directory } + end + end +end diff --git a/vcsrepo/spec/acceptance/files/create_git_repo.sh b/vcsrepo/spec/acceptance/files/create_git_repo.sh new file mode 100755 index 000000000..b5e930ca5 --- /dev/null +++ b/vcsrepo/spec/acceptance/files/create_git_repo.sh @@ -0,0 +1,39 @@ +#!/bin/bash +mkdir testrepo +cd testrepo + +touch file1.txt file2.txt file3.txt +git init +echo 'change 1' > file1.txt +git add file1.txt +git commit -m 'add file1' +git tag 0.0.1 +echo 'change 2' > file2.txt +git add file2.txt +git commit -m 'add file2' +git tag 0.0.2 +echo 'change 3' > file3.txt +git add file3.txt +git commit -m 'add file3' +git tag 0.0.3 + +git checkout -b a_branch +echo 'change 4' > file4.txt +git add file4.txt +git commit -m 'add file4' +echo 'change 5' > file5.txt +git add file5.txt +git commit -m 'add file5' +echo 'change 6' > file6.txt +git add file6.txt +git commit -m 'add file6' + +git checkout master +cd .. + +git --git-dir=testrepo/.git config core.bare true +cp -r testrepo/.git testrepo.git +rm -rf testrepo +cd testrepo.git +touch git-daemon-export-ok +git update-server-info diff --git a/vcsrepo/spec/acceptance/files/server.crt b/vcsrepo/spec/acceptance/files/server.crt new file mode 100644 index 000000000..ef1de5a92 --- /dev/null +++ b/vcsrepo/spec/acceptance/files/server.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICATCCAWoCCQCS3fQotV10LzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMB4XDTE0MDQyMzIyMzEyM1oXDTE1MDQyMzIyMzEyM1owRTELMAkG +A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 +IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyRTv +uX6328aQ5Auc8PI+xNaCiE0UZNYcs+xq3AEkR/Tnz0HGXdx3+PnFG7MIRSS65hXA +VGenZk3wP4vNIe9gu+G9jtOFTJOgoOBUnJ/Hcs79Zgcmz3cAWQpqww+CZpyngUDS +msZ5HoEbNS+qaIron3IrYCgPsy1BHFs5ze7JrtcCAwEAATANBgkqhkiG9w0BAQUF +AAOBgQA2uLvdc1cf+nt7d8Lmu0SdaoIsCzh6DjVscCpFJKXdDjGT2Ys40iKbLRnY +Tt98wa6uRzEhSKfx+zVi8n3PSkQHlER7jzKFXMVx8NEt2/O/APKXVizmLFjk5WcT +FvGmmbkqX+Nj9TUTuSRZEmF776r5k8U5ABu/VarxvAzyoXAhqA== +-----END CERTIFICATE----- diff --git a/vcsrepo/spec/acceptance/files/server.key b/vcsrepo/spec/acceptance/files/server.key new file mode 100644 index 000000000..b594f13ef --- /dev/null +++ b/vcsrepo/spec/acceptance/files/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDJFO+5frfbxpDkC5zw8j7E1oKITRRk1hyz7GrcASRH9OfPQcZd +3Hf4+cUbswhFJLrmFcBUZ6dmTfA/i80h72C74b2O04VMk6Cg4FScn8dyzv1mBybP +dwBZCmrDD4JmnKeBQNKaxnkegRs1L6poiuifcitgKA+zLUEcWznN7smu1wIDAQAB +AoGAQPnD8OOyk5DZVuctwmn0wHQ0X8jQczkAs18MtKSlzZ6knUM6zy+jkM9c0vOK +E5Wn0xtqN5v66sL6g/4vvex1DA5Q6YsXvZ48VpVliZXXK/1pdTv0qwMyHdlBhmgJ +MhnZbyNy61QHdOTsWDR1YrELpDyFMJ9cZZD0NOnsuhd2DbECQQDq7W/zlJBZPWNR +ab2dP+HLpm/PiEBT13SuEEskh3GEEfZlwz/cGu0Z8DHA4E3Z60KFjwgnc92GNFMg +m0t3hHtpAkEA2x5PsDxBk9sWwdIvu57vjQLdotvAfyb+W9puIaZS1JRSVLTsUVEj +Y0KxgsPHtcjrVoN//zGymn4ePxWOzlrQPwJBAN5thEuZY7o6dyiD9zVFYKGSqdZS +aKV5H04Wuy6Q1pd28lWTMYlSLR8b3d+B//PN3SPbMps4BoukSvhaUG+OjdECQFzF +KZIBAPa7pJftCH6UHPIDy5ifF5H+DWUQRt6CT8FnBrCMZR1MkAH/g65Me6pwZYsc +Y73E6cxVJzMoSmz9r/sCQQCOhPflFCxZ23ocsuRBo9O/mMUDaLoHZXWuJ2DqAUN2 +mS6UUR/lpyc7Cmy0VOyhS8783D7MUfji5ddfVxb5tWgm +-----END RSA PRIVATE KEY----- diff --git a/vcsrepo/spec/acceptance/modules_1596_spec.rb b/vcsrepo/spec/acceptance/modules_1596_spec.rb new file mode 100644 index 000000000..fa36285a1 --- /dev/null +++ b/vcsrepo/spec/acceptance/modules_1596_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + context 'force with a remote' do + it 'clones from remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => 'https://github.com/puppetlabs/puppetlabs-vcsrepo', + force => true, + } + EOS + + # Run it twice to test for idempotency + apply_manifest(pp, :catch_failures => true) + # need to create a file to make sure we aren't destroying the repo + # because fun fact, if you call destroy/create in 'retrieve' puppet won't + # register that any changes happen, because that method isn't supposed to + # be making any changes. + shell("touch #{tmpdir}/vcsrepo/foo") + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/vcsrepo/foo") do + it { is_expected.to be_file } + end + end + + context 'force over an existing repo' do + it 'clones from remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => 'https://github.com/puppetlabs/puppetlabs-vcsrepo', + force => true, + } + EOS + + pp2 = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => 'https://github.com/puppetlabs/puppetlabs-stdlib', + force => true, + } + EOS + + + apply_manifest(pp, :catch_failures => true) + # create a file to make sure we're destroying the repo + shell("touch #{tmpdir}/vcsrepo/foo") + apply_manifest(pp2, :catch_failures => true) + end + + describe file("#{tmpdir}/vcsrepo/foo") do + it { is_expected.to_not be_file } + end + end +end diff --git a/vcsrepo/spec/acceptance/modules_660_spec.rb b/vcsrepo/spec/acceptance/modules_660_spec.rb new file mode 100644 index 000000000..c45aa28b5 --- /dev/null +++ b/vcsrepo/spec/acceptance/modules_660_spec.rb @@ -0,0 +1,89 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'MODULES-660' do + before(:all) do + # Create testrepo.git + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + scp_to(default, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + shell("cd #{tmpdir} && ./create_git_repo.sh") + + # Configure testrepo.git as upstream of testrepo + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => present, + provider => git, + revision => 'a_branch', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo.git") + end + + shared_examples 'switch to branch/tag/sha' do + it 'pulls the new branch commits' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => latest, + provider => git, + revision => 'a_branch', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_changes => true) + apply_manifest(pp, :catch_changes => true) + end + it 'checks out the tag' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => latest, + provider => git, + revision => '0.0.3', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_changes => true) + apply_manifest(pp, :catch_changes => true) + end + it 'checks out the sha' do + sha = shell("cd #{tmpdir}/testrepo && git rev-parse origin/master").stdout.chomp + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => latest, + provider => git, + revision => '#{sha}', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_changes => true) + apply_manifest(pp, :catch_changes => true) + end + end + + context 'on branch' do + before :each do + shell("cd #{tmpdir}/testrepo && git checkout a_branch") + shell("cd #{tmpdir}/testrepo && git reset --hard 0.0.2") + end + it_behaves_like 'switch to branch/tag/sha' + end + context 'on tag' do + before :each do + shell("cd #{tmpdir}/testrepo && git checkout 0.0.1") + end + it_behaves_like 'switch to branch/tag/sha' + end + context 'on detached head' do + before :each do + shell("cd #{tmpdir}/testrepo && git checkout 0.0.2") + shell("cd #{tmpdir}/testrepo && git checkout HEAD~1") + end + it_behaves_like 'switch to branch/tag/sha' + end +end diff --git a/vcsrepo/spec/acceptance/modules_753_spec.rb b/vcsrepo/spec/acceptance/modules_753_spec.rb new file mode 100644 index 000000000..e4e332bfc --- /dev/null +++ b/vcsrepo/spec/acceptance/modules_753_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + context 'clone with single remote' do + it 'clones from default remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", + } + EOS + + apply_manifest(pp, :catch_failures => true) + + end + + it "git config output should contain the remote" do + shell("/usr/bin/git config -l -f #{tmpdir}/vcsrepo/.git/config") do |r| + expect(r.stdout).to match(/remote.origin.url=https:\/\/github.com\/puppetlabs\/puppetlabs-vcsrepo.git/) + end + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + end + + context 'clone with multiple remotes' do + it 'clones from default remote and adds 2 remotes to config file' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => {"origin" => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", "test1" => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git"}, + } + EOS + + apply_manifest(pp, :catch_failures => true) + + end + + it "git config output should contain the remotes" do + shell("/usr/bin/git config -l -f #{tmpdir}/vcsrepo/.git/config") do |r| + expect(r.stdout).to match(/remote.origin.url=https:\/\/github.com\/puppetlabs\/puppetlabs-vcsrepo.git/) + expect(r.stdout).to match(/remote.test1.url=https:\/\/github.com\/puppetlabs\/puppetlabs-vcsrepo.git/) + end + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + end + +end diff --git a/vcsrepo/spec/acceptance/nodesets/centos-59-x64.yml b/vcsrepo/spec/acceptance/nodesets/centos-59-x64.yml new file mode 100644 index 000000000..2ad90b86a --- /dev/null +++ b/vcsrepo/spec/acceptance/nodesets/centos-59-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-59-x64: + roles: + - master + platform: el-5-x86_64 + box : centos-59-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-59-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: git diff --git a/vcsrepo/spec/acceptance/nodesets/centos-64-x64-pe.yml b/vcsrepo/spec/acceptance/nodesets/centos-64-x64-pe.yml new file mode 100644 index 000000000..7d9242f1b --- /dev/null +++ b/vcsrepo/spec/acceptance/nodesets/centos-64-x64-pe.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-64-x64: + roles: + - master + - database + - dashboard + platform: el-6-x86_64 + box : centos-64-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: pe diff --git a/vcsrepo/spec/acceptance/nodesets/centos-64-x64.yml b/vcsrepo/spec/acceptance/nodesets/centos-64-x64.yml new file mode 100644 index 000000000..05540ed8c --- /dev/null +++ b/vcsrepo/spec/acceptance/nodesets/centos-64-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-64-x64: + roles: + - master + platform: el-6-x86_64 + box : centos-64-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/vcsrepo/spec/acceptance/nodesets/centos-65-x64.yml b/vcsrepo/spec/acceptance/nodesets/centos-65-x64.yml new file mode 100644 index 000000000..4e2cb809e --- /dev/null +++ b/vcsrepo/spec/acceptance/nodesets/centos-65-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-65-x64: + roles: + - master + platform: el-6-x86_64 + box : centos-65-x64-vbox436-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/vcsrepo/spec/acceptance/nodesets/debian-607-x64.yml b/vcsrepo/spec/acceptance/nodesets/debian-607-x64.yml new file mode 100644 index 000000000..43df6a57f --- /dev/null +++ b/vcsrepo/spec/acceptance/nodesets/debian-607-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + debian-607-x64: + roles: + - master + platform: debian-6-amd64 + box : debian-607-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-607-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/vcsrepo/spec/acceptance/nodesets/debian-73-x64.yml b/vcsrepo/spec/acceptance/nodesets/debian-73-x64.yml new file mode 100644 index 000000000..5b87870a9 --- /dev/null +++ b/vcsrepo/spec/acceptance/nodesets/debian-73-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + debian-73-x64: + roles: + - master + platform: debian-7-amd64 + box : debian-73-x64-virtualbox-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-73-x64-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/vcsrepo/spec/acceptance/nodesets/default.yml b/vcsrepo/spec/acceptance/nodesets/default.yml new file mode 100644 index 000000000..05540ed8c --- /dev/null +++ b/vcsrepo/spec/acceptance/nodesets/default.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-64-x64: + roles: + - master + platform: el-6-x86_64 + box : centos-64-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/vcsrepo/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml b/vcsrepo/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml new file mode 100644 index 000000000..5ca1514e4 --- /dev/null +++ b/vcsrepo/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + ubuntu-server-10044-x64: + roles: + - master + platform: ubuntu-10.04-amd64 + box : ubuntu-server-10044-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-10044-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/vcsrepo/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml b/vcsrepo/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml new file mode 100644 index 000000000..d065b304f --- /dev/null +++ b/vcsrepo/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + ubuntu-server-12042-x64: + roles: + - master + platform: ubuntu-12.04-amd64 + box : ubuntu-server-12042-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/vcsrepo/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/vcsrepo/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml new file mode 100644 index 000000000..cba1cd04c --- /dev/null +++ b/vcsrepo/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml @@ -0,0 +1,11 @@ +HOSTS: + ubuntu-server-1404-x64: + roles: + - master + platform: ubuntu-14.04-amd64 + box : puppetlabs/ubuntu-14.04-64-nocm + box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm + hypervisor : vagrant +CONFIG: + log_level : debug + type: git diff --git a/vcsrepo/spec/acceptance/remove_repo_spec.rb b/vcsrepo/spec/acceptance/remove_repo_spec.rb new file mode 100644 index 000000000..d5646b348 --- /dev/null +++ b/vcsrepo/spec/acceptance/remove_repo_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'remove a repo' do + it 'creates a blank repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_deleted": + ensure => present, + provider => git, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + it 'removes a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_deleted": + ensure => absent, + provider => git, + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + + describe file("#{tmpdir}/testrepo_deleted") do + it { is_expected.not_to be_directory } + end +end diff --git a/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb b/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb new file mode 100644 index 000000000..f6bd86e94 --- /dev/null +++ b/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb @@ -0,0 +1,31 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'does not remove a repo if noop' do + it 'creates a blank repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_noop_deleted": + ensure => present, + provider => git, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + it 'does not remove a repo if noop' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_noop_deleted": + ensure => absent, + provider => git, + force => true, + } + EOS + + apply_manifest(pp, :catch_failures => true, :noop => true, :verbose => false) + end + + describe file("#{tmpdir}/testrepo_noop_deleted") do + it { is_expected.to be_directory } + end +end diff --git a/vcsrepo/spec/fixtures/git_branch_feature_bar.txt b/vcsrepo/spec/fixtures/git_branch_feature_bar.txt new file mode 100644 index 000000000..72d5e2009 --- /dev/null +++ b/vcsrepo/spec/fixtures/git_branch_feature_bar.txt @@ -0,0 +1,14 @@ + feature/foo +* feature/bar + feature/baz + feature/quux + only/local + master + refactor/foo + origin/HEAD + origin/feature/foo + origin/feature/bar + origin/feature/baz + origin/feature/quux + origin/only/remote + origin/master diff --git a/vcsrepo/spec/fixtures/git_branch_none.txt b/vcsrepo/spec/fixtures/git_branch_none.txt new file mode 100644 index 000000000..7207c3792 --- /dev/null +++ b/vcsrepo/spec/fixtures/git_branch_none.txt @@ -0,0 +1,15 @@ + feature/foo + feature/bar + feature/baz + feature/quux + only/local + master +* (no branch) + refactor/foo + origin/HEAD + origin/feature/foo + origin/feature/bar + origin/feature/baz + origin/feature/quux + origin/only/remote + origin/master diff --git a/vcsrepo/spec/spec_helper.rb b/vcsrepo/spec/spec_helper.rb index 3bac65082..ccd305b7b 100644 --- a/vcsrepo/spec/spec_helper.rb +++ b/vcsrepo/spec/spec_helper.rb @@ -1,25 +1,16 @@ -require 'pathname' -dir = Pathname.new(__FILE__).parent -$LOAD_PATH.unshift(dir, dir + 'lib', dir + '../lib') +require 'puppetlabs_spec_helper/module_spec_helper' +require 'support/filesystem_helpers' +require 'support/fixture_helpers' -require 'test/unit' -require 'mocha' -require 'puppet' -gem 'rspec', '>= 1.2.9' -require 'spec/autorun' - -Dir[File.join(File.dirname(__FILE__), 'support', '*.rb')].each do |support_file| - require support_file -end - -Spec::Runner.configure do |config| - config.mock_with :mocha - config.include(FixtureHelpers) - config.include(FilesystemHelpers) +# SimpleCov does not run on Ruby 1.8.7 +unless RUBY_VERSION.to_f < 1.9 + require 'simplecov' + SimpleCov.start do + add_filter '/spec/' + end end -# We need this because the RAL uses 'should' as a method. This -# allows us the same behaviour but with a different method name. -class Object - alias :must :should +RSpec.configure do |c| + c.include FilesystemHelpers + c.include FixtureHelpers end diff --git a/vcsrepo/spec/spec_helper_acceptance.rb b/vcsrepo/spec/spec_helper_acceptance.rb new file mode 100644 index 000000000..9ef826ae7 --- /dev/null +++ b/vcsrepo/spec/spec_helper_acceptance.rb @@ -0,0 +1,64 @@ +require 'beaker-rspec' + +unless ENV['RS_PROVISION'] == 'no' or ENV['BEAKER_provision'] == 'no' + # This will install the latest available package on el and deb based + # systems fail on windows and osx, and install via gem on other *nixes + foss_opts = { :default_action => 'gem_install' } + + if default.is_pe?; then install_pe; else install_puppet( foss_opts ); end + + hosts.each do |host| + unless host.is_pe? + on hosts, "mkdir -p #{hosts.first['distmoduledir']}" + end + + # We ask the host to interpolate it's distmoduledir because we don't + # actually know it on Windows until we've let it redirect us (depending + # on whether we're running as a 32/64 bit process on 32/64 bit Windows + moduledir = on(host, "echo #{host['distmoduledir']}").stdout.chomp + on host, "mkdir -p #{moduledir}" + end +end + + +RSpec.configure do |c| + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Readable test descriptions + c.formatter = :documentation + + # Configure all nodes in nodeset + c.before :suite do + + # ensure test dependencies are available on all hosts + hosts.each do |host| + copy_module_to(host, :source => proj_root, :module_name => 'vcsrepo') + case fact_on(host, 'osfamily') + when 'RedHat' + if fact_on(host, 'operatingsystemmajrelease') == '5' + will_install_git = on(host, 'which git', :acceptable_exit_codes => [0,1]).exit_code == 1 + + if will_install_git + on host, puppet('module install stahnma-epel') + apply_manifest_on( host, 'include epel' ) + end + + end + + install_package(host, 'git') + + when 'Debian' + install_package(host, 'git-core') + + else + if !check_for_package(host, 'git') + puts "Git package is required for this module" + exit + end + end + on host, 'git config --global user.email "root@localhost"' + on host, 'git config --global user.name "root"' + end + end +end diff --git a/vcsrepo/spec/support/provider_example_group.rb b/vcsrepo/spec/support/provider_example_group.rb deleted file mode 100644 index 1431f7822..000000000 --- a/vcsrepo/spec/support/provider_example_group.rb +++ /dev/null @@ -1,80 +0,0 @@ -class ProviderExampleGroup < Spec::Example::ExampleGroup - - # Allow access to the current resource - attr_reader :resource - - # Build up the values for the resource in this scope - before :each do - resource_hash = example_group_hierarchy.inject({}) do |memo, klass| - memo.merge(klass.options[:resource] || {}) - end - full_hash = resource_hash.merge(:provider => described_class.name) - @resource = described_class.resource_type.new(full_hash) - end - - # Build the provider - subject { described_class.new(@resource) } - - # Allow access to it via +provider+ - alias :provider :subject - - # Generate a context for a provider operating on a resource with: - # - # call-seq: - # - # # A parameter/property set (when the value isn't important) - # resource_with :source do - # # ... - # end - # - # # A parameter/property set to a specific value - # resource_with :source => 'a-specific-value' do - # # ... - # end - # - # Note: Choose one or the other (mixing will create two separate contexts) - # - def self.resource_with(*params, &block) - params_with_values = params.last.is_a?(Hash) ? params.pop : {} - build_value_context(params_with_values, &block) - build_existence_context(*params, &block) - end - - def self.build_existence_context(*params, &block) #:nodoc: - unless params.empty? - text = params.join(', ') - placeholders = params.inject({}) { |memo, key| memo.merge(key => 'an-unimportant-value') } - context("and with a #{text}", {:resource => placeholders}, &block) - end - end - - def self.build_value_context(params = {}, &block) #:nodoc: - unless params.empty? - text = params.map { |k, v| "#{k} => #{v.inspect}" }.join(' and with ') - context("and with #{text}", {:resource => params}, &block) - end - end - - - # Generate a context for a provider operating on a resource without - # a given parameter/property. - # - # call-seq: - # - # resource_without :source do - # # ... - # end - # - def self.resource_without(field, &block) - context("and without a #{field}", &block) - end - -end - -Spec::Example::ExampleGroupFactory.register(:provider, ProviderExampleGroup) - -# Outside wrapper to lookup a provider and start the spec using ProviderExampleGroup -def describe_provider(type_name, provider_name, options = {}, &block) - provider_class = Puppet::Type.type(type_name).provider(provider_name) - describe(provider_class, options.merge(:type => :provider), &block) -end diff --git a/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb b/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb index c0231e990..b5e2f7316 100644 --- a/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb +++ b/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb @@ -1,24 +1,41 @@ require 'spec_helper' -describe_provider :vcsrepo, :bzr, :resource => {:path => '/tmp/vcsrepo'} do +describe Puppet::Type.type(:vcsrepo).provider(:bzr_provider) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :bzr, + :revision => '2634', + :source => 'lp:do', + :path => '/tmp/test', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('bzr').returns('/usr/bin/bzr') + end describe 'creating' do - resource_with :source do - resource_with :revision do - it "should execute 'bzr clone -r' with the revision" do - provider.expects(:bzr).with('branch', '-r', resource.value(:revision), resource.value(:source), resource.value(:path)) - provider.create - end + context 'with defaults' do + it "should execute 'bzr clone -r' with the revision" do + provider.expects(:bzr).with('branch', '-r', resource.value(:revision), resource.value(:source), resource.value(:path)) + provider.create end - resource_without :revision do - it "should just execute 'bzr clone' without a revision" do - provider.expects(:bzr).with('branch', resource.value(:source), resource.value(:path)) - provider.create - end + end + + context 'without revision' do + it "should just execute 'bzr clone' without a revision" do + resource.delete(:revision) + provider.expects(:bzr).with('branch', resource.value(:source), resource.value(:path)) + provider.create end end - resource_without :source do + + context 'without source' do it "should execute 'bzr init'" do + resource.delete(:source) provider.expects(:bzr).with('init', resource.value(:path)) provider.create end @@ -27,14 +44,13 @@ describe 'destroying' do it "it should remove the directory" do - expects_rm_rf provider.destroy end end describe "checking existence" do it "should check for the directory" do - expects_directory?(true, File.join(resource.value(:path), '.bzr')) + File.expects(:directory?).with(File.join(resource.value(:path), '.bzr')).returns(true) provider.exists? end end @@ -42,46 +58,49 @@ describe "checking the revision property" do before do expects_chdir - provider.expects(:bzr).with('version-info').returns(fixture(:bzr_version_info)) + provider.expects(:bzr).with('version-info').returns(File.read(fixtures('bzr_version_info.txt'))) @current_revid = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x' end - context "when given a non-revid as the resource revision", :resource => {:revision => '2634'} do + + context "when given a non-revid as the resource revision" do context "when its revid is not different than the current revid" do - before do - provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("#{resource.value(:revision)} menesis@pov.lt-20100309191856-4wmfqzc803fj300x\n") - end it "should return the ref" do - provider.revision.should == resource.value(:revision) + resource[:revision] = '2634' + provider.expects(:bzr).with('revision-info', '2634').returns("2634 menesis@pov.lt-20100309191856-4wmfqzc803fj300x\n") + expect(provider.revision).to eq(resource.value(:revision)) end end - context "when its revid is different than the current revid", :resource => {:revision => '2636'} do + context "when its revid is different than the current revid" do it "should return the current revid" do + resource[:revision] = '2636' provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("2635 foo\n") - provider.revision.should == @current_revid + expect(provider.revision).to eq(@current_revid) end end end + context "when given a revid as the resource revision" do - context "when it is the same as the current revid", :resource => {:revision => 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x'} do - before do - provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("1234 #{resource.value(:revision)}\n") - end + context "when it is the same as the current revid" do it "should return it" do - provider.revision.should == resource.value(:revision) + resource[:revision] = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x' + provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("1234 #{resource.value(:revision)}\n") + expect(provider.revision).to eq(resource.value(:revision)) end end - context "when it is not the same as the current revid", :resource => {:revision => 'menesis@pov.lt-20100309191856-4wmfqzc803fj300y'} do + context "when it is not the same as the current revid" do it "should return the current revid" do + resource[:revision] = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300y' provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("2636 foo\n") - provider.revision.should == @current_revid + expect(provider.revision).to eq(@current_revid) end end + end end describe "setting the revision property" do it "should use 'bzr update -r' with the revision" do - expects_chdir + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields provider.expects(:bzr).with('update', '-r', 'somerev') provider.revision = 'somerev' end diff --git a/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb b/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb index aad54ccdd..2e18149a1 100644 --- a/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb +++ b/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb @@ -1,28 +1,54 @@ require 'spec_helper' -describe_provider :vcsrepo, :cvs, :resource => {:path => '/tmp/vcsrepo'} do +describe Puppet::Type.type(:vcsrepo).provider(:cvs_provider) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :cvs, + :revision => '2634', + :source => 'lp:do', + :path => '/tmp/test', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('cvs').returns('/usr/bin/cvs') + end describe 'creating' do - context "with a source", :resource => {:source => ':ext:source@example.com:/foo/bar'} do - resource_with :revision do - it "should execute 'cvs checkout' and 'cvs update -r'" do - provider.expects(:cvs).with('-d', resource.value(:source), 'checkout', '-r', 'an-unimportant-value', '-d', 'vcsrepo', 'bar') - expects_chdir(File.dirname(resource.value(:path))) - #provider.expects(:cvs).with('update', '-r', resource.value(:revision), '.') - provider.create - end + context "with a source" do + it "should execute 'cvs checkout'" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource[:revision] = 'an-unimportant-value' + expects_chdir('/tmp') + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), 'checkout', '-r', 'an-unimportant-value', '-d', 'test', 'bar'], :custom_environment => {}) + provider.create end - resource_without :revision do - it "should just execute 'cvs checkout' without a revision" do - provider.expects(:cvs).with('-d', resource.value(:source), 'checkout', '-d', File.basename(resource.value(:path)), File.basename(resource.value(:source))) - provider.create - end + it "should execute 'cvs checkout' as user 'muppet'" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource[:revision] = 'an-unimportant-value' + resource[:user] = 'muppet' + expects_chdir('/tmp') + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), 'checkout', '-r', 'an-unimportant-value', '-d', 'test', 'bar'], :uid => 'muppet', :custom_environment => {}) + provider.create + end + + it "should just execute 'cvs checkout' without a revision" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource.delete(:revision) + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), 'checkout', '-d', File.basename(resource.value(:path)), File.basename(resource.value(:source))], :custom_environment => {}) + provider.create end - context "with a compression", :resource => {:compression => '3'} do + context "with a compression" do it "should just execute 'cvs checkout' without a revision" do - provider.expects(:cvs).with('-d', resource.value(:source), '-z', '3', 'checkout', '-d', File.basename(resource.value(:path)), File.basename(resource.value(:source))) + resource[:source] = ':ext:source@example.com:/foo/bar' + resource[:compression] = '3' + resource.delete(:revision) + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), '-z', '3', 'checkout', '-d', File.basename(resource.value(:path)), File.basename(resource.value(:source))], :custom_environment => {}) provider.create end end @@ -30,7 +56,8 @@ context "when a source is not given" do it "should execute 'cvs init'" do - provider.expects(:cvs).with('-d', resource.value(:path), 'init') + resource.delete(:source) + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:path), 'init'], :custom_environment => {}) provider.create end end @@ -38,24 +65,21 @@ describe 'destroying' do it "it should remove the directory" do - expects_rm_rf provider.destroy end end describe "checking existence" do - resource_with :source do - it "should check for the CVS directory" do - File.expects(:directory?).with(File.join(resource.value(:path), 'CVS')) - provider.exists? - end + it "should check for the CVS directory with source" do + resource[:source] = ':ext:source@example.com:/foo/bar' + File.expects(:directory?).with(File.join(resource.value(:path), 'CVS')) + provider.exists? end - resource_without :source do - it "should check for the CVSROOT directory" do - File.expects(:directory?).with(File.join(resource.value(:path), 'CVSROOT')) - provider.exists? - end + it "should check for the CVSROOT directory without source" do + resource.delete(:source) + File.expects(:directory?).with(File.join(resource.value(:path), 'CVSROOT')) + provider.exists? end end @@ -71,7 +95,7 @@ end it "should read CVS/Tag" do File.expects(:read).with(@tag_file).returns("T#{@tag}") - provider.revision.should == @tag + expect(provider.revision).to eq(@tag) end end @@ -80,7 +104,7 @@ File.expects(:exist?).with(@tag_file).returns(false) end it "assumes HEAD" do - provider.revision.should == 'HEAD' + expect(provider.revision).to eq('HEAD') end end end @@ -92,7 +116,7 @@ it "should use 'cvs update -dr'" do expects_chdir - provider.expects(:cvs).with('update', '-dr', @tag, '.') + Puppet::Util::Execution.expects(:execute).with([:cvs, 'update', '-dr', @tag, '.'], :custom_environment => {}) provider.revision = @tag end end diff --git a/vcsrepo/spec/unit/puppet/provider/vcsrepo/dummy_spec.rb b/vcsrepo/spec/unit/puppet/provider/vcsrepo/dummy_spec.rb deleted file mode 100644 index a9458882e..000000000 --- a/vcsrepo/spec/unit/puppet/provider/vcsrepo/dummy_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'spec_helper' - -describe_provider :vcsrepo, :dummy, :resource => {:path => '/tmp/vcsrepo'} do - - context 'dummy' do - resource_with :source do - resource_with :ensure => :present do - context "with nothing doing", :resource => {:revision => 'foo'} do - it "should raise an exception" do - proc { provider.working_copy_exists? }.should raise_error(RuntimeError) - end - end - end - end - end - -end diff --git a/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb b/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb index 68b6c0a6e..d0153a1be 100644 --- a/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb +++ b/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb @@ -1,221 +1,307 @@ require 'spec_helper' -describe_provider :vcsrepo, :git, :resource => {:path => '/tmp/vcsrepo'} do +describe Puppet::Type.type(:vcsrepo).provider(:git_provider) do + def branch_a_list(include_branch = nil?) + < 'test', + :ensure => :present, + :provider => :git, + :revision => '2634', + :source => 'git@repo', + :path => '/tmp/test', + :force => false + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('git').returns('/usr/bin/git') + end context 'creating' do - resource_with :source do - resource_with :ensure => :present do - context "with a revision that is a remote branch", :resource => {:revision => 'only/remote'} do - it "should execute 'git clone' and 'git checkout -b'" do - provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) - expects_chdir('/') - expects_chdir - provider.expects(:update_submodules) - provider.expects(:git).with('branch', '-a').returns(resource.value(:revision)) - provider.expects(:git).with('checkout', '--force', resource.value(:revision)) - provider.create - end - end - context "with a revision that is not a remote branch", :resource => {:revision => 'a-commit-or-tag'} do - it "should execute 'git clone' and 'git reset --hard'" do - provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) - expects_chdir('/') - expects_chdir - provider.expects(:update_submodules) - provider.expects(:git).with('branch', '-a').returns(resource.value(:revision)) - provider.expects(:git).with('checkout', '--force', resource.value(:revision)) - provider.create - end - end - resource_without :revision do - it "should execute 'git clone' and submodule commands" do - provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) - provider.expects(:update_submodules) - provider.create - end - end + context "with a revision that is a remote branch" do + it "should execute 'git clone' and 'git checkout -b'" do + resource[:revision] = 'only/remote' + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create end + end - resource_with :ensure => :bare do - resource_with :revision do - it "should just execute 'git clone --bare'" do - provider.expects(:git).with('clone', '--bare', resource.value(:source), resource.value(:path)) - provider.create - end - end + context "with a remote not named 'origin'" do + it "should execute 'git clone --origin not_origin" do + resource[:remote] = 'not_origin' + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', '--origin', 'not_origin', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("not_origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + end + + context "with shallow clone enable" do + it "should execute 'git clone --depth 1'" do + resource[:revision] = 'only/remote' + resource[:depth] = 1 + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', '--depth', '1', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + end + + context "with a revision that is not a remote branch" do + it "should execute 'git clone' and 'git reset --hard'" do + resource[:revision] = 'a-commit-or-tag' + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + + it "should execute 'git clone' and submodule commands" do + resource.delete(:revision) + provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remotes) + provider.create + end + end - resource_without :revision do - it "should just execute 'git clone --bare'" do - provider.expects(:git).with('clone', '--bare', resource.value(:source), resource.value(:path)) - provider.create - end + context "with an ensure of bare" do + context "with revision" do + it "should raise an error" do + resource[:ensure] = :bare + expect { provider.create }.to raise_error Puppet::Error, /cannot set a revision.+bare/i + end + end + context "without revision" do + it "should just execute 'git clone --bare'" do + resource[:ensure] = :bare + resource.delete(:revision) + provider.expects(:git).with('clone', '--bare', resource.value(:source), resource.value(:path)) + provider.expects(:update_remotes) + provider.create end end end context "when a source is not given" do - resource_with :ensure => :present do - context "when the path does not exist" do - it "should execute 'git init'" do - expects_mkdir - expects_chdir - expects_directory?(false) - provider.expects(:bare_exists?).returns(false) - provider.expects(:git).with('init') - provider.create - end - end + context "when the path does not exist" do + it "should execute 'git init'" do + resource[:ensure] = :present + resource.delete(:source) + expects_mkdir + expects_chdir + expects_directory?(false) - context "when the path is a bare repository" do - it "should convert it to a working copy" do - provider.expects(:bare_exists?).returns(true) - provider.expects(:convert_bare_to_working_copy) - provider.create - end + provider.expects(:bare_exists?).returns(false) + provider.expects(:git).with('init') + provider.create end + end - context "when the path is not a repository" do - it "should raise an exception" do - provider.expects(:path_exists?).returns(true) - proc { provider.create }.should raise_error(Puppet::Error) - end + context "when the path is a bare repository" do + it "should convert it to a working copy" do + resource[:ensure] = :present + resource.delete(:source) + provider.expects(:bare_exists?).returns(true) + provider.expects(:convert_bare_to_working_copy) + provider.create end end - resource_with :ensure => :bare do - context "when the path does not exist" do - it "should execute 'git init --bare'" do - expects_chdir - expects_mkdir - expects_directory?(false) - provider.expects(:working_copy_exists?).returns(false) - provider.expects(:git).with('init', '--bare') - provider.create - end + context "when the path is not empty and not a repository" do + it "should raise an exception" do + provider.expects(:path_exists?).returns(true) + provider.expects(:path_empty?).returns(false) + expect { provider.create }.to raise_error(Puppet::Error) end + end + end - context "when the path is a working copy repository" do - it "should convert it to a bare repository" do - provider.expects(:working_copy_exists?).returns(true) - provider.expects(:convert_working_copy_to_bare) - provider.create - end - end + context "when the path does not exist" do + it "should execute 'git init --bare'" do + resource[:ensure] = :bare + resource.delete(:source) + resource.delete(:revision) + expects_chdir + expects_mkdir + expects_directory?(false) + provider.expects(:working_copy_exists?).returns(false) + provider.expects(:git).with('init', '--bare') + provider.create + end + end - context "when the path is not a repository" do - it "should raise an exception" do - expects_directory?(true) - proc { provider.create }.should raise_error(Puppet::Error) - end - end + context "when the path is a working copy repository" do + it "should convert it to a bare repository" do + resource[:ensure] = :bare + resource.delete(:source) + resource.delete(:revision) + provider.expects(:working_copy_exists?).returns(true) + provider.expects(:convert_working_copy_to_bare) + provider.create + end + it "should clone overtop it using force" do + resource[:force] = true + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:path_exists?).returns(true) + provider.expects(:path_empty?).returns(false) + provider.destroy + provider.expects(:git).with('clone',resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create end end + context "when the path is not empty and not a repository" do + it "should raise an exception" do + provider.expects(:path_exists?).returns(true) + provider.expects(:path_empty?).returns(false) + provider.expects(:working_copy_exists?).returns(false) + expect { provider.create }.to raise_error(Puppet::Error) + end + end end + context 'destroying' do it "it should remove the directory" do - expects_rm_rf + #expects_rm_rf provider.destroy end end context "checking the revision property" do - resource_with :revision do - before do - expects_chdir - provider.expects(:git).with('rev-parse', 'HEAD').returns('currentsha') + before do + expects_chdir('/tmp/test') + resource[:revision] = 'currentsha' + resource.delete(:source) + provider.stubs(:git).with('config', 'remote.origin.url').returns('') + provider.stubs(:git).with('fetch', 'origin') # FIXME + provider.stubs(:git).with('fetch', '--tags', 'origin') + provider.stubs(:git).with('rev-parse', 'HEAD').returns('currentsha') + provider.stubs(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.stubs(:git).with('tag', '-l').returns("Hello") + end + + context "when its SHA is not different than the current SHA" do + it "should return the ref" do + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + provider.expects(:update_remotes) + expect(provider.revision).to eq(resource.value(:revision)) end + end - context "when its SHA is not different than the current SHA" do - it "should return the ref" do - provider.expects(:git).with('config', 'remote.origin.url').returns('') - provider.expects(:git).with('fetch', 'origin') # FIXME - provider.expects(:git).with('fetch', '--tags', 'origin') - provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('currentsha') - provider.expects(:git).with('tag', '-l').returns("Hello") - provider.revision.should == resource.value(:revision) - end + context "when its SHA is different than the current SHA" do + it "should return the current SHA" do + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('othersha') + provider.expects(:update_remotes) + expect(provider.revision).to eq(resource.value(:revision)) end + end - context "when its SHA is different than the current SHA" do - it "should return the current SHA" do - provider.expects(:git).with('config', 'remote.origin.url').returns('') - provider.expects(:git).with('fetch', 'origin') # FIXME - provider.expects(:git).with('fetch', '--tags', 'origin') - provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('othersha') - provider.expects(:git).with('tag', '-l').returns("Hello") - provider.revision.should == 'currentsha' - end + context "when its a ref to a remote head" do + it "should return the revision" do + provider.stubs(:git).with('branch', '-a').returns(" remotes/origin/#{resource.value(:revision)}") + provider.expects(:git).with('rev-parse', "origin/#{resource.value(:revision)}").returns("newsha") + provider.expects(:update_remotes) + expect(provider.revision).to eq(resource.value(:revision)) end + end - context "when its a ref to a remote head" do - it "should return the revision" do - provider.expects(:git).with('config', 'remote.origin.url').returns('') - provider.expects(:git).with('fetch', 'origin') # FIXME - provider.expects(:git).with('fetch', '--tags', 'origin') - provider.expects(:git).with('tag', '-l').returns("Hello") - provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('') - provider.expects(:git).with('ls-remote', '--heads', '--tags', 'origin', resource.value(:revision)).returns("newsha refs/heads/#{resource.value(:revision)}") - provider.revision.should == 'currentsha' - end + context "when its a ref to non existant remote head" do + it "should fail" do + provider.expects(:git).with('branch', '-a').returns(branch_a_list) + provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('') + provider.expects(:update_remotes) + expect { provider.revision }.to raise_error(Puppet::Error, /not a local or remote ref$/) end + end - context "when its a ref to non existant remote head" do - it "should fail" do - provider.expects(:git).with('config', 'remote.origin.url').returns('') - provider.expects(:git).with('fetch', 'origin') # FIXME - provider.expects(:git).with('fetch', '--tags', 'origin') - provider.expects(:git).with('tag', '-l').returns("Hello") - provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('') - provider.expects(:git).with('ls-remote', '--heads', '--tags', 'origin', resource.value(:revision)).returns('') - expect { provider.revision }.should raise_error(Puppet::Error, /not a local or remote ref$/) - end + context "when the source is modified" do + it "should update the origin url" do + resource[:source] = 'git://git@foo.com/bar.git' + provider.expects(:git).with('config', '-l').returns("remote.origin.url=git://git@foo.com/foo.git\n") + provider.expects(:git).with('remote', 'set-url', 'origin', 'git://git@foo.com/bar.git') + provider.expects(:git).with('remote','update') + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + expect(provider.revision).to eq(resource.value(:revision)) end + end - context "when the source is modified" do - resource_with :source => 'git://git@foo.com/bar.git' do - it "should update the origin url" do - provider.expects(:git).with('config', 'remote.origin.url').returns('old') - provider.expects(:git).with('config', 'remote.origin.url', 'git://git@foo.com/bar.git') - provider.expects(:git).with('fetch', 'origin') # FIXME - provider.expects(:git).with('fetch', '--tags', 'origin') - provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('currentsha') - provider.expects(:git).with('tag', '-l').returns("Hello") - provider.revision.should == resource.value(:revision) - end - end + context "when multiple sources are modified" do + it "should update the urls" do + resource[:source] = {"origin" => "git://git@foo.com/bar.git", "new_remote" => "git://git@foo.com/baz.git"} + provider.expects(:git).at_least_once.with('config', '-l').returns("remote.origin.url=git://git@foo.com/foo.git\n", "remote.origin.url=git://git@foo.com/bar.git\n") + provider.expects(:git).with('remote', 'set-url', 'origin', 'git://git@foo.com/bar.git') + provider.expects(:git).with('remote', 'add', 'new_remote', 'git://git@foo.com/baz.git') + provider.expects(:git).with('remote','update') + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + expect(provider.revision).to eq(resource.value(:revision)) end end + end context "setting the revision property" do before do expects_chdir end - context "when it's an existing local branch", :resource => {:revision => 'feature/foo'} do + context "when it's an existing local branch" do it "should use 'git fetch' and 'git reset'" do + resource[:revision] = 'feature/foo' provider.expects(:update_submodules) - provider.expects(:git).with('branch', '-a').returns(resource.value(:revision)) + provider.expects(:git).with('branch', '-a').at_least_once.returns(branch_a_list(resource.value(:revision))) provider.expects(:git).with('checkout', '--force', resource.value(:revision)) - provider.expects(:git).with('branch', '-a').returns(resource.value(:revision)) - provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}") + provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}") provider.revision = resource.value(:revision) end end - context "when it's a remote branch", :resource => {:revision => 'only/remote'} do + context "when it's a remote branch" do it "should use 'git fetch' and 'git reset'" do + resource[:revision] = 'only/remote' provider.expects(:update_submodules) - provider.expects(:git).with('branch', '-a').returns(resource.value(:revision)) + provider.expects(:git).with('branch', '-a').at_least_once.returns(resource.value(:revision)) provider.expects(:git).with('checkout', '--force', resource.value(:revision)) - provider.expects(:git).with('branch', '-a').returns(resource.value(:revision)) - provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}") + provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}") provider.revision = resource.value(:revision) end end - context "when it's a commit or tag", :resource => {:revision => 'a-commit-or-tag'} do + context "when it's a commit or tag" do it "should use 'git fetch' and 'git reset'" do - provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a)) + resource[:revision] = 'a-commit-or-tag' + provider.expects(:git).with('branch', '-a').at_least_once.returns(fixture(:git_branch_a)) provider.expects(:git).with('checkout', '--force', resource.value(:revision)) provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a)) provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a)) @@ -227,43 +313,55 @@ context "updating references" do it "should use 'git fetch --tags'" do + resource.delete(:source) expects_chdir - provider.expects(:git).with('config', 'remote.origin.url').returns('') + provider.expects(:git).with('config', '-l').returns("remote.origin.url=git://git@foo.com/foo.git\n") provider.expects(:git).with('fetch', 'origin') provider.expects(:git).with('fetch', '--tags', 'origin') provider.update_references end end - context "checking if revision" do - before do - expects_chdir - provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a)) - end - context "is a local branch" do - context "when it's listed in 'git branch -a'", :resource => {:revision => 'feature/foo'} do - it "should return true" do - provider.should be_local_branch_revision - end - end - context "when it's not listed in 'git branch -a'" , :resource => {:revision => 'feature/notexist'}do - it "should return false" do - provider.should_not be_local_branch_revision - end + describe 'latest?' do + context 'when true' do + it do + provider.expects(:revision).returns('testrev') + provider.expects(:latest_revision).returns('testrev') + expect(provider.latest?).to be_truthy end end - context "is a remote branch" do - context "when it's listed in 'git branch -a' with an 'origin/' prefix", :resource => {:revision => 'only/remote'} do - it "should return true" do - provider.should be_remote_branch_revision - end - end - context "when it's not listed in 'git branch -a' with an 'origin/' prefix" , :resource => {:revision => 'only/local'}do - it "should return false" do - provider.should_not be_remote_branch_revision - end + context 'when false' do + it do + provider.expects(:revision).returns('master') + provider.expects(:latest_revision).returns('testrev') + expect(provider.latest?).to be_falsey end end end + describe 'convert_working_copy_to_bare' do + it do + FileUtils.expects(:mv).returns(true) + FileUtils.expects(:rm_rf).returns(true) + FileUtils.expects(:mv).returns(true) + + provider.instance_eval { convert_working_copy_to_bare } + end + end + + describe 'convert_bare_to_working_copy' do + it do + FileUtils.expects(:mv).returns(true) + FileUtils.expects(:mkdir).returns(true) + FileUtils.expects(:mv).returns(true) + provider.expects(:commits_in?).returns(true) + # If you forget to stub these out you lose 3 hours of rspec work. + provider.expects(:reset).with('HEAD').returns(true) + provider.expects(:git_with_identity).returns(true) + provider.expects(:update_owner_and_excludes).returns(true) + + provider.instance_eval { convert_bare_to_working_copy } + end + end + end diff --git a/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb b/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb index f17aa2f20..65d820d93 100644 --- a/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb +++ b/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb @@ -1,24 +1,38 @@ require 'spec_helper' -describe_provider :vcsrepo, :hg, :resource => {:path => '/tmp/vcsrepo'} do +describe Puppet::Type.type(:vcsrepo).provider(:hg) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :hg, + :path => '/tmp/vcsrepo', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('hg').returns('/usr/bin/hg') + end describe 'creating' do - resource_with :source do - resource_with :revision do - it "should execute 'hg clone -u' with the revision" do - provider.expects(:hg).with('clone', '-u', - resource.value(:revision), - resource.value(:source), - resource.value(:path)) - provider.create - end + context 'with source and revision' do + it "should execute 'hg clone -u' with the revision" do + resource[:source] = 'something' + resource[:revision] = '1' + provider.expects(:hg).with('clone', '-u', + resource.value(:revision), + resource.value(:source), + resource.value(:path)) + provider.create end + end - resource_without :revision do - it "should just execute 'hg clone' without a revision" do - provider.expects(:hg).with('clone', resource.value(:source), resource.value(:path)) - provider.create - end + context 'without revision' do + it "should just execute 'hg clone' without a revision" do + resource[:source] = 'something' + provider.expects(:hg).with('clone', resource.value(:source), resource.value(:path)) + provider.create end end @@ -28,6 +42,22 @@ provider.create end end + + context "when basic auth is used" do + it "should execute 'hg clone'" do + resource[:source] = 'something' + resource[:basic_auth_username] = 'user' + resource[:basic_auth_password] = 'pass' + provider.expects(:hg).with('clone', + resource.value(:source), + resource.value(:path), + "--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" + "\"") + provider.create + end + end end describe 'destroying' do @@ -55,15 +85,17 @@ provider.expects(:hg).with('tags').returns(fixture(:hg_tags)) end - context "when its SHA is not different than the current SHA", :resource => {:revision => '0.6'} do + context "when its SHA is not different than the current SHA" do it "should return the ref" do - provider.revision.should == '0.6' + resource[:revision] = '0.6' + expect(provider.revision).to eq('0.6') end end - context "when its SHA is different than the current SHA", :resource => {:revision => '0.5.3'} do + context "when its SHA is different than the current SHA" do it "should return the current SHA" do - provider.revision.should == '34e6012c783a' + resource[:revision] = '0.5.3' + expect(provider.revision).to eq('34e6012c783a') end end end @@ -74,15 +106,17 @@ context "when it is the same as the current SHA", :resource => {:revision => '34e6012c783a'} do it "should return it" do + resource[:revision] = '34e6012c783a' provider.expects(:hg).with('tags').returns(fixture(:hg_tags)) - provider.revision.should == resource.value(:revision) + expect(provider.revision).to eq(resource.value(:revision)) end end context "when it is not the same as the current SHA", :resource => {:revision => 'not-the-same'} do it "should return the current SHA" do + resource[:revision] = 'not-the-same' provider.expects(:hg).with('tags').returns(fixture(:hg_tags)) - provider.revision.should == '34e6012c783a' + expect(provider.revision).to eq('34e6012c783a') end end end diff --git a/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb b/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb new file mode 100644 index 000000000..e331cae69 --- /dev/null +++ b/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb @@ -0,0 +1,82 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:p4) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :p4, + :path => '/tmp/vcsrepo', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('p4').returns('/usr/local/bin/p4') + end + + spec = { + :input => "Description: Generated by Puppet VCSrepo\nRoot: /tmp/vcsrepo\n\nView:\n", + :marshal => false + } + + describe 'creating' do + context 'with source and revision' do + it "should execute 'p4 sync' with the revision" do + resource[:source] = 'something' + resource[:revision] = '1' + ENV['P4CLIENT'] = 'client_ws1' + + provider.expects(:p4).with(['client', '-o', 'client_ws1']).returns({}) + provider.expects(:p4).with(['client', '-i'], spec) + provider.expects(:p4).with(['sync', resource.value(:source) + "@" + resource.value(:revision)]) + provider.create + end + end + + context 'without revision' do + it "should just execute 'p4 sync' without a revision" do + resource[:source] = 'something' + ENV['P4CLIENT'] = 'client_ws2' + + provider.expects(:p4).with(['client', '-o', 'client_ws2']).returns({}) + provider.expects(:p4).with(['client', '-i'], spec) + provider.expects(:p4).with(['sync', resource.value(:source)]) + provider.create + end + end + + context "when a client and source are not given" do + it "should execute 'p4 client'" do + ENV['P4CLIENT'] = nil + + path = resource.value(:path) + host = Facter.value('hostname') + default = "puppet-" + Digest::MD5.hexdigest(path + host) + + provider.expects(:p4).with(['client', '-o', default]).returns({}) + provider.expects(:p4).with(['client', '-i'], spec) + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + ENV['P4CLIENT'] = 'test_client' + + provider.expects(:p4).with(['client', '-d', '-f', 'test_client']) + expects_rm_rf + provider.destroy + end + end + + describe "checking existence" do + it "should check for the directory" do + provider.expects(:p4).with(['info'], {:marshal => false}).returns({}) + provider.expects(:p4).with(['where', resource.value(:path) + "..."], {:raise => false}).returns({}) + provider.exists? + end + end + +end diff --git a/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb b/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb index 675fc0b61..494da521a 100644 --- a/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb +++ b/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb @@ -1,41 +1,55 @@ require 'spec_helper' -describe_provider :vcsrepo, :svn, :resource => {:path => '/tmp/vcsrepo'} do +describe Puppet::Type.type(:vcsrepo).provider(:svn) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :svn, + :path => '/tmp/vcsrepo', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('git').returns('/usr/bin/git') + end describe 'creating' do - resource_with :source do - resource_with :revision do - it "should execute 'svn checkout' with a revision" do - provider.expects(:svn).with('--non-interactive', 'checkout', '-r', - resource.value(:revision), - resource.value(:source), - resource.value(:path)) - provider.create - end + context 'with source and revision' do + it "should execute 'svn checkout' with a revision" do + resource[:source] = 'exists' + resource[:revision] = '1' + provider.expects(:svn).with('--non-interactive', 'checkout', '-r', + resource.value(:revision), + resource.value(:source), + resource.value(:path)) + provider.create end - resource_without :revision do - it "should just execute 'svn checkout' without a revision" do - provider.expects(:svn).with('--non-interactive', 'checkout', - resource.value(:source), - resource.value(:path)) - provider.create - end + end + context 'with source' do + it "should just execute 'svn checkout' without a revision" do + resource[:source] = 'exists' + provider.expects(:svn).with('--non-interactive', 'checkout', + resource.value(:source), + resource.value(:path)) + provider.create end end - resource_without :source do - resource_with :fstype do - it "should execute 'svnadmin create' with an '--fs-type' option" do - provider.expects(:svnadmin).with('create', '--fs-type', - resource.value(:fstype), - resource.value(:path)) - provider.create - end + + context 'with fstype' do + it "should execute 'svnadmin create' with an '--fs-type' option" do + resource[:fstype] = 'ext4' + provider.expects(:svnadmin).with('create', '--fs-type', + resource.value(:fstype), + resource.value(:path)) + provider.create end - resource_without :fstype do - it "should execute 'svnadmin create' without an '--fs-type' option" do - provider.expects(:svnadmin).with('create', resource.value(:path)) - provider.create - end + end + context 'without fstype' do + it "should execute 'svnadmin create' without an '--fs-type' option" do + provider.expects(:svnadmin).with('create', resource.value(:path)) + provider.create end end end @@ -61,7 +75,7 @@ end it "should use 'svn info'" do expects_chdir - provider.revision.should == '3' # From 'Last Changed Rev', not 'Revision' + expect(provider.revision).to eq('4') # From 'Revision', not 'Last Changed Rev' end end @@ -69,12 +83,10 @@ before do @revision = '30' end - resource_without :source do - it "should use 'svn update'" do - expects_chdir - provider.expects(:svn).with('--non-interactive', 'update', '-r', @revision) - provider.revision = @revision - end + it "should use 'svn update'" do + expects_chdir + provider.expects(:svn).with('--non-interactive', 'update', '-r', @revision) + provider.revision = @revision end end @@ -82,12 +94,11 @@ before do @revision = '30' end - resource_with :source do - it "should use 'svn switch'" do - expects_chdir - provider.expects(:svn).with('--non-interactive', 'switch', '-r', @revision, 'an-unimportant-value') - provider.revision = @revision - end + it "should use 'svn switch'" do + resource[:source] = 'an-unimportant-value' + expects_chdir + provider.expects(:svn).with('--non-interactive', 'switch', '-r', @revision, 'an-unimportant-value') + provider.revision = @revision end end