orca 0.3.0 → 0.3.1

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.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- orca (0.3.0)
4
+ orca (0.3.1)
5
5
  colored
6
6
  net-sftp
7
7
  net-ssh
data/README.md CHANGED
@@ -87,6 +87,7 @@ Options, all commands support the following optional parameters...
87
87
  --sequential | dont attempt to run commands accross multiple nodes in parrallel
88
88
  --throw | throw a stack trace rather than pretty printing errors
89
89
  --file | path to the orca.rb file to load, defaults to ./orca/orca.rb
90
+ --verbose | print all SSH output, useful for debugging but can be rather long
90
91
  --skip-dependancies | Don't validate and run dependancies, only the pkg in question
91
92
 
92
93
 
@@ -123,6 +124,7 @@ Orca packages are written in a Ruby based DSL. It's really simple to learn in le
123
124
  end
124
125
  end
125
126
 
127
+ A more complete WIP example can be found in this gist... https://gist.github.com/andykent/5814997
126
128
 
127
129
 
128
130
  Extensions
@@ -3,6 +3,12 @@ require 'colored'
3
3
  require 'thor'
4
4
 
5
5
  module Orca
6
+ def verbose(val=nil)
7
+ @verbose = val unless val.nil?
8
+ @verbose || false
9
+ end
10
+ module_function :verbose
11
+
6
12
  def root
7
13
  File.dirname(ENV['ORCA_FILE'])
8
14
  end
@@ -7,6 +7,7 @@ class Orca::Cli < Thor
7
7
  class_option :file, :banner => 'ORCA_FILE', :desc => "path to the orca.rb file to load, defaults to ./orca/orca.rb"
8
8
  class_option :throw, :type => :boolean, :desc => "Don't pretty print errors, raise with a stack trace."
9
9
  class_option :sequential, :type => :boolean, :desc => "Don't run tasks in parrallel across nodes."
10
+ class_option :verbose, :type => :boolean, :desc => "print all SSH output, useful for debugging"
10
11
  class_option :'skip-dependancies', :type => :boolean, :desc => "Don't validate and run dependancies."
11
12
 
12
13
  desc "apply PACKAGE_NAME GROUP_OR_NODE_NAME", "apply the given package onto the given named group"
@@ -37,6 +38,7 @@ class Orca::Cli < Thor
37
38
  private
38
39
 
39
40
  def run_command(package, group, cmd)
41
+ Orca.verbose(options[:verbose] || false)
40
42
  begin
41
43
  suite = Orca::Suite.new(options)
42
44
  suite.load_file(orca_file)
@@ -47,6 +49,8 @@ class Orca::Cli < Thor
47
49
  else
48
50
  puts "!!! ERROR !!! [#{e.class.name}] #{e.message}".red.bold
49
51
  end
52
+ ensure
53
+ suite.cleanup
50
54
  end
51
55
  end
52
56
 
@@ -9,16 +9,16 @@ class Orca::ExecutionContext
9
9
  instance_eval(&blk)
10
10
  end
11
11
 
12
- def run(cmd)
13
- @node.execute(cmd)
12
+ def run(cmd, opts={})
13
+ @node.execute(cmd, opts)
14
14
  end
15
15
 
16
16
  def log(msg)
17
17
  @node.log('log', msg)
18
18
  end
19
19
 
20
- def sudo(cmd)
21
- @node.sudo(cmd)
20
+ def sudo(cmd, opts={})
21
+ @node.sudo(cmd, opts)
22
22
  end
23
23
 
24
24
  def upload(from, to)
@@ -1,25 +1,38 @@
1
1
  Orca.extension :apt do
2
+
3
+ # supports three formats
4
+ # apt_package 'git-core' - create a package 'git-core' that installs 'git-core'
5
+ # apt_package 'git', 'git-core' - creates a package 'git' that installs 'git-core'
6
+ # apt_package 'git', package:'git-core', version:'1.7.2' - creates a package 'git' that installs 'git-core=1.7.2'
2
7
  module_function
3
- def apt_package(pkg_name, apt_name=pkg_name, &blk)
8
+ def apt_package(pkg_name, opts=pkg_name, &blk)
9
+ apt_name = opts
10
+ version = nil
11
+ if opts.is_a? Hash
12
+ version = opts[:version]
13
+ apt_name = opts[:package] || pkg_name
14
+ end
4
15
  package pkg_name do
5
- depends_on 'apt'
6
- validate { trigger 'apt:exists', apt_name }
7
- apply do
8
- trigger 'apt:update'
9
- trigger 'apt:install', apt_name
16
+ depends_on('apt')
17
+ validate { trigger('apt:exists', apt_name, version) }
18
+ apply do
19
+ trigger('apt:update')
20
+ trigger('apt:install', apt_name, version)
10
21
  end
11
- remove { trigger 'apt:remove', apt_name }
22
+ remove { trigger('apt:remove', apt_name, version) }
12
23
  instance_eval(&blk) if blk
13
24
  end
14
25
  end
15
26
 
16
27
  package 'apt' do
17
- action 'install' do |package_name|
18
- sudo "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq #{package_name}"
28
+ action 'install' do |package_name, version=nil|
29
+ package_description = [package_name, version].compact.join('=')
30
+ sudo "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq #{package_description}"
19
31
  end
