vagrant-orchestrate 0.4.7 → 0.5.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5fc2ef762f37e5306a47335865711960050d8b72
4
- data.tar.gz: bb42f425ad3b8166dd940a6adcde5bfc2ca4a97a
3
+ metadata.gz: 819bc31d3db68968306ae9731bfb0c7d65dbb068
4
+ data.tar.gz: 36ed5193b32ddf55945b36ebc8c241a6e22e154a
5
5
  SHA512:
6
- metadata.gz: ca299b93bf0b71ecc4d84d75238ac64fa7432b58792a646bab733764b9b338cdfb2262e57556e2c81f3faa189e12c98548a9b13b0801550b81d33e4a1171894e
7
- data.tar.gz: 7a8dc4f6ab76d4e372ce923f2e1b14bae2c1c613628d9615d83a2c2c2819e574101a51e6bf15c246c1245869b61fed0537ed401ef39772c6ef9576ea43919dc9
6
+ metadata.gz: 508a675892462b3d0d6615966ba0574ccf749f11ae40fba8a6902ab81b6f10ec2cfec0b40a8fbf0233459af6c1dc6dd8354772f9b3ca314043e56e43006cf19f
7
+ data.tar.gz: 45002e7db4623f4f193b956d732eb6b7def0d19c3f7d4eaf907c76d269a0b697e5966cfd9fa5bf4b06392c7c0eb0277de57dfb161c0c56eb64d9d4a0e8284201
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ 0.5.0 (April 22, 2015)
2
+
3
+ - Add guard_clean so that a push will fail if there are uncommitted files. Override with VAGRANT_ORCHESTRATE_NO_GUARD_CLEAN
4
+ - Push a status file including git remote url, ref, user, and date on a successful provision to /var/status/vagrant_orchestrate (c:\programdata\vagrant_orchestrate)
5
+ - Retrieve status using `vagrant orchestrate status`
data/README.md CHANGED
@@ -14,7 +14,7 @@ Linux, and Mac**.
14
14
  ## Quick start
15
15
 
16
16
  ```
17
- $ vagrant orchestrate init --shell --shell-inline "echo Hello" \
17
+ $ vagrant orchestrate init --shell --shell-inline "echo Hello!" \
18
18
  --servers myserver1.mydomain.com,myserver2.mydomain.com \
19
19
  --ssh-username USERNAME --ssh-private-key-path PATH
20
20
  $ vagrant orchestrate push
@@ -109,94 +109,24 @@ This works for Windows managed servers using WinRM as well
109
109
 
110
110
  #### Plugins
111
111
 
112
- This also supports a self-contained way to install plugins, just list them in the required_plugins section
112
+ This also supports a portable way to install plugins, just list them in the required_plugins section
113
113
 
114
114
  ```ruby
115
115
  required_plugins = %w( vagrant-managed-servers vagrant-hostsupdater )
