r10k 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/CHANGELOG +35 -0
- data/doc/dynamic-environments.mkd +24 -0
- data/doc/dynamic-environments/configuration.mkd +177 -0
- data/doc/dynamic-environments/git-environments.markdown +42 -0
- data/doc/dynamic-environments/introduction.mkd +70 -0
- data/doc/dynamic-environments/usage.mkd +75 -0
- data/lib/r10k/cli.rb +15 -2
- data/lib/r10k/cli/deploy.rb +0 -13
- data/lib/r10k/cli/puppetfile.rb +2 -2
- data/lib/r10k/git.rb +1 -0
- data/lib/r10k/git/alternates.rb +49 -0
- data/lib/r10k/git/repository.rb +8 -1
- data/lib/r10k/git/working_dir.rb +33 -11
- data/lib/r10k/version.rb +1 -1
- data/spec/unit/git/alternates_spec.rb +90 -0
- data/spec/unit/git/repository_spec.rb +10 -0
- data/spec/unit/git/working_dir_spec.rb +110 -1
- data/spec/unit/util/subprocess_spec.rb +4 -0
- metadata +10 -3
- data/doc/dynamic-environments.markdown +0 -206
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MzBlNGU0MTQxMjk1ODQzM2ZkOGMzNmEyYjFmZTVkMGIzY2RiMzk5OQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NTc0ZWVhNjdiZGZjZWNlZTUyZjQ3OTU5ZGMxZWI1NDAzN2Q4YTQ1ZQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ODk2YzRlZGZhOGEwNmMyYTgzMzNjMTY0YzI4OTZjZTc5ZjA3MWYwNTViMTA1
|
10
|
+
MmNmMDhjMDUzMDRkYzQ2ZmY5NWRkNmQ3ZWU1YWRkMDZkYTdmOWYxZWYzOGVh
|
11
|
+
ZjU1MzY3MjU1OTgzNTk0ZmIyYzYwYjE0YjA5N2I4YWIwNTNjYjA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZDUzYzQ1Yjg3Njk2NjA1YmM2YjVhN2JjNDkyYjY3OTU5YWVkYmE1NGI0OGJl
|
14
|
+
MzQ3OGM2NDY2M2U3OGMwYjVkMGY3OTU4NjI0NTIyMjQyMDlmMzg2YzMyZDg2
|
15
|
+
OTQwMjI4NDVhZGQwYzMyOTkxNWYyZWEzNmQ5ZjYwNzUzNmU1YjI=
|
data/CHANGELOG
CHANGED
@@ -1,6 +1,41 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
=========
|
3
3
|
|
4
|
+
1.2.2
|
5
|
+
-----
|
6
|
+
|
7
|
+
2014/07/16
|
8
|
+
|
9
|
+
### User Notes
|
10
|
+
|
11
|
+
(GH-165) `r10k puppetfile` only consumes handled command line options.
|
12
|
+
|
13
|
+
Previously, passing `-v` or other commands when running `r10k puppetfile *`
|
14
|
+
could result in this error:
|
15
|
+
|
16
|
+
r10k puppetfile install --help --trace
|
17
|
+
Error while running: #<RuntimeError: Unrecognized options: help>
|
18
|
+
|
19
|
+
This was due to overly greedy code passing in all options from the command line
|
20
|
+
to the TaskRunner. This has been fixed so only known options are passed along,
|
21
|
+
and options that aren't relevant (such as :verbose) will be ignored.
|
22
|
+
|
23
|
+
(GH-158) Log levels are now documented in the command line --help pages.
|
24
|
+
|
25
|
+
(GH-137) Git remotes are now correctly updated.
|
26
|
+
|
27
|
+
A regression in the Git remote handling meant that git remotes would never be
|
28
|
+
properly updated when switching Git environments and modules from one remote
|
29
|
+
to another, and the git alternates file was never updated properly. This has
|
30
|
+
been fixed so that when the Git remote is updated, all references to the
|
31
|
+
remotes and alternates will be updated.
|
32
|
+
|
33
|
+
(GH-163) All Git tags are deleted when switching Git remotes
|
34
|
+
|
35
|
+
Git tags cannot necessarily be transferred from one Git repository to another,
|
36
|
+
so when a Git repo has its remotes changed all tags are deleted to prevent stale
|
37
|
+
tags from overwriting tags from the new repo.
|
38
|
+
|
4
39
|
1.2.1
|
5
40
|
-----
|
6
41
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Dynamic Environments
|
2
|
+
====================
|
3
|
+
|
4
|
+
Dynamic environment deployment is the core functionality of r10k.
|
5
|
+
|
6
|
+
Table of contents
|
7
|
+
-----------------
|
8
|
+
|
9
|
+
* [Introduction](dynamic-environments/introduction/): A brief description of
|
10
|
+
what dynamic environments are and how they work.
|
11
|
+
* [Git environments](dynamic-environments/git-environments/) How r10k
|
12
|
+
implements dynamic environments using git
|
13
|
+
* [Configuration](dynamic-environments/configuration/) A reference of dynamic
|
14
|
+
environment configuration options and how they're used
|
15
|
+
* [Usage](dynamic-environments/usage/) A reference of r10k commands and how
|
16
|
+
they're used.
|
17
|
+
|
18
|
+
- - -
|
19
|
+
|
20
|
+
Community guides
|
21
|
+
----------------
|
22
|
+
|
23
|
+
* [Building a Functional Puppet Workflow Part 3: Dynamic Environments with R10k](http://garylarizza.com/blog/2014/02/18/puppet-workflow-part-3/)
|
24
|
+
* [Puppet Infrastructure with r10k](http://terrarum.net/blog/puppet-infrastructure-with-r10k.html)
|
@@ -0,0 +1,177 @@
|
|
1
|
+
Dynamic Environment Configuration
|
2
|
+
=================================
|
3
|
+
|
4
|
+
r10k uses a configuration file to determine how dynamic environments should be
|
5
|
+
deployed.
|
6
|
+
|
7
|
+
Config file location
|
8
|
+
--------------------
|
9
|
+
|
10
|
+
By default r10k will try to read `/etc/r10k.yaml` for configuration settings.
|
11
|
+
You can specify an alternate configuration file by specifying the `--config`
|
12
|
+
option, like so:
|
13
|
+
|
14
|
+
r10k deploy -c /srv/puppet/r10k.yaml
|
15
|
+
|
16
|
+
General options
|
17
|
+
---------------
|
18
|
+
|
19
|
+
### cachedir
|
20
|
+
|
21
|
+
The 'cachedir' setting specifies where r10k should keep cached information.
|
22
|
+
Right now this is predominantly used for caching git repositories but will be
|
23
|
+
expanded as other subsystems can take advantage of caching.
|
24
|
+
|
25
|
+
For example:
|
26
|
+
|
27
|
+
```yaml
|
28
|
+
---
|
29
|
+
# Store all cache information in /var/cache
|
30
|
+
cachedir: '/var/cache/r10k'
|
31
|
+
```
|
32
|
+
|
33
|
+
[prerun_command](http://docs.puppetlabs.com/references/latest/configuration.html#preruncommand)
|
34
|
+
|
35
|
+
The cachedir setting defaults to `~/.r10k'. If the HOME environment variable is
|
36
|
+
unset r10k will assume that r10k is being run with the Puppet [`prerun_command`][prerun_command]
|
37
|
+
setting and will set the cachedir default to `/root/.r10k`.
|
38
|
+
|
39
|
+
Deployment options
|
40
|
+
------------------
|
41
|
+
|
42
|
+
The following options configure how r10k deploys dynamic environments.
|
43
|
+
|
44
|
+
### sources
|
45
|
+
|
46
|
+
The `sources` setting specifies what repositories should be used for creating
|
47
|
+
dynamic environments. It is a hash where each key is the short name of a
|
48
|
+
specific repository (for instance, "qa" or "web" or "ops") and the value is a
|
49
|
+
hash of properties for that source.
|
50
|
+
|
51
|
+
```yaml
|
52
|
+
---
|
53
|
+
sources:
|
54
|
+
main:
|
55
|
+
# Source settings follow
|
56
|
+
```
|
57
|
+
|
58
|
+
Source options
|
59
|
+
--------------
|
60
|
+
|
61
|
+
The following options are respected by all source implementations. Sources may
|
62
|
+
implement other options in addition to the ones listed below; see the source
|
63
|
+
specific documentation for more information.
|
64
|
+
|
65
|
+
### remote
|
66
|
+
|
67
|
+
The 'remote' setting specifies where the source repository should be fetched
|
68
|
+
from. It may be any valid URL that the source may check out or clone. The remote
|
69
|
+
must be able to be fetched without any interactive input, eg usernames or
|
70
|
+
passwords cannot be prompted for in order to fetch the remote.
|
71
|
+
|
72
|
+
```
|
73
|
+
---
|
74
|
+
sources:
|
75
|
+
mysource:
|
76
|
+
remote: 'git://git-server.site/my-org/main-modules'
|
77
|
+
```
|
78
|
+
|
79
|
+
### basedir
|
80
|
+
|
81
|
+
The 'basedir' setting specifies where environments will be created for this
|
82
|
+
source. This directory will be entirely managed by r10k and any contents that
|
83
|
+
r10k did not put there will be _removed_.
|
84
|
+
|
85
|
+
```yaml
|
86
|
+
---
|
87
|
+
sources:
|
88
|
+
mysource:
|
89
|
+
basedir: '/etc/puppet/environments'
|
90
|
+
```
|
91
|
+
|
92
|
+
R10k will not check to make sure that different sources collide in a single base
|
93
|
+
directory; if you are using multiple sources you are responsible for making sure
|
94
|
+
that they do not overwrite each other. See also the prefix setting.
|
95
|
+
|
96
|
+
### prefix
|
97
|
+
|
98
|
+
The prefix setting allows environment names to be prefixed with the short name
|
99
|
+
of the given source. This prevents collisions when multiple sources are deployed
|
100
|
+
into the same directory.
|
101
|
+
|
102
|
+
```yaml
|
103
|
+
---
|
104
|
+
sources:
|
105
|
+
mysource:
|
106
|
+
basedir: '/etc/puppet/environments'
|
107
|
+
prefix: true # All environments will be prefixed with "mysource_"
|
108
|
+
```
|
109
|
+
|
110
|
+
Examples
|
111
|
+
--------
|
112
|
+
|
113
|
+
### Minimal example
|
114
|
+
|
115
|
+
The majority of users will only have a single repository where all modules and
|
116
|
+
hiera data files are kept. In this case you will specify a single source:
|
117
|
+
|
118
|
+
```yaml
|
119
|
+
---
|
120
|
+
sources:
|
121
|
+
operations:
|
122
|
+
remote: 'git://git-server.site/my-org/org-modules'
|
123
|
+
basedir: '/etc/puppet/environments'
|
124
|
+
```
|
125
|
+
|
126
|
+
### Separate hiera data
|
127
|
+
|
128
|
+
For more complex cases where you want to store hiera data in a different
|
129
|
+
repository and your modules in another repository, you can specify two sources:
|
130
|
+
|
131
|
+
```yaml
|
132
|
+
---
|
133
|
+
sources:
|
134
|
+
operations:
|
135
|
+
remote: 'git://git-server.site/my-org/org-modules'
|
136
|
+
basedir: '/etc/puppet/environments'
|
137
|
+
hiera:
|
138
|
+
remote: 'git://git-server.site/my-org/org-hiera-data'
|
139
|
+
basedir: '/etc/puppet/hiera-data'
|
140
|
+
```
|
141
|
+
|
142
|
+
### Multiple tenancy
|
143
|
+
|
144
|
+
Alternately you may want to create separate environments from multiple
|
145
|
+
repositories. This is useful when you want two groups to be able to deploy
|
146
|
+
Puppet modules but they should only have write access to their own modules and
|
147
|
+
not the modules of other groups.
|
148
|
+
|
149
|
+
```yaml
|
150
|
+
---
|
151
|
+
sources:
|
152
|
+
main:
|
153
|
+
remote: 'git://git-server.site/my-org/main-modules'
|
154
|
+
basedir: '/etc/puppet/environments'
|
155
|
+
prefix: false # Prefix defaults to false so this is only here for clarity
|
156
|
+
qa:
|
157
|
+
remote: 'git://git-server.site/my-org/qa-puppet-modules'
|
158
|
+
basedir: '/etc/puppet/environments'
|
159
|
+
prefix: true
|
160
|
+
dev:
|
161
|
+
remote: 'git://git-server.site/my-org/dev-puppet-modules'
|
162
|
+
basedir: '/etc/puppet/environments'
|
163
|
+
prefix: true
|
164
|
+
```
|
165
|
+
|
166
|
+
This will create the following directory structure:
|
167
|
+
|
168
|
+
```
|
169
|
+
/etc/puppet/environments
|
170
|
+
|-- production # main-modules repository, production branch
|
171
|
+
|-- upgrade_apache # main-modules repository, upgrade_apache branch
|
172
|
+
|-- qa_production # qa repository, production branch
|
173
|
+
|-- qa_jenkins_test # qa repository, jenkins_test branch
|
174
|
+
|-- dev_production # dev repository, production branch
|
175
|
+
`-- dev_loadtest # dev repository, loadtest branch
|
176
|
+
```
|
177
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Git Based Dynamic Environments
|
2
|
+
==============================
|
3
|
+
|
4
|
+
r10k can use Git repositories to implement dynamic environments. You can create,
|
5
|
+
update, and delete Puppet environments automatically as part of your normal Git
|
6
|
+
workflow.
|
7
|
+
|
8
|
+
Dynamic Environments in a nutshell
|
9
|
+
----------------------------------
|
10
|
+
|
11
|
+
The core idea of dynamic environments is that you should be able to manage your
|
12
|
+
Puppet modules in the same manner that you would manage any other code base. It
|
13
|
+
builds on top of Git topic branch model.
|
14
|
+
|
15
|
+
[git-topic-branching]: http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches "Git Topic Branches"
|
16
|
+
|
17
|
+
One of the most prevalent ways of using Git relies on using [topic branches][git-topic-branching].
|
18
|
+
Whenever changes need to be made that need to be reviewed or tested before going
|
19
|
+
live, they should be done in a different, short lived branch called a topic
|
20
|
+
branch. Work can be freely done on a topic branch in isolation and when the work
|
21
|
+
is completed it is merged into a "master" or "production" branch. This is very
|
22
|
+
powerful because it allows any number of people to rapidly develop features in
|
23
|
+
isolation and merge features in a single operation.
|
24
|
+
|
25
|
+
The dynamic environment model extends extends this git branching strategy to
|
26
|
+
your live Puppet masters. It creates a mapping between Git branches and Puppet
|
27
|
+
environments so that you can use the Git branching model and have that be
|
28
|
+
seamlessly reflected in Puppet environments. This means that creating a new Git
|
29
|
+
branch creates a new Puppet environment, updating a Git branch will update that
|
30
|
+
environment, and deleting a Git branch will remove that environment.
|
31
|
+
|
32
|
+
How it works
|
33
|
+
------------
|
34
|
+
|
35
|
+
r10k works by tracking the state of your git repositories and comparing them the
|
36
|
+
the currently deployed environments. If there's a Git branch that doesn't have a
|
37
|
+
corresponding Puppet environment then r10k will clone that branch into the
|
38
|
+
appropriate directory. When Git branches are updated r10k will update the
|
39
|
+
appropriate Puppet environment to the latest version. Finally if there are
|
40
|
+
Puppet environments that don't have matching Git branches, r10k will assume that
|
41
|
+
the branches for those environments were deleted and will remove those
|
42
|
+
environments.
|
@@ -0,0 +1,70 @@
|
|
1
|
+
Dynamic Environments
|
2
|
+
====================
|
3
|
+
|
4
|
+
One of the most important functions of r10k is its ability to dynamically manage
|
5
|
+
your Puppet environments.
|
6
|
+
|
7
|
+
When environments were originally built into Puppet they were meant to be static
|
8
|
+
in nature. Each environment had to be defined beforehand in the master's
|
9
|
+
puppet.conf file in a section, like so:
|
10
|
+
|
11
|
+
```ini
|
12
|
+
[master]
|
13
|
+
# Environment independent settings
|
14
|
+
vardir = '/var/lib/puppet'
|
15
|
+
|
16
|
+
[production]
|
17
|
+
modulepath = '/etc/puppet/environments/production/modules'
|
18
|
+
|
19
|
+
[testing]
|
20
|
+
modulepath = '/etc/puppet/environments/testing/modules'
|
21
|
+
|
22
|
+
[development]
|
23
|
+
modulepath = '/etc/puppet/environments/development/modules'
|
24
|
+
```
|
25
|
+
|
26
|
+
Static Puppet environments were frequently used to implement a pipeline for
|
27
|
+
developing Puppet code. New Puppet code would be developed and deployed to the
|
28
|
+
development environment, pushed to testing for validation, and then finally
|
29
|
+
pushed to the production for general deployment.
|
30
|
+
|
31
|
+
This static nature of Puppet environments turned out to be inflexible in
|
32
|
+
practice. With a predefined list of environments it could be very cumbersome to
|
33
|
+
develop on different parts of a Puppet codebase in isolation; you could either
|
34
|
+
develop multiple features in the same environment and risk cross pollution, or
|
35
|
+
manually create new environments every time you needed isolation.
|
36
|
+
|
37
|
+
Dynamic environments work by dynamically determining the settings for Puppet
|
38
|
+
environment when the environment is used, rather than by defining an explicit
|
39
|
+
section in puppet.conf. This works by making the current environment (in the
|
40
|
+
'$environment' variable) part of of the path to environment specific settings,
|
41
|
+
like modulepath, manifest, and so forth.
|
42
|
+
|
43
|
+
```ini
|
44
|
+
[master]
|
45
|
+
vardir = '/var/lib/puppet'
|
46
|
+
modulepath = '/etc/puppet/environments/$environment/modules'
|
47
|
+
```
|
48
|
+
|
49
|
+
Running `puppet agent -t --environment myenv` will cause $environment to be
|
50
|
+
expanded to 'myenv', so the modulepath for that environment will be set to
|
51
|
+
'/etc/puppet/environments/myenv/modules'.
|
52
|
+
|
53
|
+
This approach of allowing environments to be defined on the fly is a complete
|
54
|
+
reversal of the original architecture of environments. This approach means that
|
55
|
+
it can be very easy to create new environments, update existing environments,
|
56
|
+
and remove environments that aren't needed anymore. It's common practice
|
57
|
+
to create a temporary environment to test an idea and destroy it shortly after.
|
58
|
+
R10k is designed to enable this sort of fluid workflow.
|
59
|
+
|
60
|
+
R10k predominantly uses version control systems to implement dynamic
|
61
|
+
environments. This works by inspecting the VCS repositories containing your
|
62
|
+
Puppet code and checking out that code on your masters so, that there's a 1:1
|
63
|
+
connection between a branch in your VCS repository and a Puppet environment on
|
64
|
+
your masters. This approach allows you to define the way you want to work and
|
65
|
+
use that with your chosen VCS, and r10k will make Puppet implement that
|
66
|
+
workflow.
|
67
|
+
|
68
|
+
Different version control systems will implement dynamic environments in
|
69
|
+
slightly different ways; check out the VCS specific documentation for more
|
70
|
+
information.
|
@@ -0,0 +1,75 @@
|
|
1
|
+
Usage
|
2
|
+
=====
|
3
|
+
|
4
|
+
R10k provides fairly fine grained controls over your environments to fit your
|
5
|
+
needs. If you want to do a full update of all of your environments and modules
|
6
|
+
and don't need it to be done in real time, you can trigger a full update and let
|
7
|
+
it run in the background. If you are actively developing code and need to run
|
8
|
+
very fast updates of one specific environment, you can do a targeted update of
|
9
|
+
that code as well.
|
10
|
+
|
11
|
+
All commands that deal with deploying environments are grouped under the `r10k
|
12
|
+
deploy` subcommand.
|
13
|
+
|
14
|
+
Command line invocation
|
15
|
+
-----------------------
|
16
|
+
|
17
|
+
### Deploying environments
|
18
|
+
|
19
|
+
Recursively update all environments:
|
20
|
+
|
21
|
+
r10k deploy environment --puppetfile
|
22
|
+
|
23
|
+
The simplest way to use r10k is by simply updating all environments and modules
|
24
|
+
and takes the brute force approach of "update everything, ever." When this
|
25
|
+
command is run r10k will update all sources, create new environments and delete
|
26
|
+
old environments, and recursively update all environment modules specified in
|
27
|
+
environment Puppetfiles. While this is the simplest method for running r10k, is
|
28
|
+
is also the slowest by a very large degree because it does the maximum possible
|
29
|
+
work. This should not be something you run interactively, or use on a regular
|
30
|
+
basis.
|
31
|
+
|
32
|
+
- - -
|
33
|
+
|
34
|
+
Update environments while avoiding unnecessary recursion
|
35
|
+
|
36
|
+
r10k deploy environment
|
37
|
+
|
38
|
+
This will update existing environments and recursively create new environments.
|
39
|
+
Note that when an environment is deployed for the first time, it will
|
40
|
+
automatically update all modules as well. For subsequent updates only the
|
41
|
+
environment itself will be updated.
|
42
|
+
|
43
|
+
- - -
|
44
|
+
|
45
|
+
Update a single environment:
|
46
|
+
|
47
|
+
r10k deploy environment my_working_environment
|
48
|
+
|
49
|
+
When you're actively developing on a given environment, this is the best way to
|
50
|
+
deploy your changes. Note that when an environment is deployed for the first
|
51
|
+
time, it will automatically update all modules as well. For subsequent updates
|
52
|
+
only the environment itself will be updated.
|
53
|
+
|
54
|
+
- - -
|
55
|
+
|
56
|
+
Update a single environment and force an update of modules:
|
57
|
+
|
58
|
+
r10k deploy environment my_working_environment --puppetfile
|
59
|
+
|
60
|
+
This will update the given environment and update all contained modules. This is
|
61
|
+
useful if you want to make sure that a given environment is fully up to date.
|
62
|
+
|
63
|
+
### Deploying modules
|
64
|
+
|
65
|
+
Update a single module across all environments
|
66
|
+
|
67
|
+
r10k deploy module apache
|
68
|
+
|
69
|
+
This is useful for when you're working on a module specified in a Puppetfile and want to update it across all environments.
|
70
|
+
|
71
|
+
- - -
|
72
|
+
|
73
|
+
Update multiple modules across all environments
|
74
|
+
|
75
|
+
r10k deploy module apache jenkins java
|
data/lib/r10k/cli.rb
CHANGED
@@ -16,10 +16,23 @@ module R10K::CLI
|
|
16
16
|
complex environments.
|
17
17
|
EOD
|
18
18
|
|
19
|
-
|
19
|
+
|
20
|
+
flag :h, :help, 'Show help for this command' do |value, cmd|
|
21
|
+
# This is evil because we may not necessarily be called from the
|
22
|
+
# command line and have a meaningful ARGV to scan. However the best
|
23
|
+
# way of having a globally useful --help command is to define the
|
24
|
+
# behavior in the block of the option to immediately handle it and exit
|
25
|
+
# and we don't have access to the verbose option, so the simple method
|
26
|
+
# is to simply scan ARGV.
|
27
|
+
verbose = (ARGV.include?('-v') || ARGV.include?('--verbose'))
|
28
|
+
puts cmd.help(:verbose => verbose)
|
29
|
+
exit 0
|
30
|
+
end
|
31
|
+
|
20
32
|
flag :t, :trace, 'Display stack traces on application crash'
|
21
33
|
|
22
|
-
|
34
|
+
loglevels = R10K::Logging::LOG_LEVELS.reverse.map(&:downcase).join(", ")
|
35
|
+
optional :v, :verbose, "Set log verbosity. Valid values: #{loglevels}" do |value, cmd|
|
23
36
|
case value
|
24
37
|
when true
|
25
38
|
R10K::Logging.level = 'INFO'
|
data/lib/r10k/cli/deploy.rb
CHANGED
@@ -51,10 +51,6 @@ scheduled. On subsequent deployments, Puppetfile deployment will default to off.
|
|
51
51
|
DESCRIPTION
|
52
52
|
|
53
53
|
flag :p, :puppetfile, 'Deploy modules from a puppetfile'
|
54
|
-
flag :h, :help, 'Show help for this command' do |value, cmd|
|
55
|
-
puts cmd.help
|
56
|
-
exit 0
|
57
|
-
end
|
58
54
|
|
59
55
|
run do |opts, args, cmd|
|
60
56
|
deploy = R10K::Deployment.load_config(opts[:config])
|
@@ -90,11 +86,6 @@ It will load the Puppetfile configurations out of all environments, and will
|
|
90
86
|
try to deploy the given module names in all environments.
|
91
87
|
DESCRIPTION
|
92
88
|
|
93
|
-
flag :h, :help, 'Show help for this command' do |value, cmd|
|
94
|
-
puts cmd.help
|
95
|
-
exit 0
|
96
|
-
end
|
97
|
-
|
98
89
|
run do |opts, args, cmd|
|
99
90
|
deploy = R10K::Deployment.load_config(opts[:config])
|
100
91
|
|
@@ -120,10 +111,6 @@ try to deploy the given module names in all environments.
|
|
120
111
|
summary 'Display environments and modules in the deployment'
|
121
112
|
|
122
113
|
flag :p, :puppetfile, 'Display Puppetfile modules'
|
123
|
-
flag :h, :help, 'Show help for this command' do |value, cmd|
|
124
|
-
puts cmd.help
|
125
|
-
exit 0
|
126
|
-
end
|
127
114
|
|
128
115
|
run do |opts, args, cmd|
|
129
116
|
deploy = R10K::Deployment.load_config(opts[:config])
|
data/lib/r10k/cli/puppetfile.rb
CHANGED
@@ -37,7 +37,7 @@ Puppetfile (http://bombasticmonkey.com/librarian-puppet/).
|
|
37
37
|
|
38
38
|
puppetfile = R10K::Puppetfile.new(puppetfile_root, puppetfile_path, puppetfile)
|
39
39
|
|
40
|
-
runner = R10K::TaskRunner.new(opts)
|
40
|
+
runner = R10K::TaskRunner.new(:trace => opts[:trace])
|
41
41
|
task = R10K::Task::Puppetfile::Sync.new(puppetfile)
|
42
42
|
runner.append_task task
|
43
43
|
|
@@ -90,7 +90,7 @@ Puppetfile (http://bombasticmonkey.com/librarian-puppet/).
|
|
90
90
|
|
91
91
|
puppetfile = R10K::Puppetfile.new(puppetfile_root, puppetfile_path, puppetfile)
|
92
92
|
|
93
|
-
runner = R10K::TaskRunner.new(opts)
|
93
|
+
runner = R10K::TaskRunner.new(:trace => opts[:trace])
|
94
94
|
task = R10K::Task::Puppetfile::Purge.new(puppetfile)
|
95
95
|
runner.append_task task
|
96
96
|
|
data/lib/r10k/git.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
# Manage `$GIT_DIR/objects/info/alternates`
|
4
|
+
#
|
5
|
+
# @see man gitrepository-layout(5)
|
6
|
+
class R10K::Git::Alternates
|
7
|
+
|
8
|
+
# @attribute [r] file
|
9
|
+
# @return [Pathname] The alternates file
|
10
|
+
attr_reader :file
|
11
|
+
|
12
|
+
# @param git_dir [String] The path to the git repository
|
13
|
+
def initialize(git_dir)
|
14
|
+
@file = Pathname.new(File.join(git_dir, 'objects', 'info', 'alternates'))
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_a
|
18
|
+
read()
|
19
|
+
end
|
20
|
+
|
21
|
+
def <<(path)
|
22
|
+
write(to_a << path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def include?(path)
|
26
|
+
to_a.include?(path)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def write(entries)
|
32
|
+
if ! @file.parent.directory?
|
33
|
+
raise R10K::Git::GitError, "Cannot write #{@file.to_path}; parent directory does not exist"
|
34
|
+
end
|
35
|
+
@file.open("w") do |fh|
|
36
|
+
entries.each do |entry|
|
37
|
+
fh.puts(entry)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def read
|
43
|
+
entries = []
|
44
|
+
if @file.file?
|
45
|
+
entries = @file.readlines.map(&:chomp)
|
46
|
+
end
|
47
|
+
entries
|
48
|
+
end
|
49
|
+
end
|
data/lib/r10k/git/repository.rb
CHANGED
@@ -84,7 +84,7 @@ class R10K::Git::Repository
|
|
84
84
|
|
85
85
|
ret = {}
|
86
86
|
output.stdout.each_line do |line|
|
87
|
-
next if line.match
|
87
|
+
next if line.match(/\(push\)/)
|
88
88
|
name, url, _ = line.split(/\s+/)
|
89
89
|
ret[name] = url
|
90
90
|
end
|
@@ -92,6 +92,13 @@ class R10K::Git::Repository
|
|
92
92
|
ret
|
93
93
|
end
|
94
94
|
|
95
|
+
def tags
|
96
|
+
entries = []
|
97
|
+
output = git(['tag', '-l'], :git_dir => @git_dir).stdout
|
98
|
+
output.each_line { |line| entries << line.chomp }
|
99
|
+
entries
|
100
|
+
end
|
101
|
+
|
95
102
|
private
|
96
103
|
|
97
104
|
# Fetch objects and refs from the given git remote
|
data/lib/r10k/git/working_dir.rb
CHANGED
@@ -41,7 +41,8 @@ class R10K::Git::WorkingDir < R10K::Git::Repository
|
|
41
41
|
@full_path = File.join(@basedir, @dirname)
|
42
42
|
@git_dir = File.join(@full_path, '.git')
|
43
43
|
|
44
|
-
@
|
44
|
+
@alternates = R10K::Git::Alternates.new(@git_dir)
|
45
|
+
@cache = R10K::Git::Cache.generate(@remote)
|
45
46
|
|
46
47
|
if ref.is_a? String
|
47
48
|
@ref = R10K::Git::Ref.new(ref, self)
|
@@ -61,7 +62,9 @@ class R10K::Git::WorkingDir < R10K::Git::Repository
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def update
|
64
|
-
if
|
65
|
+
update_remotes if update_remotes?
|
66
|
+
|
67
|
+
if ref_needs_fetch?
|
65
68
|
fetch_from_cache
|
66
69
|
checkout(@ref)
|
67
70
|
elsif needs_checkout?
|
@@ -114,22 +117,17 @@ class R10K::Git::WorkingDir < R10K::Git::Repository
|
|
114
117
|
|
115
118
|
private
|
116
119
|
|
117
|
-
|
120
|
+
# Do we need to fetch additional objects and refs in order to resolve the given ref?
|
121
|
+
# @return [true, false]
|
122
|
+
def ref_needs_fetch?
|
118
123
|
@ref.fetch?
|
119
124
|
end
|
120
125
|
|
121
126
|
def fetch_from_cache
|
122
|
-
set_cache_remote
|
123
127
|
@cache.sync
|
124
128
|
fetch('cache')
|
125
129
|
end
|
126
130
|
|
127
|
-
def set_cache_remote
|
128
|
-
if self.remote != @cache.remote
|
129
|
-
git ["remote", "set-url", "cache", @cache.git_dir], :path => @full_path
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
131
|
# Perform a non-bare clone of a git repository.
|
134
132
|
def clone
|
135
133
|
@cache.sync
|
@@ -151,6 +149,30 @@ class R10K::Git::WorkingDir < R10K::Git::Repository
|
|
151
149
|
expected = ref.sha1
|
152
150
|
actual = rev_parse('HEAD')
|
153
151
|
|
154
|
-
!
|
152
|
+
!(expected == actual)
|
153
|
+
end
|
154
|
+
|
155
|
+
def update_remotes?
|
156
|
+
real_remotes = remotes
|
157
|
+
|
158
|
+
expected_origin = @remote
|
159
|
+
expected_cache = @cache.git_dir
|
160
|
+
|
161
|
+
!(expected_origin == real_remotes['origin'] and expected_cache == real_remotes['cache'])
|
162
|
+
end
|
163
|
+
|
164
|
+
def update_remotes
|
165
|
+
# todo: remove all existing refs as they may belong to the old remote
|
166
|
+
git ['remote', 'set-url', 'origin', remote], :path => @full_path
|
167
|
+
git ['remote', 'set-url', 'cache', @cache.git_dir], :path => @full_path
|
168
|
+
@alternates << File.join(@cache.git_dir, 'objects')
|
169
|
+
logger.debug("Removing stale git tags from #{@full_path}")
|
170
|
+
remove_tags
|
171
|
+
end
|
172
|
+
|
173
|
+
def remove_tags
|
174
|
+
tags.each do |tag|
|
175
|
+
git ['tag', '-d', tag], :path => @full_path
|
176
|
+
end
|
155
177
|
end
|
156
178
|
end
|
data/lib/r10k/version.rb
CHANGED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
require 'r10k/git'
|
4
|
+
|
5
|
+
describe R10K::Git::Alternates do
|
6
|
+
subject { described_class.new("/some/nonexistent/path/.git") }
|
7
|
+
|
8
|
+
it "interacts with the alternates file in the given git repository" do
|
9
|
+
expect(subject.file.to_path).to eq("/some/nonexistent/path/.git/objects/info/alternates")
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "reading alternate object entries" do
|
13
|
+
it "reads the alternates file and splits on lines" do
|
14
|
+
expect(subject.file).to receive(:file?).and_return true
|
15
|
+
expect(subject.file).to receive(:readlines).and_return([
|
16
|
+
"/var/cache/r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git\n",
|
17
|
+
"/vagrant/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git\n",
|
18
|
+
])
|
19
|
+
|
20
|
+
expect(subject.to_a).to eq([
|
21
|
+
"/var/cache/r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git",
|
22
|
+
"/vagrant/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git",
|
23
|
+
])
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns an empty array when the file is not present" do
|
27
|
+
expect(subject.file).to receive(:file?).and_return false
|
28
|
+
expect(subject.file).to receive(:readlines).never
|
29
|
+
expect(subject.to_a).to eq([])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "determining if an entry is already present" do
|
34
|
+
before do
|
35
|
+
allow(subject).to receive(:to_a).and_return([
|
36
|
+
"/var/cache/r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git",
|
37
|
+
"/vagrant/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git",
|
38
|
+
])
|
39
|
+
end
|
40
|
+
|
41
|
+
it "is true if the element is in the array of read entries" do
|
42
|
+
expect(subject).to include("/vagrant/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "is false if the element is not in the array of read entries" do
|
46
|
+
expect(subject).to_not include("/tmp/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "appending a new alternate object entry" do
|
51
|
+
describe "and the git objects/info directory does not exist" do
|
52
|
+
it "raises an error when the parent directory does not exist" do
|
53
|
+
expect {
|
54
|
+
subject << "/tmp/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git"
|
55
|
+
}.to raise_error(R10K::Git::GitError,"Cannot write /some/nonexistent/path/.git/objects/info/alternates; parent directory does not exist")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "and the git objects/info directory exists" do
|
60
|
+
let(:io) { StringIO.new }
|
61
|
+
|
62
|
+
before do
|
63
|
+
expect(subject.file).to receive(:open).with('w').and_yield(io)
|
64
|
+
subject.file.stub_chain(:parent, :directory?).and_return true
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
it "creates the alternates file with the new entry when not present" do
|
69
|
+
expect(subject).to receive(:to_a).and_return([])
|
70
|
+
subject << "/tmp/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git"
|
71
|
+
|
72
|
+
expect(io.string).to eq("/tmp/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git\n")
|
73
|
+
end
|
74
|
+
|
75
|
+
it "rewrites the file with all alternate entries" do
|
76
|
+
expect(subject).to receive(:to_a).and_return([
|
77
|
+
"/var/cache/r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git",
|
78
|
+
"/vagrant/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git",
|
79
|
+
])
|
80
|
+
subject << "/tmp/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git"
|
81
|
+
|
82
|
+
expect(io.string).to eq(<<-EOD)
|
83
|
+
/var/cache/r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git
|
84
|
+
/vagrant/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git
|
85
|
+
/tmp/.r10k/git/git---github.com-puppetlabs-puppetlabs-apache.git
|
86
|
+
EOD
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -21,4 +21,14 @@ describe R10K::Git::Repository do
|
|
21
21
|
})
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
describe "tags" do
|
26
|
+
let(:tags) { %w[0.1.1 0.1.2 0.1.3 0.1.4 0.2.0 0.3.0 2.0.0] }
|
27
|
+
let(:output) { tags.map {|x| x + "\n"}.join }
|
28
|
+
|
29
|
+
it "returns a list of tags for this repo" do
|
30
|
+
expect(subject).to receive(:git).with(%w[tag -l], anything).and_return(double(:stdout => output))
|
31
|
+
expect(subject.tags).to eq(tags)
|
32
|
+
end
|
33
|
+
end
|
24
34
|
end
|
@@ -2,11 +2,120 @@ require 'spec_helper'
|
|
2
2
|
require 'r10k/git'
|
3
3
|
|
4
4
|
describe R10K::Git::WorkingDir do
|
5
|
+
include_context "fail on execution"
|
5
6
|
|
6
7
|
describe "initializing" do
|
7
8
|
it "generates a new cache for the remote" do
|
8
|
-
wd = described_class.new('master', 'git://github.com/adrienthebo/r10k-fixture-repo', '/
|
9
|
+
wd = described_class.new('master', 'git://github.com/adrienthebo/r10k-fixture-repo', '/some/nonexistent/dir')
|
9
10
|
wd.cache.should be_kind_of R10K::Git::Cache
|
10
11
|
end
|
12
|
+
|
13
|
+
it "uses the provided ref as the dirname when no dirname is given" do
|
14
|
+
wd = described_class.new('master', 'git://github.com/adrienthebo/r10k-fixture-repo', '/some/nonexistent/dir')
|
15
|
+
expect(wd.dirname).to eq('master')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "uses an explicit dirname when given" do
|
19
|
+
wd = described_class.new('master', 'git://github.com/adrienthebo/r10k-fixture-repo', '/some/nonexistent/dir', 'mydir')
|
20
|
+
expect(wd.dirname).to eq('mydir')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "synchronizing the working directory" do
|
25
|
+
subject { described_class.new('master', 'git://github.com/adrienthebo/r10k-fixture-repo', '/some/nonexistent/dir') }
|
26
|
+
it "clones the repository when the repository doesn't exist" do
|
27
|
+
expect(subject).to receive(:cloned?).and_return false
|
28
|
+
expect(subject).to receive(:clone)
|
29
|
+
subject.sync
|
30
|
+
end
|
31
|
+
|
32
|
+
it "updates the repository when the repository already exists" do
|
33
|
+
expect(subject).to receive(:cloned?).and_return true
|
34
|
+
expect(subject).to receive(:update)
|
35
|
+
subject.sync
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "when cloning a new repository" do
|
40
|
+
subject { described_class.new('master', 'git://github.com/adrienthebo/r10k-fixture-repo', '/some/nonexistent/dir') }
|
41
|
+
|
42
|
+
before do
|
43
|
+
allow(subject).to receive(:cloned?).and_return false
|
44
|
+
end
|
45
|
+
|
46
|
+
it "updates the cache before cloning" do
|
47
|
+
expect(subject.cache).to receive(:sync)
|
48
|
+
allow(subject).to receive(:git)
|
49
|
+
allow(subject).to receive(:checkout)
|
50
|
+
subject.sync
|
51
|
+
end
|
52
|
+
|
53
|
+
it "clones the repository and uses the cache git dir as an object reference" do
|
54
|
+
allow(subject.cache).to receive(:sync)
|
55
|
+
expect(subject).to receive(:git).with(['clone', '--reference', subject.cache.git_dir,
|
56
|
+
'git://github.com/adrienthebo/r10k-fixture-repo',
|
57
|
+
'/some/nonexistent/dir/master'])
|
58
|
+
expect(subject).to receive(:git).with(['remote', 'add', 'cache', subject.cache.git_dir],
|
59
|
+
an_instance_of(Hash))
|
60
|
+
|
61
|
+
expect(subject).to receive(:git).with(['fetch', 'cache'], an_instance_of(Hash))
|
62
|
+
allow(subject).to receive(:checkout)
|
63
|
+
subject.sync
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'checks out the specific ref after the clone' do
|
67
|
+
allow(subject.cache).to receive(:sync)
|
68
|
+
allow(subject).to receive(:git)
|
69
|
+
expect(subject).to receive(:checkout)
|
70
|
+
subject.sync
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "updating an existing repository" do
|
75
|
+
subject { described_class.new('master', 'git://github.com/adrienthebo/r10k-fixture-repo', '/some/nonexistent/dir') }
|
76
|
+
|
77
|
+
before do
|
78
|
+
allow(subject).to receive(:cloned?).and_return true
|
79
|
+
end
|
80
|
+
|
81
|
+
it "updates the remotes when they are out of sync" do
|
82
|
+
allow(subject).to receive(:ref_needs_fetch?).and_return false
|
83
|
+
allow(subject).to receive(:needs_checkout?).and_return false
|
84
|
+
|
85
|
+
expect(subject).to receive(:update_remotes?).and_return true
|
86
|
+
expect(subject).to receive(:update_remotes)
|
87
|
+
|
88
|
+
subject.sync
|
89
|
+
end
|
90
|
+
|
91
|
+
it "updates the cache when the ref requires an update" do
|
92
|
+
allow(subject).to receive(:update_remotes?).and_return false
|
93
|
+
|
94
|
+
expect(subject).to receive(:ref_needs_fetch?).and_return true
|
95
|
+
expect(subject).to receive(:fetch_from_cache)
|
96
|
+
expect(subject).to receive(:checkout).with(an_instance_of(R10K::Git::Ref))
|
97
|
+
|
98
|
+
subject.sync
|
99
|
+
end
|
100
|
+
|
101
|
+
it "checks out the ref when the wrong commit is checked out" do
|
102
|
+
allow(subject).to receive(:update_remotes?).and_return false
|
103
|
+
allow(subject).to receive(:ref_needs_fetch?).and_return false
|
104
|
+
|
105
|
+
expect(subject).to receive(:needs_checkout?).and_return true
|
106
|
+
expect(subject).to receive(:checkout).with(an_instance_of(R10K::Git::Ref))
|
107
|
+
|
108
|
+
subject.sync
|
109
|
+
end
|
110
|
+
|
111
|
+
it "doesn't update the repo when everything is in sync" do
|
112
|
+
allow(subject).to receive(:update_remotes?).and_return false
|
113
|
+
allow(subject).to receive(:ref_needs_fetch?).and_return false
|
114
|
+
allow(subject).to receive(:needs_checkout?).and_return false
|
115
|
+
|
116
|
+
expect(subject).to_not receive(:checkout)
|
117
|
+
|
118
|
+
subject.sync
|
119
|
+
end
|
11
120
|
end
|
12
121
|
end
|
@@ -46,6 +46,10 @@ describe R10K::Util::Subprocess do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
it "raises an exception if raise_on_fail is true" do
|
49
|
+
if RUBY_VERSION =~ /^2\./
|
50
|
+
pending "Ruby 2.x and RSpec 2.x fail when raising an exception with a custom #to_s method"
|
51
|
+
end
|
52
|
+
|
49
53
|
subject.raise_on_fail = true
|
50
54
|
|
51
55
|
allow(result).to receive(:exit_code).and_return(255)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: r10k
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrien Thebo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colored
|
@@ -197,7 +197,11 @@ files:
|
|
197
197
|
- README.markdown
|
198
198
|
- Rakefile
|
199
199
|
- bin/r10k
|
200
|
-
- doc/dynamic-environments.
|
200
|
+
- doc/dynamic-environments.mkd
|
201
|
+
- doc/dynamic-environments/configuration.mkd
|
202
|
+
- doc/dynamic-environments/git-environments.markdown
|
203
|
+
- doc/dynamic-environments/introduction.mkd
|
204
|
+
- doc/dynamic-environments/usage.mkd
|
201
205
|
- doc/puppetfile.markdown
|
202
206
|
- lib/r10k.rb
|
203
207
|
- lib/r10k/cli.rb
|
@@ -223,6 +227,7 @@ files:
|
|
223
227
|
- lib/r10k/errors.rb
|
224
228
|
- lib/r10k/execution.rb
|
225
229
|
- lib/r10k/git.rb
|
230
|
+
- lib/r10k/git/alternates.rb
|
226
231
|
- lib/r10k/git/cache.rb
|
227
232
|
- lib/r10k/git/commit.rb
|
228
233
|
- lib/r10k/git/errors.rb
|
@@ -292,6 +297,7 @@ files:
|
|
292
297
|
- spec/system/version_spec.rb
|
293
298
|
- spec/unit/deployment/environment_spec.rb
|
294
299
|
- spec/unit/deployment/source_spec.rb
|
300
|
+
- spec/unit/git/alternates_spec.rb
|
295
301
|
- spec/unit/git/cache_spec.rb
|
296
302
|
- spec/unit/git/commit_spec.rb
|
297
303
|
- spec/unit/git/head_spec.rb
|
@@ -381,6 +387,7 @@ test_files:
|
|
381
387
|
- spec/unit/git/commit_spec.rb
|
382
388
|
- spec/unit/git/repository_spec.rb
|
383
389
|
- spec/unit/git/head_spec.rb
|
390
|
+
- spec/unit/git/alternates_spec.rb
|
384
391
|
- spec/unit/git/tag_spec.rb
|
385
392
|
- spec/unit/deployment/environment_spec.rb
|
386
393
|
- spec/unit/deployment/source_spec.rb
|
@@ -1,206 +0,0 @@
|
|
1
|
-
Dynamic Environments
|
2
|
-
====================
|
3
|
-
|
4
|
-
r10k implements the dynamic environment workflow with Puppet. This allows you to
|
5
|
-
create, modify, and remove Puppet environments on the fly with Git branches.
|
6
|
-
|
7
|
-
Dynamic Environments in a nutshell
|
8
|
-
----------------------------------
|
9
|
-
|
10
|
-
The core idea of dynamic environments is that you should be able to manage your
|
11
|
-
Puppet modules in the same manner that you would manage any other code base. It
|
12
|
-
builds on top of Git topic branch model.
|
13
|
-
|
14
|
-
[git-topic-branching]: http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches "Git Topic Branches"
|
15
|
-
|
16
|
-
One of the most prevalent ways of using Git relies on using [topic branches][git-topic-branching].
|
17
|
-
Whenever changes need to be made that need to be reviewed or tested before going
|
18
|
-
live, they should be done in a different, short lived branch called a topic
|
19
|
-
branch. Work can be freely done on a topic branch in isolation and when the work
|
20
|
-
is completed it is merged into a "master" or "production" branch. This is very
|
21
|
-
powerful because it allows any number of people to rapidly develop features in
|
22
|
-
isolation and merge features in a single operation.
|
23
|
-
|
24
|
-
The dynamic environment model extends extends this git branching strategy to
|
25
|
-
your live Puppet masters. It creates a mapping between Git branches and Puppet
|
26
|
-
environments so that you can use the Git branching model and have that be
|
27
|
-
seamlessly reflected in Puppet environments. This means that creating a new Git
|
28
|
-
branch creates a new Puppet environment, updating a Git branch will update that
|
29
|
-
environment, and deleting a Git branch will remove that environment.
|
30
|
-
|
31
|
-
How it works
|
32
|
-
------------
|
33
|
-
|
34
|
-
r10k works by tracking the state of your git repositories and comparing them the
|
35
|
-
the currently deployed environments. If there's a Git branch that doesn't have a
|
36
|
-
corresponding Puppet environment then r10k will clone that branch into the
|
37
|
-
appropriate directory. When Git branches are updated r10k will update the
|
38
|
-
appropriate Puppet environment to the latest version. Finally if there are
|
39
|
-
Puppet environments that don't have matching Git branches, r10k will assume that
|
40
|
-
the branches for those environments were deleted and will remove those
|
41
|
-
environments.
|
42
|
-
|
43
|
-
Configuration
|
44
|
-
-------------
|
45
|
-
|
46
|
-
r10k uses a configuration file to determine how dynamic environments should be
|
47
|
-
deployed.
|
48
|
-
|
49
|
-
### Config file location
|
50
|
-
|
51
|
-
By default r10k will try to read `/etc/r10k.yaml` for configuration settings.
|
52
|
-
You can specify an alternate configuration file by specifying the `--config`
|
53
|
-
option, like so:
|
54
|
-
|
55
|
-
r10k deploy -c /srv/puppet/r10k.yaml
|
56
|
-
|
57
|
-
### Configuration format
|
58
|
-
|
59
|
-
#### cachedir
|
60
|
-
|
61
|
-
The `cachedir` setting specifies where r10k should keep cached information.
|
62
|
-
Right now this is predominantly used for caching git repositories but will be
|
63
|
-
expanded as other subsystems can take advantage of caching.
|
64
|
-
|
65
|
-
For example:
|
66
|
-
|
67
|
-
---
|
68
|
-
# Store all cache information in /var/cache
|
69
|
-
cachedir: '/var/cache/r10k'
|
70
|
-
|
71
|
-
#### sources
|
72
|
-
|
73
|
-
The `sources` setting specifies what repositories should be used for creating
|
74
|
-
dynamic environments.
|
75
|
-
|
76
|
-
The `sources` setting is a hash where each key is the short name of a specific
|
77
|
-
repository (for instance, "qa" or "web" or "ops") and the value is a hash of
|
78
|
-
properties for that source.
|
79
|
-
|
80
|
-
#### source sub-options
|
81
|
-
|
82
|
-
##### remote
|
83
|
-
|
84
|
-
The remote is the URL of the Git repository to clone. This repository will need
|
85
|
-
to be cloned without user intervention so SSH keys will need to be configured
|
86
|
-
for the user running r10k.
|
87
|
-
|
88
|
-
##### basedir
|
89
|
-
|
90
|
-
The basedir is the directory that will be populated with Puppet environments.
|
91
|
-
This directory will be entirely managed by r10k and any contents that r10k did
|
92
|
-
not put there will be _removed_.
|
93
|
-
|
94
|
-
##### prefix
|
95
|
-
|
96
|
-
The prefix setting allows environment names to be prefixed with the short name
|
97
|
-
of the given source. This prevents collisions when multiple sources are deployed
|
98
|
-
into the same directory.
|
99
|
-
|
100
|
-
#### source examples
|
101
|
-
|
102
|
-
##### Basic examples
|
103
|
-
|
104
|
-
The majority of users will only have a single repository where all modules and
|
105
|
-
hiera data files are kept. In this case you will specify a single source:
|
106
|
-
|
107
|
-
---
|
108
|
-
# Specify a single environment source
|
109
|
-
sources:
|
110
|
-
operations:
|
111
|
-
remote: 'git@github.com:my-org/org-modules'
|
112
|
-
basedir: '/etc/puppet/environments'
|
113
|
-
|
114
|
-
- - -
|
115
|
-
|
116
|
-
##### Advanced examples
|
117
|
-
|
118
|
-
For more complex cases where you want to store hiera data in a different
|
119
|
-
repository and your modules in another repository, you can specify two sources:
|
120
|
-
|
121
|
-
---
|
122
|
-
sources:
|
123
|
-
operations:
|
124
|
-
remote: 'git@github.com:my-org/org-modules'
|
125
|
-
basedir: '/etc/puppet/environments'
|
126
|
-
hiera:
|
127
|
-
remote: 'git@github.com:my-org/org-hiera-data'
|
128
|
-
basedir: '/etc/puppet/hiera-data'
|
129
|
-
|
130
|
-
- - -
|
131
|
-
|
132
|
-
Alternately you may want to create separate environments from multiple
|
133
|
-
repositories. This is useful when you want two groups to be able to deploy
|
134
|
-
Puppet modules but they should only have write access to their own modules and
|
135
|
-
not the modules of other groups.
|
136
|
-
|
137
|
-
---
|
138
|
-
sources:
|
139
|
-
main:
|
140
|
-
remote: 'git@github.com:my-org/main-modules'
|
141
|
-
basedir: '/etc/puppet/environments'
|
142
|
-
prefix: false # Prefix defaults to false so this is only here for clarity
|
143
|
-
qa:
|
144
|
-
remote: 'git@github.com:my-org/qa-puppet-modules'
|
145
|
-
basedir: '/etc/puppet/environments'
|
146
|
-
prefix: true
|
147
|
-
dev:
|
148
|
-
remote: 'git@github.com:my-org/dev-puppet-modules'
|
149
|
-
basedir: '/etc/puppet/environments'
|
150
|
-
prefix: true
|
151
|
-
|
152
|
-
This will create the following directory structure:
|
153
|
-
|
154
|
-
|
155
|
-
/etc/puppet/environments
|
156
|
-
|-- production # main-modules repository, production branch
|
157
|
-
|-- upgrade_apache # main-modules repository, upgrade_apache branch
|
158
|
-
|-- qa_production # qa repository, production branch
|
159
|
-
|-- qa_jenkins_test # qa repository, jenkins_test branch
|
160
|
-
|-- dev_production # dev repository, production branch
|
161
|
-
`-- dev_loadtest # dev repository, loadtest branch
|
162
|
-
|
163
|
-
Dynamic environments and Puppetfiles
|
164
|
-
------------------------------------
|
165
|
-
|
166
|
-
TODO
|
167
|
-
|
168
|
-
Interacting with dynamic environments
|
169
|
-
-------------------------------------
|
170
|
-
|
171
|
-
r10k provides fairly fine grained controls over your environments to fit your
|
172
|
-
needs. If you want to do a full update of all of your environments and modules
|
173
|
-
and don't need it to be done in real time, you can trigger a full update and let
|
174
|
-
it run in the background. If you are actively developing code and need to run
|
175
|
-
very fast updates of one specific environment, you can do a targeted update of
|
176
|
-
that code as well.
|
177
|
-
|
178
|
-
All commands that deal with deploying environments are grouped under the `r10k
|
179
|
-
deploy` subcommand.
|
180
|
-
|
181
|
-
### Examples
|
182
|
-
|
183
|
-
#### Deploying environments
|
184
|
-
|
185
|
-
# Update all environments across all sources. This can be slow depending
|
186
|
-
# on the number of environments and modules that you're using.
|
187
|
-
r10k deploy environment
|
188
|
-
|
189
|
-
# Update a single environment. When you're actively working on an
|
190
|
-
# environment this is the best way to deploy your changes.
|
191
|
-
r10k deploy environment my_working_environment
|
192
|
-
|
193
|
-
# This is the brute force approach of "update everything, ever." This can
|
194
|
-
# run for an extremely long time so it should not be something you run
|
195
|
-
# interactively on a regular basis.
|
196
|
-
r10k deploy environment --puppetfile
|
197
|
-
|
198
|
-
#### Deploying modules
|
199
|
-
|
200
|
-
# Update a single module across all environments This is useful for when
|
201
|
-
# you're working on a module in an environment and only want to update that
|
202
|
-
# one module.
|
203
|
-
r10k deploy module apache
|
204
|
-
|
205
|
-
# More than one module can be updated at a time.
|
206
|
-
r10k deploy module apache jenkins java
|