20
32
 
21
- action 'remove' do |package_name|
22
- sudo "DEBIAN_FRONTEND=noninteractive apt-get remove -y -qq #{package_name}"
33
+ action 'remove' do |package_name, version=nil|
34
+ package_description = [package_name, version].compact.join('=')
35
+ sudo "DEBIAN_FRONTEND=noninteractive apt-get remove -y -qq #{package_description}"
23
36
  end
24
37
 
25
38
  action 'ppa' do |repo|
@@ -30,8 +43,15 @@ Orca.extension :apt do
30
43
  sudo "DEBIAN_FRONTEND=noninteractive apt-get update -y -qq"
31
44
  end
32
45
 
33
- action 'exists' do |package_name|
34
- run("dpkg -s #{package_name} 2>&1 | grep Status") =~ /Status: install ok installed/
46
+ action 'exists' do |package_name, required_version=nil|
47
+ pkg_info = run("dpkg -s #{package_name} 2>&1")
48
+ installed = pkg_info =~ /Status: install ok installed/
49
+ next false unless installed
50
+ next true if required_version.nil?
51
+ version = pkg_info.match(/^Version: (.+?)$/)[1]
52
+ version_matches = (version == required_version)
53
+ log("#{package_name}: expected '#{required_version}' but found '#{version}'") unless version_matches
54
+ version_matches
35
55
  end
36
56
 
37
57
  validate do
@@ -50,7 +50,7 @@ class Orca::FileSync
50
50
  end
51
51
 
52
52
  def run_after_apply(context)
53
- context.instance_eval(&@after_apply)
53
+ context.instance_eval(&@after_apply) if @after_apply
54
54
  end
55
55
 
56
56
  def add_content_package
@@ -60,21 +60,21 @@ class Orca::Node
60
60
  @sftp ||= connection.sftp.connect
61
61
  end
62
62
 
63
- def execute(cmd)
63
+ def execute(cmd, opts={})
64
64
  log('execute', cmd.cyan)
65
65
  output = ""
66
66
  connection.exec! cmd do |channel, stream, data|
67
67
  output += data if stream == :stdout
68
68
  data.split("\n").each do |line|
69
69
  msg = stream == :stdout ? line.green : line.red
70
- log(stream, msg)
70
+ log(stream, msg) if opts[:log] || Orca.verbose
71
71
  end
72
72
  end
73
73
  output
74
74
  end
75
75
 
76
- def sudo(cmd)
77
- execute("sudo #{cmd}")
76
+ def sudo(cmd, opts={})
77
+ execute("sudo #{cmd}", opts)
78
78
  end
79
79
 
80
80
  def log(context, msg)
@@ -84,7 +84,11 @@ class Orca::Node
84
84
 
85
85
  def connection
86
86
  return @connection if @connection
87
- @connetion = Net::SSH.start(@host, (@options[:user] || 'root'), options_for_ssh)
87
+ @connection = Net::SSH.start(@host, (@options[:user] || 'root'), options_for_ssh)
88
+ end
89
+
90
+ def disconnect
91
+ @connection.close if @connection && !@connection.closed?
88
92
  end
89
93
 
90
94
  def to_s
@@ -4,6 +4,7 @@ class Orca::Suite
4
4
  @sequential = options[:sequential]
5
5
  @demonstrate = options[:demonstrate]
6
6
  @skip_dependancies = options[:'skip-dependancies'] || false
7
+ @nodes = []
7
8
  end
8
9
 
9
10
  def load_file(file)
@@ -13,6 +14,7 @@ class Orca::Suite
13
14
  def run(group_name, pkg_name, command, sequential=false)
14
15
  group = Orca::Group.find(group_name)
15
16
  runners = group.nodes.map do |node|
17
+ @nodes << node
16
18
  if command == :trigger
17
19
  Orca::TriggerRunner.new(node, pkg_name)
18
20
  else
@@ -28,6 +30,12 @@ class Orca::Suite
28
30
  end
29
31
  end
30
32
 
33
+ def cleanup
34
+ @nodes.each(&:disconnect)
35
+ end
36
+
37
+ private
38
+
31
39
  def exec(runner, command)
32
40
  if @demonstrate
33
41
  runner.demonstrate(command)
@@ -10,7 +10,7 @@ Gem::Specification.new do |gem|
10
10
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
11
11
  gem.name = "orca"
12
12
  gem.require_paths = ["lib"]
13
- gem.version = '0.3.0'
13
+ gem.version = '0.3.1'
14
14
  gem.add_dependency('colored')
15
15
  gem.add_dependency('net-ssh')
16
16
  gem.add_dependency('net-sftp')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
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: 2013-06-26 00:00:00.000000000 Z
12
+ date: 2013-06-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: colored
@@ -132,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
132
  version: '0'
133
133
  segments:
134
134
  - 0
135
- hash: 1540904086341919600
135
+ hash: -4313409858467376914
136
136
  required_rubygems_version: !ruby/object:Gem::Requirement
137
137
  none: false
138
138
  requirements:
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  version: '0'
142
142
  segments:
143
143
  - 0
144
- hash: 1540904086341919600
144
+ hash: -4313409858467376914
145
145
  requirements: []
146
146
  rubyforge_project:
147
147
  rubygems_version: 1.8.23