ssp 0.4 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,10 @@
1
1
  require 'linode'
2
2
  require 'ssp/config'
3
3
 
4
- class OpenStruct
5
- undef :type # fixing object.type deprecation issue
4
+ if OpenStruct.new.respond_to?(:type)
5
+ class OpenStruct
6
+ undef :type # fixing object.type deprecation issue
7
+ end
6
8
  end
7
9
 
8
10
  class SSP::App::Domain < Thor
@@ -0,0 +1,160 @@
1
+ require 'chef/config'
2
+ require 'chef/search/query'
3
+ require 'chef/node'
4
+
5
+ class Chef::Knife::Ssh
6
+ def print_data(host, data)
7
+ if data =~ /\n/
8
+ data.split(/\n/).each { |d| print_data(host, d) }
9
+ else
10
+ unless config[:dont_print_hosts]
11
+ padding = @longest - host.length
12
+ print h.color(host, :cyan)
13
+ print " " * padding
14
+ end
15
+ puts data
16
+ end
17
+ end
18
+ end
19
+
20
+ class SSP::App::Remote < Thor
21
+ namespace :remote
22
+
23
+ default_task :command
24
+
25
+ class_option :chef_config, :aliases => "-c",
26
+ :desc => "Location of the knife configuration file",
27
+ :default => File.join(ENV['HOME'], '.chef', 'knife.rb')
28
+
29
+ class_option :ssh_user, :aliases => "-u",
30
+ :desc => <<-EOH.squeeze(" ").strip
31
+ The ssh username. Defaults to the project name if only
32
+ project nodes are provided or to the current local user
33
+ otherwise,
34
+ EOH
35
+ class_option :ssh_password, :aliases => "-p",
36
+ :desc => "The ssh password"
37
+ class_option :cwd, :aliases => "-d",
38
+ :desc => <<-EOH.squeeze(" ").strip
39
+ The working directory where the command should be run.
40
+ If the user is a project user (e.g. dtm) then cwd defaults
41
+ to an intelligent choice: with no value it will be ~/current,
42
+ but it can be given as a partial SHA1 hash (at least 6 chars
43
+ long) in which case it will be used as a release directory.
44
+ Provide $HOME to run in the user's home dir.
45
+ EOH
46
+
47
+
48
+ desc "command NODE_or_QUERY COMMAND", "Runs a command on multiple nodes"
49
+ def command(nodes, *args)
50
+ chef_config
51
+
52
+ nodes = nodes.split(" ").map {|n| n.index('.') or n.index(':') ? n : "#{n}.sspti.me"}
53
+ user = ssh_user(nodes)
54
+ cwd = working_dir(user)
55
+ command = "cd #{cwd}\n#{args.join(" ")}"
56
+
57
+ say "Running #{shell.set_color(args.join(" ").inspect, :green)} in #{shell.set_color(cwd, :yellow)} as #{shell.set_color(user, :blue)} on #{nodes.map {|n| shell.set_color(n, :cyan)}.join(", ").gsub(/,([^,]*)$/, " and\\1")}"
58
+ ssh_run nodes.join(" "), command, user
59
+ end
60
+
61
+ desc "command NODE_or_QUERY TASK...", "Runs rake task(s) on multiple nodes"
62
+ def rake(nodes, *args)
63
+ args.unshift("rake")
64
+ command(nodes, *args)
65
+ end
66
+
67
+ desc "log LOGFILE", "Tails a logfile"
68
+ method_option :node, :aliases => "-n",
69
+ :desc => "The node where the logfile is located",
70
+ :default => "dtm-db-2"
71
+ method_option :host, :aliases => "-h",
72
+ :desc => "Host or project name (e.g. sage or dtm)"
73
+ method_option :date, :aliases => "-D",
74
+ :desc => "The date of the logfile you're interested in. Defaults to today, turns off tailing if this is in the past.",
75
+ :default => Date.today.to_s
76
+ method_option :history, :aliases => "-N",
77
+ :desc => "How many lines to show from the past",
78
+ :default => 10
79
+ def log(logfile)
80
+ @working_dir = options[:cwd] || options[:node] == "dtm-db-2" ? "/srv/rsyslog" : "/var/log"
81
+ @working_dir += '/' + options[:host] if options[:host]
82
+ @working_dir += '/' + options[:date].tr('-', '/')
83
+
84
+ @dont_print_hosts = true
85
+ tail = "-f " if Date.parse(options[:date]) == Date.today
86
+ command(options[:node], "tail -n#{options[:history]} #{tail}#{logfile}")
87
+ rescue Interrupt
88
+ # we don't care about interrupting a tail
89
+ end
90
+
91
+
92
+ private
93
+
94
+ def ssh_run(host, command, user, pass = options[:ssh_password], manual = !host.index(':'))
95
+ ssh = ::Chef::Knife::Ssh.new
96
+ ssh.name_args = [ host, command ]
97
+ ssh.config[:ssh_user] = user
98
+ ssh.config[:password] = pass
99
+ ssh.config[:manual] = manual
100
+ if @dont_print_hosts
101
+ ssh.config[:dont_print_hosts] = true
102
+ end
103
+
104
+ begin
105
+ ssh.run
106
+ rescue Net::SSH::AuthenticationFailed
107
+ unless pass
108
+ puts "Failed to authenticate #{user} - trying password auth"
109
+ ssh = ::Chef::Knife::Ssh.new
110
+ ssh.name_args = [ host, command ]
111
+ ssh.config[:ssh_user] = user
112
+ ssh.config[:manual] = manual
113
+ ssh.config[:password] = ssh.get_password
114
+ if @dont_print_hosts
115
+ ssh.config[:dont_print_hosts] = true
116
+ end
117
+ ssh.run
118
+ end
119
+ end
120
+ end
121
+
122
+ def working_dir(user)
123
+ if @working_dir
124
+ @working_dir
125
+ elsif %w{dtm}.include?(user)
126
+ if options[:cwd] =~ /^[a-f0-9]{6,}$/
127
+ "~/releases/#{options[:cwd]}*"
128
+ elsif options[:cwd].nil?
129
+ "~/current"
130
+ end
131
+ else
132
+ options[:cwd] || "~"
133
+ end
134
+ end
135
+
136
+ def user_from_nodes(nodes)
137
+ if nodes.all? {|n| n.index('-')}
138
+ project_names = nodes.map do |node|
139
+ if node.index(':').nil? or node.split(':').first == "hostname"
140
+ node.split(':').last.split('-').first
141
+ end
142
+ end
143
+ if project_names.uniq.size == 1
144
+ project_names.first
145
+ end
146
+ end
147
+ end
148
+
149
+ def ssh_user(nodes)
150
+ options[:ssh_user] || user_from_nodes(nodes) || ENV['USER'].downcase
151
+ end
152
+
153
+ def chef_config
154
+ unless defined?(@_chef_config_loaded)
155
+ ::Chef::Config.from_file(options[:chef_config])
156
+ @_chef_config_loaded = true
157
+ end
158
+ ::Chef::Config
159
+ end
160
+ end
data/lib/ssp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module SSP
2
- VERSION = "0.4"
2
+ VERSION = "0.5"
3
3
  end