116
116
  ```
117
117
 
118
118
  #### Working with multiple environments
119
- It is a very common pattern in software development to have separate environments - e.g. dev, test, and prod.
120
- Vagrant Orchestrate offers a way to manage multiple environments using a combination of a single servers.json
121
- file and the name of the current git branch to know which the current environment is.
122
-
123
- ```javascript
124
- # servers.json
125
- {
126
- "environments": {
127
- "dev": {
128
- "servers": [
129
- "dev.myapp.mydomain.com"
130
- ]
131
- },
132
- "test": {
133
- "servers": [
134
- "test1.myapp.mydomain.com",
135
- "test2.myapp.mydomain.com"
136
- ]
137
- },
138
- "prod": {
139
- "servers": [
140
- "prod1.myapp.mydomain.com",
141
- "prod2.myapp.mydomain.com",
142
- "prod3.myapp.mydomain.com"
143
- ]
144
- }
145
- }
146
- }
147
- ```
148
119
 
149
- Add the following line to the top of your `Vagrantfile`
120
+ Vagrant Orchestrate offers a way to manage multiple environments using a combination of a single servers.json file and the name of the current git branch as an indicator of the current environment.
150
121
 
151
- ```ruby
152
- managed_servers = VagrantPlugins::Orchestrate::Plugin.load_servers_for_branch
153
- ```
122
+ To initialize an environment aware Vagrantfile, use
154
123
 
155
- If you create git branches named `dev`, `test`, and `prod`, your vagrantfile will become environment aware and
156
- you'll only be able to see the servers appropriate for that environment.
124
+ $ vagrant orchestrate init --environments dev,test,prod
157
125
 
158
- ```
159
- $ git branch
160
- * dev
161
- test
162
- prod
163
- $ vagrant status
164
- Current machine states:
165
-
166
- local not created (virtualbox)
167
- dev.myapp.mydomain.com not created (managed)
168
-
169
- $ git checkout test
170
- Switched to branch 'test'
171
- $ vagrant status
172
- Current machine states:
173
-
174
- local not created (virtualbox)
175
- test1.myapp.mydomain.com not created (managed)
176
- test2.myapp.mydomain.com not created (managed)
177
-
178
- $ git checkout prod
179
- Switched to branch 'prod'
180
- $ vagrant status
181
- Current machine states:
182
-
183
- local not created (virtualbox)
184
- prod1.myapp.mydomain.com not created (managed)
185
- prod2.myapp.mydomain.com not created (managed)
186
- prod3.myapp.mydomain.com not created (managed)
187
- ```
126
+ You'll need to create git branches with matching names and fill out the servers.json
127
+ file in order for the Vagrantfile to be git branch aware.
188
128
 
189
- Any branch that doesn't have a matching environment in the servers.json file will
190
- not list any managed servers.
191
-
192
- ```
193
- $ git checkout -b my_feature_branch
194
- Switched to a new branch 'my_feature_branch'
195
- $ vagrant status
196
- Current machine states:
197
-
198
- local not created (virtualbox)
199
- ```
129
+ Learn more about [environments](docs/environments.md)
200
130
 
201
131
  #### Credentials
202
132
 
@@ -206,13 +136,7 @@ by passing the `--credentials-prompt` flag to the `vagrant orchestrate init` com
206
136
  or add the following to your Vagrantfile.
207
137
 
208
138
  ```ruby
209
- Vagrant.configure("2") do |config|
210
-
211
- ...
212
-
213
- config.orchestrate.credentials do |creds|
214
- creds.prompt = true
215
- end
139
+ config.orchestrate.credentials.prompt = true
216
140
  ```
217
141
 
218
142
  The credentials config object can accept one additional parameter, `file_path`. Setting
@@ -227,36 +151,7 @@ will be checked.
227
151
 
228
152
  #### Puppet
229
153
 
230
- Experimental puppet templating support is available as well with the `--puppet` flag and associated options
231
-
232
- ```ruby
233
- required_plugins = %w( vagrant-managed-servers vagrant-librarian-puppet )
234
-
235
- ...
236
-
237
- config.librarian_puppet.placeholder_filename = ".gitignore"
238
- config.vm.provision "puppet" do |puppet|
239
- puppet.module_path = 'modules'
240
- puppet.hiera_config_path = 'hiera.yaml'
241
- end
242
- ```
243
-
244
- The following files and folders will be placed in the puppet directory
245
-
246
- ```
247
- Puppetfile
248
- Vagrantfile
249
- dummy.box
250
- hiera/
251
- common.yaml
252
- hiera.yaml
253
- manifests/
254
- default.pp
255
- modules/
256
- .gitignore
257
- ```
258
-
259
- For a full list of init options, run `vagrant orchestrate init --help`
154
+ Experimental [puppet templating](docs/puppet.md) support is available as well with the `--puppet` flag and associated options
260
155
 
261
156
  ### Pushing changes
262
157
  Go ahead and push changes to your managed servers, in serial by default.
@@ -267,13 +162,27 @@ The push command is currently limited by convention to vagrant machines that use
267
162
 
268
163
  #### Deployment Strategy
269
164
 
270
- Vagrant Orchestrate supports several deployment [strategies](docs/strategy.md) including parallel, canary, and
271
- half and half.
165
+ Vagrant Orchestrate supports several deployment [strategies](docs/strategy.md) including parallel, canary, and half and half.
272
166
 
273
167
  You can push changes to all of your servers in parallel with
274
168
 
275
169
  $ vagrant orchestrate push --strategy parallel
276
170
 
171
+ ### Status
172
+ The `vagrant orchestrate status` command will reach out to each of the defined
173
+ managed servers and print information about the last successful push from this
174
+ repo, including date, ref, and user that performed the push.
175
+
176
+ ```
177
+ $ vagrant orchestrate status
178
+ Current managed server states:
179
+
180
+ managed-1 2015-04-19 00:46:22 UTC e983dddd8041c5db77494266328f1d266430f57d cbaldauf
181
+ managed-2 2015-04-19 00:46:22 UTC e983dddd8041c5db77494266328f1d266430f57d cbaldauf
182
+ managed-3 Status unavailable.
183
+ managed-4 2015-04-19 00:43:07 UTC e983dddd8041c5db77494266328f1d266430f57d cbaldauf
184
+ ```
185
+
277
186
  ## Filtering managed commands
278
187
  It can be easy to make mistakes such as rebooting production if you have managed long-lived servers as well as local VMs defined in your Vagrantfile. We add some protection with the `orchestrate.filter_managed_commands` configuration setting, which will cause up, provision, reload, and destroy commands to be ignored for servers with the managed provider.
279
188
 
@@ -281,14 +190,6 @@ It can be easy to make mistakes such as rebooting production if you have managed
281
190
  config.orchestrate.filter_managed_commands = true
282
191
  ```
