standup 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -4,15 +4,16 @@ Standup is an application deployment and infrastructure management tool for Rail
4
4
 
5
5
  ## Basic usage
6
6
 
7
- 0. Add `gem 'standup'` into Gemfile and install it via `> bundle install`
8
- 0. `> standup init`
9
- 0. Write actual settings in generated `config/standup.yml`
10
- 0. `> standup setup`
11
- 0. `> standup status`
7
+ 0. `gem install standup`
8
+ 0. `cd path/to/your/rails/project`
9
+ 0. `standup init`
10
+ 0. Fill in actual settings in generated file `config/standup.yml`
11
+ 0. `standup setup`
12
+ 0. `standup status`
12
13
 
13
14
  ## Tweaking default scripts
14
15
 
15
- 0. `> standup localize SCRIPT=<script_name>`
16
+ 0. `standup localize <script_name>`
16
17
  0. Script file `config/standup/<script_name>.rb` will be copied from gem.
17
18
  0. Script's own files, like configs etc. under `config/standup/<script_name>`, if any, will be copied from gem too.
18
19
  0. You can edit them and standup will use them instead of default.
@@ -20,7 +21,7 @@ Standup is an application deployment and infrastructure management tool for Rail
20
21
 
21
22
  ## Creating new scripts
22
23
 
23
- 0. `> standup generate SCRIPT=<script_name>`
24
+ 0. `standup generate <script_name>`
24
25
  0. Script file `config/standup/<script_name>.rb` will be created with empty script stub.
25
26
  0. Edit it as you want, it's now available for standup.
26
27
 
@@ -43,18 +44,12 @@ For example, if you want to add `rescue` to your configuration, you need to:
43
44
 
44
45
  ## To do
45
46
 
46
- - Redesign node:script running concept:
47
- `setup` script need to be run for each node
48
- `shell` script is meant to be run for one specific node
49
- `init` script does not relate to any node at all.
50
-
51
- - If there is more than one node in standup.yml, require node name(s) or `all` explicitly set:
52
- `standup shell web`
53
- `standup update db,web`
54
- `standup setup all`
47
+ - `standup -v`
55
48
 
56
49
  - **?** Script sequences: rework default script as script sequence
57
50
 
51
+ - ERB processing for script files
52
+
58
53
  ## Copyright
59
54
 
60
55
  Copyright (c) 2010 Ilia Ablamonov, Cloud Castle Inc.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.3.4
data/bin/standup CHANGED
@@ -8,14 +8,14 @@ opt_parser = Trollop::Parser.new do
8
8
  banner 'Standup is an application deployment and infrastructure management tool for Rails and Amazon EC2.'
9
9
  banner ''
10
10
  banner 'Usage:'
11
- banner ' standup script [options]'
11
+ banner ' standup [options] <script> [script arguments]'
12
12
  banner ''
13
- banner 'where script is one of the following:'
13
+ banner 'where <script> is one of the following:'
14
14
  banner ''
15
15
 
16
16
  offset = Standup.scripts.keys.map(&:length).max + 2
17
- Standup.scripts.each do |name, script|
18
- banner "#{"%-#{offset}s" % name} #{script.description}"
17
+ Standup.scripts.keys.sort.each do |name|
18
+ banner "#{"%-#{offset}s" % name} #{Standup.scripts[name].description}"
19
19
  end
20
20
 
21
21
  banner ''
@@ -33,9 +33,10 @@ end
33
33
  exit if ARGV.empty?
34
34
 
35
35
  script_name = ARGV.shift
36
+ script = Standup.scripts[script_name]
36
37
 
37
- if Standup.scripts.include? script_name
38
- Standup.nodes.each {|node| node.run_script script_name}
38
+ if script
39
+ script.execute
39
40
  else
40
41
  opt_parser.die "unknown script #{script_name}", nil
41
42
  end
data/lib/standup.rb CHANGED
@@ -10,6 +10,7 @@ require 'standup/settings'
10
10
  require 'standup/ec2'
11
11
  require 'standup/remoting'
12
12
  require 'standup/scripts/base'
13
+ require 'standup/scripts/node'
13
14
  require 'standup/node'
