marionetta 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Marionetta
2
2
 
3
- Marionetta is a ruby library for executing commands on one
4
- or more remote machines via SSH.
3
+ [Marionetta][marionetta] is a ruby library for executing
4
+ commands on one or more remote machines via SSH.
5
5
 
6
6
  It provides puppet provisioning without the need for a puppet
7
7
  master and can also deploy your application code (with
@@ -22,6 +22,21 @@ source 'http://rubygems.org'
22
22
  gem 'marionetta'
23
23
  ```
24
24
 
25
+ [marionetta]: http://drpheltright.github.com/marionetta/
26
+
27
+ ## Documentation
28
+
29
+ Marionetta has [annotated source][docs] that provides the
30
+ bulk of documentation for Marionetta. Hopefully you'll find
31
+ the annotations informative on *how to use* this library. If
32
+ you feel they could be improved please create an issue on
33
+ GitHub.
34
+
35
+ If you prefer looking at the code, check it out on [github][github].
36
+
37
+ [docs]: http://drpheltright.github.com/marionetta/docs/marionetta.html
38
+ [github]: http://github.com/DrPheltRight/marionetta/
39
+
25
40
  ## Using Marionetta in your Rakefile
26
41
 
27
42
  Marionetta provides an easy mechanism to generate rake tasks
@@ -153,6 +168,12 @@ staging.manipulate_each_server(:deployer, :rollback)
153
168
 
154
169
  Luke Morton a.k.a. DrPheltRight
155
170
 
171
+ ## Collaborating
172
+
173
+ Create an issue and send a pull request if you get any bright
174
+ ideas or have a fix. Feel free to create an issue and not send
175
+ one too, feedback is always welcome.
176
+
156
177
  ## License
157
178
 
158
- MIT
179
+ Licensed under MIT by Luke Morton, 2012.
@@ -27,9 +27,15 @@ module Marionetta
27
27
 
28
28
  ### Local execution
29
29
 
30
- # Local commands are executed with `.system()`. You can
31
- # optionally pass in a block which receives `stdout` and
32
- # `stderr` as arguments:
30
+ # Local commands are executed with `.system()`. We use
31
+ # `Open4::popen4` to capture the output of the command run
32
+ # neatly.
33
+ #
34
+ # The command run is logged as info, output as debug and
35
+ # any exceptions thrown are sent as fatal.
36
+ #
37
+ # You can optionally pass in a block which receives
38
+ # `stdout` and `stderr` as arguments:
33
39
  #
34
40
  # cmd.system('ls ~') do |out, err|
35
41
  # puts out
@@ -57,6 +63,28 @@ module Marionetta
57
63
  return status.exitstatus == 0
58
64
  end
59
65
 
66
+ # Create an archive of a local directory, optionally
67
+ # saving it to a directory or file path.
68
+ #
69
+ def archive(directory, save_to = nil)
70
+ if save_to.nil?
71
+ save_to = "#{directory}.#{server[:archive][:ext]}"
72
+ elsif File.directory?(save_to)
73
+ dirname = File.basename(directory)
74
+ save_to = "#{save_to}/#{dirname}.#{server[:archive][:ext]}"
75
+ end
76
+
77
+ archive_cmd = [
78
+ server[:archive][:command],
79
+ server[:archive][:flags],
80
+ ['-f', save_to],
81
+ ['-C', File.dirname(directory)],
82
+ File.basename(directory),
83
+ ]
84
+
85
+ system(*archive_cmd.flatten)
86
+ end
87
+
60
88
  # The last command run by `.system()` is accessible via
61
89
  # the `.last` attribute.
62
90
  #
@@ -72,7 +100,7 @@ module Marionetta
72
100
  # A block can be called against this method just like
73
101
  # `.system()` in order to get `stdout` and `stderr`.
74
102
  #
75
- # An example:
103
+ # Example:
76
104
  #
77
105
  # server = Marionetta.default_server
78
106
  # server[:hostname] = 'example.com'
@@ -96,25 +124,9 @@ module Marionetta
96
124
  system(*ssh_cmd.flatten, &block)
97
125
  end
98
126
 
99
- def archive(directory, save_to = nil)
100
- if save_to.nil?
101
- save_to = "#{directory}.#{server[:archive][:ext]}"
102
- elsif File.directory?(save_to)
103
- dirname = File.basename(directory)
104
- save_to = "#{save_to}/#{dirname}.#{server[:archive][:ext]}"
105
- end
106
-
107
- archive_cmd = [
108
- server[:archive][:command],
109
- server[:archive][:flags],
110
- ['-f', save_to],
111
- ['-C', File.dirname(directory)],
112
- File.basename(directory),
113
- ]
114
-
115
- system(*archive_cmd.flatten)
116
- end
117
-
127
+ # Extract an archive, optionally to a specified directory
128
+ # on a remote machine.
129
+ #
118
130
  def ssh_extract(archive_path, save_to = File.dirname(archive_path))
119
131
  cmds = [
120
132
  "mkdir -p #{save_to}",
@@ -132,6 +144,15 @@ module Marionetta
132
144
  ssh(cmds.join(' && '))
133
145
  end
134
146
 
147
+ # Using the rsync command copy one file system location to
148
+ # another. These may be both local or remote, or a mixture
149
+ # of the two.
150
+ #
151
+ # Example:
152
+ #
153
+ # rsync('/var/www/logs', '/var/backups/www/logs')
154
+ # rsync('/var/www/logs', 'ubuntu@example.com:/var/backups/www/logs')
155
+ #
135
156
  def rsync(from, to)
136
157
  rsync_cmd = [server[:rsync][:command]]
137
158
 
@@ -144,10 +165,18 @@ module Marionetta
144
165
  system(*rsync_cmd.flatten)
145
166
  end
146
167
 
168
+ # Short hand for grabbing a file from `:hostname` saving
169
+ # to the same location on the local machine unless a path
170
+ # is specified.
171
+ #
147
172
  def get(file_path, save_to = File.dirname(file_path))
148
173
  rsync("#{server[:hostname]}:#{file_path}", save_to)
149
174
  end
150
175
 
176
+ # Short hand for putting a file to `:hostname` from the
177
+ # local machine to the same location on the remote
178
+ # machine unless a path is specified.
179
+ #
151
180
  def put(file_path, save_to = File.dirname(file_path))
152
181
  rsync(file_path, "#{server[:hostname]}:#{save_to}")
153
182
  end
@@ -1,21 +1,40 @@
1
+ # `Group` represents a collection of `server` hashes and
2
+ # provides `.each_server()` and `.manipulate_each_server` as
3
+ # isolated interation methods.
4
+ #
5
+ # You can also nest groups within other groups so that
6
+ # multiple groups can be operated on at once.
7
+ #
8
+ # The external requirement for this file is `celluloid` so we
9
+ # can iterate over `@servers` in parallel.
10
+ #
1
11
  require 'marionetta'
2
12
  require 'marionetta/manipulators'
3
13
  require 'celluloid'
4
14
 
5
15
  module Marionetta
6
16
  class Group
7
- attr_reader :name
8
17
 
18
+ # Group name is currently optional.
19
+ #
9
20
  def initialize(name = nil)
10
21
  @name = name
11
22
  @groups = []
12
23
  @servers = []
13
24
  end
14
25
 
26
+ # The name of the group.
27
+ #
28
+ attr_reader :name
29
+
30
+ # Nest a group using `.add_group()`.
31
+ #
15
32
  def add_group(group)
16
33
  @groups << group
17
34
  end
18
35
 
36
+ # Get all descending groups contained within this group.
37
+ #
19
38
  def groups()
20
39
  groups = @groups
21
40
 
@@ -26,12 +45,25 @@ module Marionetta
26
45
  return groups
27
46
  end
28
47
 
48
+ # Add a `server` hash or build on the default server in a
49
+ # block.
50
+ #
51
+ # Example:
52
+ #
53
+ # staging = Marionetta::Group.new(:staging)
54
+ # staging.add_server(:hostname => 'ubuntu@example.com')
55
+ # staging.add_server do |s|
56
+ # s[:hostname] = 'ubuntu@example.com'
57
+ # end
58
+ #
29
59
  def add_server(server = nil)
30
60
  server ||= Marionetta.default_server
31
61
  yield server if block_given?
32
62
  @servers << server
33
63
  end
34
64
 
65
+ # Get servers in this group and all descendant groups.
66
+ #
35
67
  def servers()
36
68
  servers = @servers
37
69
 
@@ -42,6 +74,16 @@ module Marionetta
42
74
  return servers
43
75
  end
44
76
 
77
+ # Iterate over each `server` definition (including nested
78
+ # servers) in parallel by passing a block.
79
+ #
80
+ # each_server do |s|
81
+ # cmd = Marionetta::CommandRunner.new(s)
82
+ # cmd.ssh('whoami') do |out|
83
+ # puts out.read
84
+ # end
85
+ # end
86
+ #
45
87
  def each_server()
46
88
  futures = []
47
89
 
@@ -62,6 +104,15 @@ module Marionetta
62
104
  return return_values
63
105
  end
64
106
 
107
+ # Manipulate each server by passing a manipulator key as
108
+ # registered with `Manipulators` and a method name.
109
+ #
110
+ # If manipulator cannot be run on a server definition then
111
+ # a warn message will be logged.
112
+ #
113
+ # If block passed in then the server and return value for
114
+ # each server will be passed in when complete.
115
+ #
65
116
  def manipulate_each_server(manipulator_name, method_name)
66
117
  each_server do |s|
67
118
  manipulator = Manipulators[manipulator_name].new(s)
@@ -144,7 +144,7 @@ module Marionetta
144
144
  puppet_cmd = ['sudo puppet apply']
145
145
 
146
146
  if server[:puppet].has_key?(:modules)
147
- puppet_cmd << '--modulepath=/tmp/puppet/modules'
147
+ puppet_cmd << "--modulepath=#{puppet_tmp}/modules"
148
148
  end
149
149
 
150
150
  puppet_cmd << 'manifest.pp'
@@ -1,9 +1,25 @@
1
+ # `Manipulators` is a container for registering manipulators.
2
+ #
3
+ # The interface of a manipulator is:
4
+ #
5
+ # self.tasks() an array of methods to expose via
6
+ # RakeHelpers *optional*
7
+ #
8
+ # initialize(server) *required*
9
+ # can?() *required*
10
+ #
1
11
  module Marionetta
2
12
  module Manipulators
13
+
14
+ # We automatically require the manipulators packaged with
15
+ # this library. *Is this a good idea?*
16
+ #
3
17
  require_relative 'manipulators/deployer'
4
18
  require_relative 'manipulators/debloyer'
5
19
  require_relative 'manipulators/puppet_manipulator'
6
20
 
21
+ # A hash of all the manipulators.
22
+ #
7
23
  def self.all()
8
24
  {
9
25
  :deployer => Deployer,
@@ -12,6 +28,8 @@ module Marionetta
12
28
  }
13
29
  end
14
30
 
31
+ # Get a manipulator.
32
+ #
15
33
  def self.[](key)
16
34
  all[key]
17
35
  end
@@ -1,3 +1,9 @@
1
+ # `RakeHelper` is provided for those of you who wish to use
2
+ # Marionetta in your `Rakefile`.
3
+ #
4
+ # One method is provided to expose tasks of a specified group,
5
+ # `.install_group_tasks(group)`.
6
+ #
1
7
  require 'marionetta'
2
8
  require 'marionetta/manipulators'
3
9
  require 'rake'
data/lib/marionetta.rb CHANGED
@@ -1,5 +1,5 @@
1
- # Marionetta is a ruby library for executing commands on one
2
- # or more remote machines via SSH.
1
+ # [Marionetta][homepage] is a ruby library for executing
2
+ # commands on one or more remote machines via SSH.
3
3
  #
4
4
  # It provides puppet provisioning without the need for a
5
5
  # puppet master and can also deploy your application code
@@ -21,12 +21,13 @@
21
21
  # where you can report issues and send your well thought out
22
22
  # pull requests.
23
23
  #
24
+ # [homepage]: http://drpheltright.github.com/marionetta/
25
+ # [github]: https://github.com/DrPheltRight/marionetta/
24
26
  # [author]: http://lukemorton.co.uk
25
- # [github]: https://github.com/DrPheltRight/marionetta
26
27
  #
27
28
  module Marionetta
28
29
 
29
- VERSION = '0.4.1'
30
+ VERSION = '0.4.2'
30
31
 
31
32
  ### Defining Servers
32
33
 
data/marionetta.gemspec CHANGED
@@ -3,10 +3,14 @@ require File.dirname(__FILE__)+'/lib/marionetta'
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "marionetta"
5
5
  s.version = Marionetta::VERSION
6
+
6
7
  s.homepage = 'https://github.com/DrPheltRight/marionetta'
8
+
7
9
  s.authors = ["Luke Morton"]
8
10
  s.email = ["lukemorton.dev@gmail.com"]
11
+
9
12
  s.summary = "Provision using puppet and deploy your servers over SSH."
13
+
10
14
  s.description = "Marionetta is a ruby library for executing commands on one
11
15
  or more remote machines via SSH. It provides puppet
12
16
  provisioning without the need for a puppet master and can
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marionetta
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-21 00:00:00.000000000 Z
12
+ date: 2012-09-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: open4