283
192
 
284
- ## Branching strategy
285
-
286
- If you have several environments (e.g. dev, test, prod), it is recommended to create
287
- a separate branch for each environment and put the appropriate servers into the
288
- managed_servers array at the top of the Vagrantfile for each. To move a change
289
- across branches, simply create a feature branch from your earliest branch and then
290
- merge that feature into downstream environments to avoid conflicts.
291
-
292
193
  ## Tips for Windows hosts
293
194
 
294
195
  * Need rsync? Install [OpenSSH](http://www.mls-software.com/opensshd.html) and then run this [script](https://github.com/joefitzgerald/packer-windows/blob/master/scripts/rsync.bat) to install rsync. Vagrant managed servers currently only works with cygwin based rsync implementations.
@@ -302,14 +203,13 @@ merge that feature into downstream environments to avoid conflicts.
302
203
  4. Push to the branch (`git push origin my-new-feature`)
303
204
  5. Create a new Pull Request
304
205
 
305
- ## Development Tips
306
-
307
- You'll want Ruby v2.0.0* and bundler for developing changes.
308
-
309
- During the course of development you'll want to run the code you're working on,
310
- not the version of Vagrant Orchestrate you've installed. In order to accomplish
311
- this, run your vagrant orchestrate commands in the bundler environment.
206
+ ## Development Flow
312
207
 
313
- In your shell:
208
+ Prerequisites:
209
+ * Ruby 2.0 or greater
314
210
 
315
- $ bundle exec vagrant orchestrate
211
+ Flow:
212
+ 1. Develop your feature
213
+ 2. Test locally with `bundle exec vagrant orchestrate *`
214
+ 3. `bundle exec rake build`
215
+ 4. `bundle exec rake acceptance`, which will take a few minutes
data/Rakefile CHANGED
@@ -10,13 +10,13 @@ task default: :build
10
10
 
11
11
  desc "Run acceptance tests with vagrant-spec"
12
12
  task :acceptance do
13
- puts "Brining up target servers"
13
+ puts "Bringing up target servers and syncing with NTP"
14
14
  # Spinning up local servers here, which the managed provider will connect to
15
15
  # by IP. See the Vagrantfile in the root of the repo for more info.
16
16
  system("vagrant up /local/ --no-provision")
17
17
  # To ensure the ntp sync happens even if the servers are already up
18
18
  system("vagrant provision /local/")
19
- system("bundle exec vagrant-spec test --components=orchestrate/push orchestrate/prompt")
19
+ system("bundle exec vagrant-spec test --components=orchestrate/push orchestrate/prompt orchestrate/status")
20
20
  puts "Destroying target servers"
21
21
  system("vagrant destroy -f /local/")
22
22
  end
data/Vagrantfile CHANGED
@@ -1,6 +1,8 @@
1
1
  managed_servers = %w( 192.168.10.80 192.168.10.81 192.168.10.82 192.168.10.83)
2
2
 
3
3
  Vagrant.configure(2) do |config|
4
+ config.orchestrate.filter_managed_commands = true
5
+
4
6
  # These boxes are defined locally to enable acceptance testing. Spinning up
5
7
  # real boxes in the vagrant-spec environment was expensive because it ignored
6
8
  # the cache and didn't expose a facility to view the vagrant output as it ran.
@@ -0,0 +1,35 @@
1
+ require "vagrant-spec"
2
+ require "vagrant-orchestrate/repo_status"
3
+
4
+ describe "vagrant orchestrate status", component: "orchestrate/status" do
5
+ include_context "acceptance"
6
+
7
+ TEST_REF = "050bfd9c686b06c292a9614662b0ab1bbf652db3"
8
+ TEST_REMOTE_ORIGIN_URL = "http://github.com/Cimpress-MCP/vagrant-orchestrate.git"
9
+
10
+ before do
11
+ environment.skeleton("basic")
12
+ end
13
+
14
+ it "handles no status file gracefully" do
15
+ # Make sure we're starting from a clean slate, rspec order isn't guaranteed.
16
+ execute("vagrant", "ssh", "-c", "\"rm -rf /var/state/vagrant_orchestrate\" /managed-1/")
17
+ # All commands are executed against a single machine to reduce variability
18
+ result = execute("vagrant", "orchestrate", "status", "/managed-1/")
19
+ expect(result.stdout).to include("Status unavailable.")
20
+ end
21
+
22
+ it "can push and retrieve status" do
23
+ # Because vagrant-spec executes in a clean tmp folder, it isn't a git repo,
24
+ # and the normal git commands don't work. We'll inject some test data using
25
+ # environment variables. See vagrant-orchestrate/repo_status.rb for impl.
26
+ ENV["VAGRANT_ORCHESTRATE_STATUS_TEST_REF"] = TEST_REF
27
+ ENV["VAGRANT_ORCHESTRATE_STATUS_TEST_REMOTE_ORIGIN_URL"] = TEST_REMOTE_ORIGIN_URL
28
+ execute("vagrant", "orchestrate", "push", "/managed-1/")
29
+ result = execute("vagrant", "orchestrate", "status", "/managed-1/")
30
+ status = VagrantPlugins::Orchestrate::RepoStatus.new
31
+ # Punting on date. Can always add it later if needed
32
+ expect(result.stdout).to include(status.ref)
33
+ expect(result.stdout).to include(status.user)
34
+ end
35
+ end
@@ -0,0 +1,82 @@
1
+ # Environments
2
+ It is a very common pattern in software development to have separate environments - e.g. dev, test, and prod.
3
+ Vagrant Orchestrate offers a way to manage multiple environments using a combination of a single servers.json
4
+ file and the name of the current git branch to know which the current environment is.
5
+
6
+ ```javascript
7
+ # servers.json
8
+ {
9
+ "environments": {
10
+ "dev": {
11
+ "servers": [
12
+ "dev.myapp.mydomain.com"
13
+ ]
14
+ },
15
+ "test": {
16
+ "servers": [
17
+ "test1.myapp.mydomain.com",
18
+ "test2.myapp.mydomain.com"
19
+ ]
20
+ },
21
+ "prod": {
22
+ "servers": [
23
+ "prod1.myapp.mydomain.com",
24
+ "prod2.myapp.mydomain.com",
25
+ "prod3.myapp.mydomain.com"
26
+ ]
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ Add the following line to the top of your `Vagrantfile`
33
+
34
+ ```ruby
35
+ managed_servers = VagrantPlugins::Orchestrate::Plugin.load_servers_for_branch
36
+ ```
37
+
38
+ If you create git branches named `dev`, `test`, and `prod`, your vagrantfile will become environment aware and
39
+ you'll only be able to see the servers appropriate for that environment.
40
+
41
+ ```
42
+ $ git branch
43
+ * dev
44
+ test
45
+ prod
46
+ $ vagrant status
47
+ Current machine states:
48
+
49
+ local not created (virtualbox)
50
+ dev.myapp.mydomain.com not created (managed)
51
+
52
+ $ git checkout test
53
+ Switched to branch 'test'
54
+ $ vagrant status
55
+ Current machine states:
56
+
57
+ local not created (virtualbox)
58
+ test1.myapp.mydomain.com not created (managed)
59
+ test2.myapp.mydomain.com not created (managed)
60
+
61
+ $ git checkout prod
62
+ Switched to branch 'prod'
63
+ $ vagrant status
64
+ Current machine states:
65
+
66
+ local not created (virtualbox)
67
+ prod1.myapp.mydomain.com not created (managed)
68
+ prod2.myapp.mydomain.com not created (managed)
69
+ prod3.myapp.mydomain.com not created (managed)
70
+ ```
71
+
72
+ Any branch that doesn't have a matching environment in the servers.json file will
73
+ not list any managed servers.
74
+
75
+ ```
76
+ $ git checkout -b my_feature_branch
77
+ Switched to a new branch 'my_feature_branch'
78
+ $ vagrant status
79
+ Current machine states:
80
+
81
+ local not created (virtualbox)
82
+ ```
data/docs/puppet.md ADDED
@@ -0,0 +1,32 @@
1
+ # Puppet
2
+
3
+ Experimental [puppet templating](docs/puppet.md) support is available as well with the `--puppet` flag and associated options
4
+
5
+ ```ruby
6
+ required_plugins = %w( vagrant-managed-servers vagrant-librarian-puppet )
7
+
8
+ ...
9
+
10
+ config.librarian_puppet.placeholder_filename = ".gitignore"
11
+ config.vm.provision "puppet" do |puppet|
12
+ puppet.module_path = 'modules'
13
+ puppet.hiera_config_path = 'hiera.yaml'
14
+ end
15
+ ```
16
+
17
+ The following files and folders will be placed in the puppet directory
18
+
19
+ ```
20
+ Puppetfile
21
+ Vagrantfile
22
+ dummy.box
23
+ hiera/
24
+ common.yaml
25
+ hiera.yaml
26
+ manifests/
27
+ default.pp
28
+ modules/
29
+ .gitignore
30
+ ```
31
+
32
+ For a full list of init options, run `vagrant orchestrate init --help`
@@ -0,0 +1,40 @@
1
+ module VagrantPlugins
2
+ module Orchestrate
3
+ module Command
4
+ module CommandMixins
5
+ # Given an array of vagrant command line args (e.g. the result of calling
6
+ # parse_options), filter out unmanaged servers and provide the resulting list.
7
+ def filter_unmanaged(argv)
8
+ machines = []
9
+ with_target_vms(argv) do |machine|
10
+ if machine.provider_name.to_sym == :managed
11
+ machines << machine
12
+ else
13
+ @logger.debug("Skipping #{machine.name} because it doesn't use the :managed provider")
14
+ end
15
+ end
16
+
17
+ if machines.empty?
18
+ @env.ui.info("No servers with :managed provider found. Exiting.")
19
+ end
20
+
21
+ machines
22
+ end
23
+
24
+ # Delete a file in a way that works on windows
25
+ def super_delete(filepath)
26
+ # Thanks, Windows. http://alx.github.io/2009/01/27/ruby-wundows-unlink.html
27
+ 10.times do
28
+ begin
29
+ File.delete(filepath)
30
+ break
31
+ rescue
32
+ @logger.warn("Unable to delete file #{filepath}")
33
+ sleep 0.05
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -142,7 +142,7 @@ module VagrantPlugins
142
142
  environments: options[:environments],
143
143
  plugins: options[:plugins],
144
144
  creds_prompt: options[:creds_prompt]
145
- )
145
+ )
146
146
  write_file("Vagrantfile", contents, options)
147
147
  FileUtils.cp(Orchestrate.source_root.join("templates", "vagrant", "dummy.box"),
148
148
  File.join(@env.cwd, "dummy.box"))
@@ -1,6 +1,9 @@
1
+ require "English"
1
2
  require "optparse"
2
3
  require "vagrant"
3
4
  require "vagrant-orchestrate/action/setcredentials"
5
+ require "vagrant-orchestrate/repo_status"
6
+ require_relative "command_mixins"
4
7
 
5
8
  # Borrowed from http://stackoverflow.com/questions/12374645/splitting-an-array-into-equal-parts-in-ruby
6
9
  class Array
@@ -16,6 +19,7 @@ module VagrantPlugins
16
19
  module Command
17
20
  class Push < Vagrant.plugin("2", :command)
18
21
  include Vagrant::Util
22
+ include CommandMixins
19
23
 
20
24
  @logger = Log4r::Logger.new("vagrant_orchestrate::command::push")
21
25
 
@@ -44,19 +48,10 @@ module VagrantPlugins
44
48
  argv = parse_options(opts)
45
49
  return unless argv
46
50
 
47
- machines = []
48
- with_target_vms(argv) do |machine|
49
- if machine.provider_name.to_sym == :managed
50
- machines << machine
51
- else
52
- @logger.debug("Skipping #{machine.name} because it doesn't use the :managed provider")
53
- end
54
- end
51
+ guard_clean unless ENV["VAGRANT_ORCHESTRATE_NO_GUARD_CLEAN"]
55
52
 
56
- if machines.empty?
57
- @env.ui.info("No servers with :managed provider found. Skipping.")
58
- return 0
59
- end
53
+ machines = filter_unmanaged(argv)
54
+ return 0 if machines.empty?
60
55
 
61
56
  retrieve_creds(machines) if @env.vagrantfile.config.orchestrate.credentials
62
57
 
@@ -94,6 +89,7 @@ module VagrantPlugins
94
89
  return 1 unless result
95
90
  0
96
91
  end
92
+ # rubocop:enable Metrics/AbcSize, MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
97
93
 
98
94
  def split(machines)
99
95
  groups = machines.in_groups(2)
@@ -103,6 +99,7 @@ module VagrantPlugins
103
99
  groups
104
100
  end
105
101
 
102
+ # rubocop:disable Metrics/AbcSize, MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
106
103
  def deploy(options, *groups)
107
104
  groups.select! { |g| g.size > 0 }
108
105
  groups.each_with_index do |machines, index|
@@ -115,6 +112,7 @@ module VagrantPlugins
115
112
  begin
116
113
  batchify(machines, :up, options)
117
114
  batchify(machines, :provision, options)
115
+ upload_status_all(machines)
118
116
  batchify(machines, :reload, options) if options[:reboot]
119
117
  ensure
120
118
  batchify(machines, :destroy, options)
@@ -159,12 +157,53 @@ module VagrantPlugins
159
157
  creds.apply_creds(machine, username, password)
160
158
  end
161
159
  else
162
- @env.ui.warn <<-WARNING
163
- Vagrant-orchestrate could not gather credentials. \
164
- Continuing with default credentials."
165
- WARNING
160
+ @env.ui.warn "Vagrant-orchestrate could not gather credentials. Continuing with default credentials."
166
161
  end
167
162
  end
163
+
164
+ def guard_clean
165
+ clean? && committed? || abort("ERROR!\nThere are files that need to be committed first.")
166
+ end
167
+
168
+ def clean?
169
+ `git diff --exit-code 2>&1`
170
+ $CHILD_STATUS == 0
171
+ end
172
+
173
+ def committed?
174
+ `git diff-index --quiet --cached HEAD 2>&1`
175
+ $CHILD_STATUS == 0
176
+ end
177
+
178
+ def upload_status_all(machines)
179
+ status = RepoStatus.new
180
+ source = File.join(@env.tmp_path, "vagrant_orchestrate_status")
181
+ File.write(source, status.to_json)
182
+ machines.each do |machine|
183
+ upload_status_one(source, status, machine)
184
+ end
185
+ ensure
186
+ super_delete(source) if File.exist?(source)
187
+ end
188
+
189
+ def upload_status_one(source, status, machine)
190
+ destination = status.remote_path(machine.config.vm.communicator)
191
+ parent_folder = File.split(destination)[0]
192
+ machine.communicate.wait_for_ready(5)
193
+ @logger.debug("Ensuring vagrant_orchestrate status directory exists")
194
+ machine.communicate.sudo("mkdir -p #{parent_folder}")
195
+ machine.communicate.sudo("chmod 777 #{parent_folder}")
196
+ @logger.debug("Uploading vagrant_orchestrate status file")
197
+ @logger.debug(" source: #{source}")
198
+ @logger.debug(" dest: #{destination}")
199
+ machine.communicate.upload(source, destination)
200
+ @logger.debug("Setting uploaded file world-writable")
201
+ machine.communicate.sudo("chmod 777 #{destination}")
202
+ rescue => ex
203
+ @logger.error(ex)
204
+ @env.ui.warn("An error occurred when trying to upload status to #{machine.name}. Continuing")
205
+ @env.ui.warn(ex.message)
206
+ end
168
207
  end
169
208
  end
170
209
  end
@@ -25,6 +25,11 @@ module VagrantPlugins
25
25
  require_relative "push"
26
26
  Push
27
27
  end
28
+
29
+ @subcommands.register(:status) do
30
+ require_relative "status"
31
+ Status
32
+ end
28
33
  end
29
34
 
30
35
  def execute
@@ -44,7 +49,6 @@ module VagrantPlugins
44
49
  end
45
50
 
46
51
  # Prints the help out for this command
47
- # rubocop:disable Metrics/AbcSize
48
52
  def help
49
53
  opts = OptionParser.new do |o|
50
54
  o.banner = "Usage: vagrant orchestrate <subcommand> [<args>]"
@@ -66,7 +70,6 @@ module VagrantPlugins
66
70
 
67
71
  @env.ui.info(opts.help, prefix: false)
68
72
  end
69
- # rubocop:enable Metrics/AbcSize
70
73
  end
71
74
  end
72
75
  end
@@ -0,0 +1,69 @@
1
+ require "json"
2
+ require "optparse"
3
+ require "vagrant"
4
+ require "vagrant-orchestrate/repo_status"
5
+ require_relative "command_mixins"
6
+
7
+ module VagrantPlugins
8
+ module Orchestrate
9
+ module Command
10
+ class Status < Vagrant.plugin("2", :command)
11
+ include Vagrant::Util
12
+ include CommandMixins
13
+
14
+ @logger = Log4r::Logger.new("vagrant_orchestrate::command::status")
15
+
16
+ def execute
17
+ opts = OptionParser.new do |o|
18
+ o.banner = "Usage: vagrant orchestrate status"
19
+ o.separator ""
20
+ end
21
+
22
+ argv = parse_options(opts)
23
+ return unless argv
24
+
25
+ machines = filter_unmanaged(argv)
26
+ return 0 if machines.empty?
27
+
28
+ print_status machines
29
+ end
30
+
31
+ def print_status(machines)
32
+ # There is some detail output fromt he communicator.download that I
33
+ # don't want to suppress, but I also don't want it to be interspersed
34
+ # with the actual status information. Let's buffer the status output.
35
+ output = []
36
+ @logger.debug("About to download machine status")
37
+ machines.each do |machine|
38
+ output << get_status(RepoStatus.new.remote_path(machine.config.vm.communicator), machine)
39
+ end
40
+ @env.ui.info("Current managed server states:")
41
+ @env.ui.info("")
42
+ output.each do |line|
43
+ @env.ui.info line
44
+ end
45
+ end
46
+
47
+ def get_status(remote, machine)
48
+ machine.communicate.wait_for_ready(5)
49
+ local = File.join(@env.tmp_path, "#{machine.name}_status")
50
+ @logger.debug("Downloading orchestrate status for #{machine.name}")
51
+ @logger.debug(" remote file: #{remote}")
52
+ @logger.debug(" local file: #{local}")
53
+ machine.communicate.download(remote, local)
54
+ content = File.read(local)
55
+ @logger.debug("File content:")
56
+ @logger.debug(content)
57
+ status = JSON.parse(content)
58
+ return machine.name.to_s + " " + status["last_sync"] + " " + status["ref"] + " " + status["user"]
59
+ rescue => ex
60
+ @env.ui.warn("Error downloading status for #{machine.name}.")
61
+ @env.ui.warn(ex.message)
62
+ return machine.name.to_s + " Status unavailable."
63
+ ensure
64
+ super_delete(local) if File.exist?(local)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,61 @@
1
+ require "json"
2
+
3
+ module VagrantPlugins
4
+ module Orchestrate
5
+ class RepoStatus
6
+ attr_reader :last_sync
7
+
8
+ def initialize
9
+ @last_sync = Time.now.utc # Managed servers could be in different timezones
10
+ end
11
+
12
+ def ref
13
+ # Env vars are here only for testing, since vagrant-spec is executed from
14
+ # a temp directory and can't use git to get repository information
15
+ @ref ||= ENV["VAGRANT_ORCHESTRATE_STATUS_TEST_REF"]
16
+ @ref ||= `git log --pretty=format:'%H' --abbrev-commit -1`
17
+ @ref
18
+ end
19
+
20
+ def remote_origin_url
21
+ @remote_origin_url ||= ENV["VAGRANT_ORCHESTRATE_STATUS_TEST_REMOTE_ORIGIN_URL"]
22
+ @remote_origin_url ||= `git config --get remote.origin.url`.chomp
23
+ @remote_origin_url
24
+ end
25
+
26
+ def repo
27
+ @repo ||= File.basename(remote_origin_url, ".git")
28
+ @repo
29
+ end
30
+
31
+ def user
32
+ user = ENV["USER"] || ENV["USERNAME"] || "unknown"
33
+ user = ENV["USERDOMAIN"] + "\\" + user if ENV["USERDOMAIN"]
34
+
35
+ @user ||= user
36
+ @user
37
+ end
38
+
39
+ def to_json
40
+ contents = {
41
+ repo: repo,
42
+ remote_url: remote_origin_url,
43
+ ref: ref,
44
+ user: user,
45
+ last_sync: last_sync
46
+ }
47
+ JSON.pretty_generate(contents)
48
+ end
49
+
50
+ # The path to where this should be stored on a remote machine, inclusive
51
+ # of the file name.
52
+ def remote_path(communicator)
53
+ if communicator == :winrm
54
+ File.join("c:", "programdata", "vagrant_orchestrate", repo)
55
+ else
56
+ File.join("/var", "state", "vagrant_orchestrate", repo)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module Orchestrate
3
- VERSION = "0.4.7"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
data/lib/vms.save ADDED
@@ -0,0 +1,24 @@
1
+ # R&D work that may be used in a future version, but can be ignored for now.
2
+ module ManagedServers
3
+ module Action
4
+ include Vagrant::Action::Builtin
5
+ def self.action_push
6
+ Vagrant::Action::Builder.new.tap do |b|
7
+ b.use HandleBox
8
+ b.use ConfigValidate
9
+ b.use WarnNetworks
10
+ b.use Call, IsLinked do |env, b2|
11
+ if env[:result]
12
+ b2.use MessageAlreadyLinked
13
+ next
14
+ end
15
+
16
+ b2.use LinkServer
17
+ end
18
+ b.use Provision
19
+ b.use SyncFolders
20
+ b.use UnlinkServer
21
+ end
22
+ end
23
+ end
24
+ end
data/mytestfile ADDED
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-orchestrate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Baldauf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-15 00:00:00.000000000 Z
11
+ date: 2015-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -77,6 +77,7 @@ files:
77
77
  - .rspec
78
78
  - .rubocop.yml
79
79
  - .travis.yml
80
+ - CHANGELOG.md
80
81
  - Gemfile
81
82
  - LICENSE
82
83
  - README.md
@@ -84,22 +85,30 @@ files:
84
85
  - Vagrantfile
85
86
  - acceptance/command/prompt_spec.rb
86
87
  - acceptance/command/push_spec.rb
88
+ - acceptance/command/status_spec.rb
87
89
  - acceptance/support-skeletons/basic/Vagrantfile
88
90
  - acceptance/support-skeletons/basic/dummy.box
89
91
  - acceptance/support-skeletons/prompt/Vagrantfile
90
92
  - acceptance/support-skeletons/prompt/dummy.box
93
+ - docs/environments.md
94
+ - docs/puppet.md
91
95
  - docs/strategy.md
92
96
  - dummy.box
93
97
  - lib/vagrant-orchestrate.rb
94
98
  - lib/vagrant-orchestrate/action/filtermanaged.rb
95
99
  - lib/vagrant-orchestrate/action/setcredentials.rb
100
+ - lib/vagrant-orchestrate/command/command_mixins.rb
96
101
  - lib/vagrant-orchestrate/command/init.rb
97
102
  - lib/vagrant-orchestrate/command/push.rb
98
103
  - lib/vagrant-orchestrate/command/root.rb
104
+ - lib/vagrant-orchestrate/command/status.rb
99
105
  - lib/vagrant-orchestrate/config.rb
100
106
  - lib/vagrant-orchestrate/plugin.rb
107
+ - lib/vagrant-orchestrate/repo_status.rb
101
108
  - lib/vagrant-orchestrate/version.rb
109
+ - lib/vms.save
102
110
  - locales/en.yml
111
+ - mytestfile
103
112
  - spec/spec_helper.rb
104
113
  - spec/vagrant-orchestrate/command/init_spec.rb
105
114
  - spec/vagrant-orchestrate/command/root_spec.rb