14
15
 
15
16
  module Standup
@@ -44,9 +45,17 @@ module Standup
44
45
  @@scripts
45
46
  end
46
47
 
47
- def self.script &block
48
+ def self.script type = :node, &block
48
49
  name = block.__file__.match(/([^\/]*)\.rb$/)[1]
49
- script_class = Class.new(Standup::Scripts::Base, &block)
50
+ superclass = case type
51
+ when :node
52
+ Scripts::Node
53
+ when :local
54
+ Scripts::Base
55
+ else
56
+ raise ArgumentError, "Unknown script type #{type}"
57
+ end
58
+ script_class = Class.new(superclass, &block)
50
59
  script_class.name = name
51
60
  Standup::Scripts.const_set name.camelize, script_class
52
61
  scripts[name] = script_class
data/lib/standup/node.rb CHANGED
@@ -13,7 +13,8 @@ module Standup
13
13
  attr_reader :name, :scripts
14
14
 
15
15
  def run_script script_name
16
- scripts[script_name].titled_run
16
+ scripts[script_name].put_title
17
+ scripts[script_name].run
17
18
  close_remoting
18
19
  end
19
20
 
@@ -3,14 +3,9 @@ require 'active_support/hash_with_indifferent_access'
3
3
  module Standup
4
4
  module Scripts
5
5
  class Base
6
- def initialize node
7
- @node = node
8
- @remoting = nil
9
- @params = if node.params[name].is_a? Hash
10
- ActiveSupport::HashWithIndifferentAccess.new self.class.default_params.merge(node.params[name])
11
- else
12
- node.params[name] || self.class.default_params
13
- end
6
+ def initialize *args
7
+ merge_params self.class.default_params
8
+ merge_params Settings[name]
14
9
  end
15
10
 
16
11
  class_attribute :name
@@ -20,21 +15,14 @@ module Standup
20
15
 
21
16
  class_attribute :description
22
17
 
23
- delegate :instance, :open_port, :open_ports, :remoting, :scripts,
24
- :to => :@node
25
-
26
- delegate :download, :upload, :remote_update, :exec, :sudo, :in_dir, :in_temp_dir, :file_exists?, :install_package, :install_packages, :install_gem,
27
- :to => :remoting
28
-
29
- attr_accessor :node, :params
18
+ attr_accessor :params
30
19
 
31
20
  def name
32
21
  self.class.name
33
22
  end
34
23
 
35
- def titled_run
36
- bright_p "#{@node.name}:#{name}", HighLine::CYAN
37
- run
24
+ def put_title
25
+ bright_p name, HighLine::CYAN
38
26
  end
39
27
 
40
28
  def script_file filename
@@ -46,7 +34,55 @@ module Standup
46
34
  nil
47
35
  end
48
36
 
49
- def run; end
37
+ def self.execute
38
+ new.run
39
+ end
40
+
41
+ protected
42
+
43
+ def merge_params param_overrides
44
+ @params = if param_overrides.is_a? Hash
45
+ ActiveSupport::HashWithIndifferentAccess.new((@params || {}).merge(param_overrides))
46
+ else
47
+ param_overrides || @params
48
+ end
49
+ end
50
+
51
+ def argument arg_pattern, arg_name = arg_pattern, variants = nil
52
+ self.class.argument arg_pattern, arg_name, variants
53
+ end
54
+
55
+ def self.argument arg_pattern, arg_name = arg_pattern, variants = nil
56
+ script_description = description
57
+ script_name = name
58
+ opt_parser = Trollop::Parser.new do
59
+ banner script_description
60
+ banner ''
61
+ banner 'Usage:'
62
+ banner " standup #{script_name} [options] #{arg_pattern}"
63
+ banner ''
64
+ if variants
65
+ banner "where <#{arg_name}> is one of the following:"
66
+ banner ''
67
+ variants.each { |v| banner v }
68
+ banner ''
69
+ end
70
+ banner "and [options] are:"
71
+ banner ''
72
+
73
+ stop_on_unknown
74
+ end
75
+ Trollop::with_standard_exception_handling opt_parser do
76
+ opt_parser.parse ARGV
77
+ raise Trollop::HelpNeeded if ARGV.empty?
78
+ end
79
+
80
+ result = ARGV.shift
81
+ if variants && !variants.include?(result)
82
+ opt_parser.die "unknown #{arg_name} #{result}", nil
83
+ end
84
+ result
85
+ end
50
86
  end
