vagrant-orchestrate 0.4.7 → 0.5.0

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