ssp 0.4 → 0.5

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,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"