shaft 0.6 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.md +14 -12
  2. data/bin/shaft +54 -27
  3. data/lib/shaft/version.rb +1 -1
  4. metadata +3 -2
data/README.md CHANGED
@@ -38,22 +38,24 @@ files.
38
38
 
39
39
  ## Configuration
40
40
 
41
- Each SSH tunnel you want to have configured needs to be defined
42
- in YAML format and stored in `~/.shaft/name.yml`, where `name`
43
- is the tunnel name that would be used for `shaft`.
41
+ The SSH tunnels configuration Shaft will use are all stored in
42
+ a single YAML file under `~/.shaft`.
44
43
 
45
- An example configuration would be:
44
+ Each tunnel is represented by a key defining its name, followed
45
+ by an object describing all of the required parameters.
46
46
 
47
- port: 22
48
- username: user
49
- host: remote-host
50
- bind:
51
- client-port: 9999
52
- host: host
53
- host-port: 8888
47
+ An example configuration would be:
54
48
 
49
+ foobar:
50
+ port: 22
51
+ username: user
52
+ host: remote-host
53
+ bind:
54
+ client-port: 9999
55
+ host: host
56
+ host-port: 8888
55
57
 
56
- Starting the tunnel defined in this example would be equivalent
58
+ Calling Shaft with `$ shaft start foobar` would be equivalent
57
59
  to running:
58
60
 
59
61
  $ ssh -N -p 22 user@remote-host -L 9999:host:8888
data/bin/shaft CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- SHAFT_DIR = File.join(Dir.home, ".shaft")
3
+ SHAFT_CONFIG = File.join(Dir.home, ".shaft")
4
+ SHAFT_ACTIVE = File.join(Dir.home, ".shaft.active")
4
5
 
5
6
  require 'rubygems'
6
7
  require 'thor'
@@ -10,11 +11,11 @@ class ShaftCLI < Thor
10
11
  include Thor::Actions
11
12
 
12
13
  map "-h" => :help
13
- map "-l" => :list
14
+ map "-l" => :active
14
15
 
15
- desc "list", "Lists active tunnels"
16
+ desc "active", "Lists active tunnels"
16
17
  method_options %w( short -s ) => :boolean
17
- def list
18
+ def active
18
19
  active = get_active
19
20
  unless active.empty?
20
21
  if options[:short]
@@ -31,7 +32,7 @@ class ShaftCLI < Thor
31
32
  desc "all", "Lists all available tunnels"
32
33
  def all
33
34
  say "Listing all available tunnels:"
34
- tunnels = Dir["#{SHAFT_DIR}/*.yml"].map { |f| File.basename(f, ".yml") }
35
+ tunnels = get_config.keys
35
36
  print_in_columns tunnels
36
37
  end
37
38
 
@@ -42,14 +43,20 @@ class ShaftCLI < Thor
42
43
  if active.has_key? name
43
44
  say "Error: tunnel '#{name}' already active!"
44
45
  else
45
- c = read_yaml("#{name}.yml")
46
+ c = get_tunnel(name)
46
47
  unless c.nil?
47
48
  begin
48
49
  port = c['port']
49
50
  bind = "#{c['bind']['client-port']}:#{c['bind']['host']}:#{c['bind']['host-port']}"
50
51
  host = "#{c['username']}@#{c['host']}"
51
52
  rescue NoMethodError
52
- error "Tunnel file for '#{name}' appears to be invalid!"
53
+ error "Tunnel configuration for '#{name}' appears to be invalid!"
54
+ return
55
+ end
56
+
57
+ used = local_port_used?(c['bind']['client-port'])
58
+ if used
59
+ error "Local port #{port} is used by:\n#{used}"
53
60
  return
54
61
  end
55
62
 
@@ -61,7 +68,7 @@ class ShaftCLI < Thor
61
68
  active[name] = pid
62
69
  set_active(active)
63
70
  else
64
- error "Tunnel '#{name}' file not found!"
71
+ error "Tunnel '#{name}' not found!"
65
72
  end
66
73
  end
67
74
  end
@@ -70,19 +77,25 @@ class ShaftCLI < Thor
70
77
  method_options :name => :string
71
78
  def stop(name)
72
79
  active = get_active
73
- if active.has_key? name
80
+ if active.has_key?(name)
74
81
  say "Stopping tunnel '#{name}' at pid #{active[name]}..."
75
82
  begin
76
83
  Process.kill "INT", active[name]
77
- say "Stopped."
78
84
  rescue Errno::ESRCH
79
85
  say "Tunnel wasn't active (zombie shaft item)."
80
86
  end
81
87
 
82
- #TODO verify killing?
88
+ # verify killing
89
+ tunnel = get_tunnel(name)
90
+ if local_port_used?(tunnel['bind']['client-port'])
91
+ error "Could not stop tunnel process!"
92
+ else
93
+ say "Stopped."
83
94
 
84
- active.delete(name)
85
- set_active(active)
95
+ # set as inactive
96
+ active.delete(name)
97
+ set_active(active)
98
+ end
86
99
  else
87
100
  error "Tunnel '#{name}' does not seem to be active!"
88
101
  end
@@ -95,28 +108,42 @@ class ShaftCLI < Thor
95
108
  end
96
109
 
97
110
  private
98
- def read_yaml(filename)
99
- path = File.join(SHAFT_DIR, filename)
100
- YAML::load(File.open(path)) if File.exist?(path)
111
+ def get_config
112
+ @config ||= read_yaml(SHAFT_CONFIG)
101
113
  end
102
114
 
103
115
  def get_active
104
- active = read_yaml(".active")
105
- if active.nil?
106
- active = {}
107
- set_active(active)
108
- end
109
- active
116
+ @active ||= read_yaml(SHAFT_ACTIVE)
117
+ end
118
+
119
+ def get_tunnel(name)
120
+ get_config[name] || nil
110
121
  end
111
122
 
112
123
  def set_active(active)
113
- unless File.exist?(SHAFT_DIR) and File.directory?(SHAFT_DIR)
114
- Dir.mkdir(SHAFT_DIR)
124
+ File.open(SHAFT_ACTIVE, 'w') { |out|
125
+ YAML.dump(active, out)
126
+ }
127
+ end
128
+
129
+ def read_yaml(file)
130
+ if File.directory?(SHAFT_CONFIG)
131
+ error "Shaft v0.7 and up uses a single-file config.\nConsult the Readme at http://git.io/Zs3viQ ."
132
+ {}
133
+ elsif File.exists?(file)
134
+ YAML::load(File.open(file))
135
+ else
136
+ {}
115
137
  end
138
+ end
116
139
 
117
- File.open(File.join(SHAFT_DIR, '.active'), 'w') { |f|
118
- f.write(active.to_yaml)
119
- }
140
+ def local_port_used?(port)
141
+ usage = `lsof -n -i4TCP:#{port} | grep LISTEN`
142
+ if usage.length > 0
143
+ usage
144
+ else
145
+ false
146
+ end
120
147
  end
121
148
 
122
149
  end
@@ -1,3 +1,3 @@
1
1
  module Shaft
2
- VERSION = "0.6"
2
+ VERSION = "0.7"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shaft
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.6'
4
+ version: '0.7'
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-04 00:00:00.000000000 Z
12
+ date: 2013-01-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -69,3 +69,4 @@ signing_key:
69
69
  specification_version: 3
70
70
  summary: An SSH tunnel assistant for the command line.
71
71
  test_files: []
72
+ has_rdoc: