abalone 0.1.0 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1de9af9802ec0b416470cec7b62a3cd7b3dfa053
4
- data.tar.gz: ea85d95749bb862e9b3f1edd9e69fe4cc73781f7
3
+ metadata.gz: 565875b71d7b4f783f558c97f5e4f0b3695f7428
4
+ data.tar.gz: cb3a9ed9725aee44626bb591602355a3e95a65fc
5
5
  SHA512:
6
- metadata.gz: d7d724d615b6e25db425b2d8aaaae18521053dce1c4bfbaee14b1fa6f7b26670ea603d6920e4408e15168103abd364bdd4c1b09c9a072e581bf422350bef5ce3
7
- data.tar.gz: d3b76310ff77bb549dea12f1e333d8e390d19ef9e98faef383e8ae7cac3ba3b5400278dad667a7363435828adddd586b3aad5e85f7c001a257375a143084dc7a
6
+ metadata.gz: d31db1d05ed62bdfdfe4884c4e5e9e6e1b0bbf45ef837b3363af363d7cd9aea617ca0fd45b379d5afd9bbe4928d0452f8b2619d60e335c5cdfdb5dfe334455a7
7
+ data.tar.gz: 1100692ff4a162c5daa2800bdd077cc6d481e9792235b0101e24bc8670d0fccd5957df785689d83b39956608477c0ee367fc49ffda32a17309887ca86c625992
data/README.md CHANGED
@@ -5,6 +5,8 @@ A simple Sinatra & hterm based web terminal.
5
5
 