51
87
  end
52
88
  end
@@ -0,0 +1,46 @@
1
+ module Standup
2
+ module Scripts
3
+ class Node < Base
4
+ def initialize node
5
+ super
6
+ merge_params node.params[name]
7
+ @node = node
8
+ @remoting = nil
9
+ end
10
+
11
+ delegate :instance, :open_port, :open_ports, :remoting, :scripts,
12
+ :to => :@node
13
+
14
+ delegate :download, :upload, :remote_update, :exec, :sudo, :in_dir, :in_temp_dir, :file_exists?, :install_package, :install_packages, :install_gem,
15
+ :to => :remoting
16
+
17
+ attr_accessor :node
18
+
19
+ def put_title
20
+ bright_p "#{@node.name}:#{name}", HighLine::CYAN
21
+ end
22
+
23
+ def self.execute
24
+ all_nodes = Settings.nodes.keys
25
+
26
+ nodes = if all_nodes.length > 1
27
+ node_args = argument('<node[,node]>', 'node', ['all'] + all_nodes).strip.split(',')
28
+
29
+ if node_args.include? 'all'
30
+ all_nodes
31
+ else
32
+ node_args
33
+ end
34
+ else
35
+ all_nodes
36
+ end
37
+
38
+ run_on_nodes nodes
39
+ end
40
+
41
+ def self.run_on_nodes nodes
42
+ nodes.each {|node| Standup::Node.new(node).run_script name}
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :local do
2
2
  self.description = 'Request new Elasics IP to use in node config'
3
3
 
4
4
  def run
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  self.description = 'Run remote Rails application console'
3
3
 
4
4
  def run
data/scripts/basics.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  def run
3
3
  sudo 'apt-get -qq update'
4
4
  install_packages 'build-essential libreadline5-dev mc'
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  def run
3
3
  scripts.monit.add_watch script_file('delayed_job_monit.conf')
4
4
  end
data/scripts/ec2.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  def run
3
3
  ensure_security_group
4
4
 
data/scripts/generate.rb CHANGED
@@ -1,14 +1,11 @@
1
- Standup.script do
1
+ Standup.script :local do
2
2
  self.description = 'Generate script'
3
3
 
4
4
  def run
5
- unless ENV['SCRIPT']
6
- bright_p "Specify script name with SCRIPT=name argument"
7
- return
8
- end
5
+ script_name = argument '<script name>'
9
6
 
10
7
  FileUtils.mkdir_p(Standup.local_scripts_path)
11
8
  FileUtils.copy script_file('script.rb'),
12
- File.expand_path("#{ENV['SCRIPT']}.rb", Standup.local_scripts_path)
9
+ File.expand_path("#{script_name}.rb", Standup.local_scripts_path)
13
10
  end
14
11
  end
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  self.description = 'Put description here'
3
3
 
4
4
  def run
data/scripts/init.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :local do
2
2
  self.description = 'Generate config file'
3
3
 
4
4
  def run
data/scripts/localize.rb CHANGED
@@ -1,14 +1,12 @@
1
- Standup.script do
1
+ Standup.script :local do
2
2
  self.description = 'Put specified script into project configuration'
3
3
 
4
4
  def run
5
- unless ENV['SCRIPT']
6
- bright_p "Specify script name with SCRIPT=name argument"
7
- return
8
- end
5
+ variants = Standup.scripts.keys.sort.select{|script_name| File.exists? File.expand_path("#{script_name}.rb", Standup.gem_scripts_path)}
6
+ script_name = argument '<script name>', 'script name', variants
9
7
 
10
8
  FileUtils.mkdir_p(Standup.local_scripts_path)
11
- [ENV['SCRIPT'], "#{ENV['SCRIPT']}.rb"].each do |path|
9
+ [script_name, "#{script_name}.rb"].each do |path|
12
10
  path = File.expand_path(path, Standup.gem_scripts_path)