metadata CHANGED
@@ -1,22 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 4
9
- version: "0.4"
7
+ - 5
8
+ version: "0.5"
10
9
  platform: ruby
11
10
  authors:
12
- - !binary |
13
- TMOhc3psw7MgQsOhY3Np
14
-
11
+ - "L\xC3\xA1szl\xC3\xB3 B\xC3\xA1csi"
15
12
  autorequire:
16
13
  bindir: bin
17
14
  cert_chain: []
18
15
 
19
- date: 2010-10-03 00:00:00 +02:00
16
+ date: 2010-10-14 00:00:00 +02:00
20
17
  default_executable:
21
18
  dependencies:
22
19
  - !ruby/object:Gem::Dependency
@@ -27,7 +24,6 @@ dependencies:
27
24
  requirements:
28
25
  - - ">="
29
26
  - !ruby/object:Gem::Version
30
- hash: 17
31
27
  segments:
32
28
  - 0
33
29
  - 13
@@ -42,7 +38,6 @@ dependencies:
42
38
  requirements:
43
39
  - - ">="
44
40
  - !ruby/object:Gem::Version
45
- hash: 25
46
41
  segments:
47
42
  - 0
48
43
  - 9
@@ -57,7 +52,6 @@ dependencies:
57
52
  requirements:
58
53
  - - ">="
59
54
  - !ruby/object:Gem::Version
60
- hash: 11
61
55
  segments:
62
56
  - 0
63
57
  - 2
@@ -73,7 +67,6 @@ dependencies:
73
67
  requirements:
74
68
  - - ">="
75
69
  - !ruby/object:Gem::Version
76
- hash: 21
77
70
  segments:
78
71
  - 1
79
72
  - 0
@@ -89,7 +82,6 @@ dependencies:
89
82
  requirements:
90
83
  - - ~>
91
84
  - !ruby/object:Gem::Version
92
- hash: 3
93
85
  segments:
94
86
  - 0
95
87
  - 6
@@ -116,6 +108,7 @@ files:
116
108
  - lib/ssp/application/node.rb
117
109
  - lib/ssp/application/office_node.rb
118
110
  - lib/ssp/application/pair.rb
111
+ - lib/ssp/application/remote.rb
119
112
  - lib/ssp/config.rb
120
113
  - lib/ssp/version.rb
121
114
  has_rdoc: true
@@ -132,7 +125,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
125
  requirements:
133
126
  - - ">="
134
127
  - !ruby/object:Gem::Version
135
- hash: 3
136
128
  segments:
137
129
  - 0
138
130
  version: "0"
@@ -141,7 +133,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
133
  requirements:
142
134
  - - ">="
143
135
  - !ruby/object:Gem::Version
144
- hash: 3
145
136
  segments:
146
137
  - 0
147
138
  version: "0"