6
6
  1. [Overview](#overview)
7
7
  1. [Configuration](#configuration)
8
+ 1. [SSH](#configuring-ssh)
9
+ 1. [Custom Login Command](#configuring-a-custom-command)
8
10
  1. [Limitations](#limitations)
9
11
 
10
12
  ## Overview
@@ -24,7 +26,22 @@ It supports three methods for providing a shell:
24
26
 
25
27
  Abalone defaults to loading configuration from `/etc/abalone/config.yaml`. You
26
28
  can pass the path to another config file at the command line. In that file, you
27
- can set one of `:command` or `:ssh`.
29
+ can set several options:
30
+
31
+ * `:port`
32
+ * Which port to run the server on.
33
+ * Default value: `9000`
34
+ * `:bind`
35
+ * The hostname or IP address of the interface to listen on.
36
+ * Default value: `0.0.0.0` (listen to all interfaces.)
37
+ * `:logfile`
38
+ * The path of a file to log to.
39
+ * Default value: Log only to `STDERR`. If you pass `-l` at the command line
40
+ with no filename, it will log to `/var/log/abalone`.
41
+ * One of [`:command`](#configuring-a-custom-command) or [`:ssh`](#configuring-ssh), exclusive.
42
+ * The login method to use. Abalone can use `login`, SSH, or a custom command
43
+ to start a shell. See configuration instructions below.
44
+ * Default value: uses the `login` binary, with no configuration possible.
28
45
 
29
46
  ### Configuring SSH
30
47
 
@@ -6,11 +6,10 @@ require 'abalone'
6
6
  require 'yaml'
7
7
 
8
8
  defaults = {
9
- :port => 9000,
10
- :host => '0.0.0.0',
11
- :bind => '0.0.0.0',
9
+ :port => 9000,
10
+ :bind => '0.0.0.0',
11
+ :logfile => $stderr,
12
12
  }
13
- logfile = $stderr
14
13
  loglevel = Logger::WARN
15
14
  configfile = '/etc/abalone/config.yaml'
16
15
  options = {}
@@ -29,7 +28,7 @@ optparse = OptionParser.new { |opts|
29
28
  end
30
29
 
31
30
  opts.on("-l [LOGFILE]", "--logfile [LOGFILE]", "Path to logfile. Defaults to no logging, or /var/log/abalone if no filename is passed.") do |arg|
32
- logfile = arg || '/var/log/abalone'
31
+ options[:logfile] = arg || defaults[:logfile] || '/var/log/abalone'
33
32
  end
34
33
 
35
34
  opts.on("-p PORT", "--port PORT", "Port to listen on. Defaults to 9000.") do |arg|
@@ -47,13 +46,13 @@ optparse = OptionParser.new { |opts|
47
46
  }
48
47
  optparse.parse!
49
48
 
50
- logger = Logger.new(logfile)
51
- logger.level = loglevel
52
- options[:logger] = logger
53
-
54
49
  config = YAML.load_file(configfile) rescue {}
55
50
  options = defaults.merge(config.merge(options))
56
51
 
52
+ logger = Logger.new(options[:logfile])
53
+ logger.level = loglevel
54
+ options[:logger] = logger
55
+
57
56
  if options[:params].class == Hash
58
57
  options[:params].each do |param, data|
59
58
  next if data.nil?
@@ -74,7 +73,7 @@ end
74
73
  raise 'Specify only one of a login command or SSH settings' if options.include? :command and options.include? :ssh
75
74
 
76
75
  if options.include? :command
77
- raise ":params must be an Array or Hash, not #{options[:params].class}" unless [Array, Hash].include? options[:params].class
76
+ raise ":params must be an Array or Hash, not #{options[:params].class}" unless [Array, Hash, NilClass].include? options[:params].class
78
77
  raise ":command should be a String or an Array, not a #{options[:command].class}." unless [Array, String].include? options[:command].class
79
78
  end
80
79
 
@@ -9,8 +9,8 @@ require 'io/console'
9
9
  class Abalone < Sinatra::Base
10
10
  set :logging, true
11
11
  set :strict, true
12
- set :public_folder, 'public'
13
- set :views, 'views'
12
+ set :public_folder, "#{settings.root}/../public"
13
+ set :views, "#{settings.root}/../views"
14
14
 
15
15
  before {
16
16
  env["rack.logger"] = settings.logger if settings.logger
@@ -46,19 +46,26 @@ class Abalone < Sinatra::Base
46
46
  # there must be some form of event driven pty interaction, EM or some gem maybe?
47
47
  reader.sync = true
48
48
  @term = Thread.new do
49
+ carry = []
49
50
  loop do
50
51
  begin
51
52
  PTY.check(@pid, true)
52
- data = reader.read_nonblock(512) # we read non-blocking to stream data as quickly as we can
53
+ output = reader.read_nonblock(512).unpack('c*') # we read non-blocking to stream data as quickly as we can
54
+ index = output.rindex { |x| x < 128 } # find the last low bit
55
+ carry = output[index...-11] # save the any remaining high bits and partial chars for next go-round
56
+ data = (carry + output[0..index]).pack('c*').force_encoding('UTF-8') # and pack the rest back into a string to send
57
+
58
+ ws.send(data)
59
+
53
60
  rescue IO::WaitReadable
54
61
  IO.select([reader])
55
62
  retry
56
63
  rescue PTY::ChildExited => e
57
- puts "Terminal has exited!"
58
- ws.send({'event' => 'logout'}.to_json)
64
+ warn('Terminal has exited!')
65
+ ws.close_connection
66
+
59
67
  Thread.exit
60
68
  end
61
- ws.send({'event' => 'output', 'data' => data}.to_json)
62
69
  sleep(0.05)
63
70
  end
64
71
  end
@@ -66,7 +73,7 @@ class Abalone < Sinatra::Base
66
73
  end
67
74
 
68
75
  ws.onclose do
69
- warn("websocket closed")
76
+ warn('websocket closed')
70
77
  stop_term()
71
78
  end
72
79
 
@@ -91,9 +98,10 @@ class Abalone < Sinatra::Base
91
98
  warn("Unrecognized message: #{message.inspect}")
92
99
  end
93
100
  rescue Errno::EIO => e
94
- puts "Terminal has died!"
101
+ puts "Remote terminal closed."
95
102
  puts e.message
96
- ws.send({'event' => 'logout'}.to_json)
103
+ stop_term()
104
+
97
105
  end
98
106
 
99
107
  end
@@ -108,7 +116,7 @@ class Abalone < Sinatra::Base
108
116
  helpers do
109
117
  def stop_term()
110
118
  Process.kill('TERM', @pid) rescue nil
111
- @term.join
119
+ @term.join rescue nil
112
120
  end
113
121
 
114
122
  def sanitized(params)
@@ -36,7 +36,7 @@
36
36
  </style>
37
37
  </head>
38
38
 
39
- <body onload="connect(boogers);">
39
+ <body onload="connect();">
40
40
  <div id="overlay"><input type="button" onclick="javascript:connect();" value="reconnect" /></div>
41
41
  <div id="terminal"></div>
42
42
  </body>
@@ -59,29 +59,11 @@ function disconnected() {
59
59
  }
60
60
 
61
61
  function messageHandler(data) {
62
- message = JSON.parse(data);
63
-
64
- switch(message['event']) {
65
- case 'output':
66
- if (!term) {
67
- buf += message['data'];
68
- return;
69
- }
70
- term.io.writeUTF16(message['data']);
71
- break;
72
-
73
- case 'logout':
74
- console.log("user logout");
75
- disconnected();
76
- break;
77
-
78
- case 'disconnect':
79
- disconnected();
80
- break;
81
-
82
- default:
83
-
62
+ if (!term) {
63
+ buf += data;
64
+ return;
84
65
  }
66
+ term.io.writeUTF16(data);
85
67
  }
86
68
 
87
69
  /* borrowed from https://github.com/krishnasrinivas/wetty */
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abalone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Ford
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-31 00:00:00.000000000 Z
11
+ date: 2016-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra