r10k 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|