13
11
  if File.exists? path
14
12
  FileUtils.cp_r path, Standup.local_scripts_path
data/scripts/monit.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  def run
3
3
  install_package 'monit'
4
4
 
data/scripts/passenger.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  def run
3
3
  scripts.ec2.open_port 80
4
4
 
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  def run
3
3
  install_package 'postgresql-8.4 libpq-dev'
4
4
 
data/scripts/ruby.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  def run
3
3
  return if exec('ruby -v') =~ /Ruby Enterprise Edition 2010.02/
4
4
 
data/scripts/setup.rb CHANGED
@@ -1,11 +1,12 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  self.description = 'Do all setup from scratch and/or incrementally'
3
3
 
4
4
  self.default_params = 'ec2 basics monit ruby postgresql passenger webapp update'
5
5
 
6
6
  def run
7
7
  params.strip.split.each do |name|
8
- scripts[name].titled_run
8
+ scripts[name].put_title
9
+ scripts[name].run
9
10
  end
10
11
  end
11
12
 
data/scripts/shell.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  self.description = 'Run remote shell (e.g. bash)'
3
3
 
4
4
  def run
@@ -6,6 +6,7 @@ Standup.script do
6
6
  end
7
7
 
8
8
  def make_shell shell_command = ''
9
+ return unless instance
9
10
  command = "#{node.ssh_string} -t '#{shell_command}'"
10
11
  bright_p command
11
12
  Kernel.exec command
data/scripts/status.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  self.description = 'Check nodes status and display useful info'
3
3
 
4
4
  def run
@@ -6,10 +6,13 @@ Standup.script do
6
6
  puts "Node: #{node.name}"
7
7
  puts "State: #{instance.state}"
8
8
  puts "IP: #{instance.external_ip}"
9
- puts "SSH String: #{node.ssh_string}"
10
9
  else
11
10
  puts "Node: #{node.name}"
12
11
  puts "State: not running"
13
12
  end
14
13
  end
14
+
15
+ def self.execute
16
+ run_on_nodes Standup::Settings.nodes.keys
17
+ end
15
18
  end
data/scripts/terminate.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  self.description = 'Terminate nodes'
3
3
 
4
4
  def run
data/scripts/update.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  self.description = 'Update working application'
3
3
 
4
4
  def run
data/scripts/watchlog.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  self.description = 'Watch remote Rails application log'
3
3
 
4
4
  def run
data/scripts/webapp.rb CHANGED
@@ -1,4 +1,4 @@
1
- Standup.script do
1
+ Standup.script :node do
2
2
  self.default_params = {
3
3
  :rails_env => 'production'
4
4
  }
data/standup.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{standup}
8
- s.version = "0.3.3"
8
+ s.version = "0.3.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ilia Ablamonov", "Cloud Castle Inc."]
12
- s.date = %q{2010-11-10}
12
+ s.date = %q{2010-11-11}
13
13
  s.default_executable = %q{standup}
14
14
  s.email = %q{ilia@flamefork.ru}
15
15
  s.executables = ["standup"]
@@ -35,6 +35,7 @@ Gem::Specification.new do |s|
35
35
  "lib/standup/node.rb",
36
36
  "lib/standup/remoting.rb",
37
37
  "lib/standup/scripts/base.rb",
38
+ "lib/standup/scripts/node.rb",
38
39
  "lib/standup/settings.rb",
39
40
  "scripts/allocate_ip.rb",
40
41
  "scripts/appconsole.rb",
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: standup
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 3
10
- version: 0.3.3
9
+ - 4
10
+ version: 0.3.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ilia Ablamonov
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-11-10 00:00:00 +03:00
19
+ date: 2010-11-11 00:00:00 +03:00
20
20
  default_executable: standup
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -152,6 +152,7 @@ files:
152
152
  - lib/standup/node.rb
153
153
  - lib/standup/remoting.rb
154
154
  - lib/standup/scripts/base.rb
155
+ - lib/standup/scripts/node.rb
155
156
  - lib/standup/settings.rb
156
157
  - scripts/allocate_ip.rb
157
158
  - scripts/appconsole.rb