vagrant-listen-server 0.0.5 → 0.2.0
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 +4 -4
- data/README.md +62 -25
- data/examples/node-client.js +14 -26
- data/lib/vagrant-listen-server.rb +1 -0
- data/lib/vagrant-listen-server/action.rb +7 -115
- data/lib/vagrant-listen-server/command.rb +35 -0
- data/lib/vagrant-listen-server/daemon.rb +201 -0
- data/lib/vagrant-listen-server/plugin.rb +6 -0
- data/lib/vagrant-listen-server/version.rb +1 -1
- data/vagrant-listen-server.gemspec +5 -1
- metadata +37 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2cdf2e1170398757ee77d0f77d7366215c800ac8
|
4
|
+
data.tar.gz: a9de6204420690db4cfe7a98ebc3827a43c75eaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 996828c785f9869b42ff44040e1a690e3facf5ceeb7eba5309d243406136069c7e51fbec0be53573813aa40ba2b46407e647d13c123a849046bb45c096e4920f
|
7
|
+
data.tar.gz: 1bea636775f295df277e33ed412ba0b8ea118af011495f94b08d9e267a635fc0047f7939a7b33d912303ab529da20f4190c8a2ffc91bdd31f41124ea668cb35e
|
data/README.md
CHANGED
@@ -14,29 +14,56 @@ are impossible. Statting takes forever.
|
|
14
14
|
Since polling implementations will probably rely on statting the file in some
|
15
15
|
way, this creates a pretty awful experience.
|
16
16
|
|
17
|
-
|
18
|
-
listen gem is
|
19
|
-
|
20
|
-
with.
|
17
|
+
I have tried to keep dependencies to a minimum and only rely on ruby stdlib and
|
18
|
+
gems already required by vagrant. The listen gem is used by vagrant (as part
|
19
|
+
of rsync-auto) so it is used for file system notifications.
|
21
20
|
|
22
21
|
|
23
22
|
## Clients
|
24
23
|
|
25
|
-
|
26
|
-
|
24
|
+
Clients should run inside the virtual machine as part of your build process.
|
25
|
+
Instead of listenting for filesystem events, they should listen on a tcp
|
26
|
+
connection.
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
The message format is a newline separated, json encoded object with keys `type`
|
29
|
+
and `data`. The two message types:
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
**listen**
|
32
|
+
|
33
|
+
{"type": "listen", "data": [modified, added, removed]}
|
34
|
+
|
35
|
+
data is an array of 3 arrays containing the full path of the files that are
|
36
|
+
modified, added and removed (in that order).
|
37
|
+
|
38
|
+
**ping**
|
39
|
+
|
40
|
+
{"type": "ping", "data": "message to be echoed"}
|
41
|
+
|
42
|
+
response will be of type "pong". Data will be echoed back to the client.
|
43
|
+
|
44
|
+
|
45
|
+
In many cases, a simple client that touches all modified files on the guest is
|
46
|
+
sufficient, however you'll have to be aware of loops created if filesystem
|
47
|
+
notifications are passed back from the guest to the host in any way. Listen
|
48
|
+
coalesces events for us, so there is no need to do so in your client.
|
34
49
|
|
35
50
|
See the [examples](/examples) section for some implementations. Currently there
|
36
51
|
is solely my node based client, but if you're using this in any other
|
37
52
|
languages, please add your client and submit a pull request!
|
38
53
|
|
39
54
|
|
55
|
+
## Keepalives
|
56
|
+
|
57
|
+
Ideally, the client and server sockets would both support keepalives. But we
|
58
|
+
can't rely on that working on both guest and host - windows has spotty support,
|
59
|
+
and many languages don't give control over socket flags (it's awkward in ruby).
|
60
|
+
Instead, the client can send a ping message to check the connection is alive.
|
61
|
+
|
62
|
+
A simple client can safely ignore keepalive messages.
|
63
|
+
|
64
|
+
http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/
|
65
|
+
|
66
|
+
|
40
67
|
## Usage
|
41
68
|
|
42
69
|
Install the plugin:
|
@@ -46,19 +73,29 @@ Install the plugin:
|
|
46
73
|
Then in your Vagrantfile:
|
47
74
|
|
48
75
|
```ruby
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
76
|
+
config.vm.synced_folder '/host/code', '/client/code'
|
77
|
+
|
78
|
+
# You have to specify a private network for the guest to connect to.
|
79
|
+
config.vm.network :private_network, ip: '172.16.172.16'
|
80
|
+
|
81
|
+
if Vagrant.has_plugin? 'vagrant-listen-server'
|
82
|
+
# The host will always be the same IP as the private network with the last
|
83
|
+
# octet as .1
|
84
|
+
config.listen_server.ip = '172.168.172.1'
|
85
|
+
config.listen_server.port = 4000
|
86
|
+
config.listen_server.folders = '/host/code'
|
87
|
+
config.listen_server.pid_file = '/tmp/servername.listen.pid'
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
Because sleep states of both the host and guest machines can mess with long
|
92
|
+
connections in unexpected ways, you can use the command to control the listen
|
93
|
+
server.
|
94
|
+
|
95
|
+
```bash
|
96
|
+
vagrant listen stop
|
97
|
+
vagrant listen start
|
98
|
+
vagrant listen status
|
62
99
|
```
|
63
100
|
|
64
101
|
|
@@ -78,7 +115,7 @@ Hasn't been updated to work with vagrant's new plugin system.
|
|
78
115
|
To develop locally
|
79
116
|
```
|
80
117
|
gem build vagrant-listen-server.gemspec
|
81
|
-
vagrant plugin install vagrant-listen-server
|
118
|
+
vagrant plugin install vagrant-listen-server-*.gem
|
82
119
|
```
|
83
120
|
|
84
121
|
Other good vagrant plugins used for reference:
|
data/examples/node-client.js
CHANGED
@@ -1,48 +1,36 @@
|
|
1
1
|
var net = require('net');
|
2
2
|
|
3
|
-
|
4
3
|
// Assuming the existence of some `build` method that returns a promise.
|
5
4
|
var sequence = build();
|
6
5
|
|
7
|
-
|
8
|
-
// gathers rapid changes as one build
|
9
|
-
var timeout = null;
|
10
|
-
var scheduleBuild = function() {
|
11
|
-
if (timeout) { return; }
|
12
|
-
|
13
|
-
// we want the timeout to start now before we wait for the current build
|
14
|
-
var timeoutPromise = new Promise(function(resolve) {
|
15
|
-
timeout = setTimeout(resolve, 100);
|
16
|
-
});
|
17
|
-
|
18
|
-
var timeoutThenBuild = function() {
|
19
|
-
timeoutPromise.then(function() {
|
20
|
-
timeout = null
|
21
|
-
return build();
|
22
|
-
});
|
23
|
-
};
|
24
|
-
|
25
|
-
// we want the current promise to be waiting for the current build
|
26
|
-
// regardless if it fails or not.
|
27
|
-
sequence = sequence.then(timeoutThenBuild, timeoutThenBuild);
|
28
|
-
};
|
29
|
-
|
30
|
-
|
31
6
|
var port = 4000;
|
32
7
|
var host = '172.16.172.1';
|
33
8
|
var client = new net.Socket();
|
9
|
+
var interval = null;
|
34
10
|
|
35
11
|
client.connect(port, host, function() {
|
36
12
|
console.log('Connected to listen server: ', host, port);
|
13
|
+
|
14
|
+
interval = setInterval(function() {
|
15
|
+
message = JSON.stringify({type: 'ping', message: 'listen-watcher'});
|
16
|
+
client.write(message + '\n');
|
17
|
+
, 1000);
|
37
18
|
});
|
38
19
|
|
39
20
|
client.on('data', function(data) {
|
40
21
|
// message is [modified, added, removed]
|
41
22
|
console.log('Data received', data)
|
42
23
|
var message = JSON.parse(data.toString().trim())
|
43
|
-
|
24
|
+
|
25
|
+
if (message.type === 'pong') { return; }
|
26
|
+
if (message.type !== 'listen') { throw Error('Unknown message type'); }
|
27
|
+
|
28
|
+
// We want the current promise to be waiting for the current build
|
29
|
+
// regardless if it fails or not.
|
30
|
+
sequence = sequence.then(build, build);
|
44
31
|
});
|
45
32
|
|
46
33
|
client.on('close', function() {
|
47
34
|
console.log('Connection closed');
|
35
|
+
interval && clearInterval(interval);
|
48
36
|
});
|
@@ -2,18 +2,6 @@ require 'listen'
|
|
2
2
|
require 'socket'
|
3
3
|
require 'json'
|
4
4
|
|
5
|
-
# No ActiveSupport in vagrant
|
6
|
-
def array_wrap object
|
7
|
-
if object.nil?
|
8
|
-
[]
|
9
|
-
elsif object.respond_to?(:to_ary)
|
10
|
-
object.to_ary || [object]
|
11
|
-
else
|
12
|
-
[object]
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
5
|
module VagrantPlugins
|
18
6
|
module ListenServer
|
19
7
|
module Action
|
@@ -23,95 +11,10 @@ module VagrantPlugins
|
|
23
11
|
end
|
24
12
|
|
25
13
|
def call(env)
|
26
|
-
@env = env
|
27
|
-
@ui = env[:ui]
|
28
|
-
@machine = env[:machine]
|
29
|
-
|
30
|
-
config = @machine.config.listen_server
|
31
|
-
folders = array_wrap config.folders
|
32
|
-
|
33
|
-
@ui.info "Starting listen server - #{config.ip}:#{config.port}"
|
34
|
-
|
35
|
-
# Check whether the daemon is already running.
|
36
|
-
if File.exists? config.pid_file
|
37
|
-
pid = File.read config.pid_file
|
38
|
-
begin
|
39
|
-
Process.getpgid pid.to_i
|
40
|
-
@ui.info 'Warning - listen server already running'
|
41
|
-
return @app.call(env)
|
42
|
-
rescue Errno::ESRCH
|
43
|
-
@ui.info "Warning - stale PID: #{pid}"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
14
|
out = @app.call(env)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
# Only real option is to switch to Process.spawn? I need a windows
|
52
|
-
# machine to test it out on...
|
53
|
-
pid = fork do
|
54
|
-
$0 = "vagrant-listen-server - #{@machine.name}"
|
55
|
-
|
56
|
-
clients = []
|
57
|
-
server = TCPServer.new config.ip, config.port
|
58
|
-
|
59
|
-
callback = Proc.new do |modified, added, removed|
|
60
|
-
bad_clients = []
|
61
|
-
# @ui.info "Listen fired - #{clients.count} clients.\n #{modified}\n #{added}\n #{removed}"
|
62
|
-
clients.each do |client|
|
63
|
-
begin
|
64
|
-
client.puts [modified, added, removed].to_json
|
65
|
-
rescue Errno::EPIPE
|
66
|
-
@ui.info "Connection broke! #{client}"
|
67
|
-
# Don't want to change the list of threads as we iterate.
|
68
|
-
bad_clients.push client
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
bad_clients.each do |client|
|
73
|
-
clients.delete client
|
74
|
-
end
|
75
|
-
end
|
76
|
-
listener = Listen.to(*folders, &callback)
|
77
|
-
listener.start
|
78
|
-
|
79
|
-
# server.accept blocks - we need it in its own thread so we can
|
80
|
-
# continue to have listener callbacks fired, and so we can sleep
|
81
|
-
# and catch any interrupts from vagrant.
|
82
|
-
Thread.new do
|
83
|
-
loop do
|
84
|
-
Thread.fork(server.accept) do |client|
|
85
|
-
@ui.info "New connection - #{client}"
|
86
|
-
clients.push client
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# TODO: this error won't happen on the listen anymore - it will
|
92
|
-
# happen somewhere on the tcp call. Not sure where.
|
93
|
-
#
|
94
|
-
# begin
|
95
|
-
# listener.start
|
96
|
-
# rescue Errno::EADDRNOTAVAIL
|
97
|
-
# @ui.info "Can't start server - Port in use"
|
98
|
-
# exit
|
99
|
-
# end
|
100
|
-
|
101
|
-
# Uhh... this needs work. Vagrant steals the interrupt from us and
|
102
|
-
# there's no way to get it back
|
103
|
-
# * https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/action/runner.rb#L49
|
104
|
-
# Is there a way to register more callbacks to the busy block?
|
105
|
-
# * https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/util/busy.rb
|
106
|
-
while not env[:interrupted]
|
107
|
-
sleep 1
|
108
|
-
end
|
109
|
-
@ui.info "Listen sleep finished"
|
110
|
-
end
|
111
|
-
|
112
|
-
Process.detach pid
|
113
|
-
File.write config.pid_file, pid
|
114
|
-
@ui.info "Listen server started on PID #{pid}"
|
15
|
+
# config = env[:machine].config.listen_server
|
16
|
+
vm = env[:machine]
|
17
|
+
Daemon.start vm
|
115
18
|
|
116
19
|
out
|
117
20
|
end
|
@@ -123,22 +26,11 @@ module VagrantPlugins
|
|
123
26
|
end
|
124
27
|
|
125
28
|
def call(env)
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
if File.exists? config.pid_file
|
130
|
-
pid = File.read config.pid_file
|
131
|
-
begin
|
132
|
-
Process.kill 'INT', pid.to_i
|
133
|
-
rescue Errno::ESRCH
|
134
|
-
@ui.info 'Stale PID file - no server found'
|
135
|
-
end
|
136
|
-
File.delete config.pid_file
|
137
|
-
else
|
138
|
-
@ui.info 'No listen server found'
|
139
|
-
end
|
29
|
+
out = @app.call env
|
30
|
+
vm = env[:machine]
|
31
|
+
Daemon.stop vm
|
140
32
|
|
141
|
-
|
33
|
+
out
|
142
34
|
end
|
143
35
|
end
|
144
36
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module ListenServer
|
3
|
+
class Command < Vagrant.plugin('2', :command)
|
4
|
+
def self.synopsis
|
5
|
+
"Check the status of the vagrant-listen server"
|
6
|
+
end
|
7
|
+
|
8
|
+
def execute
|
9
|
+
opts = OptionParser.new do |o|
|
10
|
+
o.banner = 'Usage: vagrant listen [start|stop|status]'
|
11
|
+
end
|
12
|
+
|
13
|
+
command = @argv.shift
|
14
|
+
argv = parse_options opts
|
15
|
+
|
16
|
+
with_target_vms nil, single_target: true do |vm|
|
17
|
+
# puts "ENV #{vm.env.inspect}"
|
18
|
+
# puts "CONFIG #{vm.config.inspect}"
|
19
|
+
# puts "LISTEN #{vm.config.listen_server.inspect}"
|
20
|
+
|
21
|
+
case command
|
22
|
+
when 'status' then Daemon.status vm.config.listen_server
|
23
|
+
when 'stop' then Daemon.stop vm
|
24
|
+
when 'start' then Daemon.start vm
|
25
|
+
else
|
26
|
+
puts 'Unknown command'
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
def array_wrap object
|
2
|
+
if object.nil?
|
3
|
+
[]
|
4
|
+
elsif object.respond_to?(:to_ary)
|
5
|
+
object.to_ary || [object]
|
6
|
+
else
|
7
|
+
[object]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
# TODO: pre-fork use vagrant logging, post fork use puts.
|
13
|
+
def log message
|
14
|
+
puts message
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
module Daemon
|
19
|
+
def self.status_code config
|
20
|
+
return :stopped unless File.exists? config.pid_file
|
21
|
+
|
22
|
+
pid = File.read config.pid_file
|
23
|
+
begin
|
24
|
+
Process.getpgid pid.to_i
|
25
|
+
return pid.to_i
|
26
|
+
rescue Errno::ESRCH
|
27
|
+
return :stale
|
28
|
+
end
|
29
|
+
:stopped
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.status config
|
33
|
+
code = self.status_code config
|
34
|
+
case code
|
35
|
+
when Fixnum then log "Running - PID: #{code}"
|
36
|
+
when :stopped then log 'Stopped'
|
37
|
+
when :stale then log 'Stopped. Stale PID file.'
|
38
|
+
else
|
39
|
+
log "Unknown status - #{code}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Wasted way too long trying to use Process.daemon. Doing it by hand. Code
|
44
|
+
# courtesy of:
|
45
|
+
# https://gist.github.com/mynameisrufus/1372491/b76b60fb1842bf0507f47869ab19ad50a045b214
|
46
|
+
# See also:
|
47
|
+
# * http://stackoverflow.com/questions/1740308/create-a-daemon-with-double-fork-in-ruby
|
48
|
+
# * http://allenlsy.com/working-with-unix-process-in-ruby/
|
49
|
+
#
|
50
|
+
# Related: Process.detach isn't what you think. It creates a process to
|
51
|
+
# monitor the child so that this can exit without creating a zombie. Because
|
52
|
+
# we want to remove parents, this actually makes life harder than just doing
|
53
|
+
# a double fork.
|
54
|
+
#
|
55
|
+
# Vagrant-notify uses fork as well, but that doesn't work on windows:
|
56
|
+
# https://github.com/fgrehm/vagrant-notify/blob/master/lib/vagrant-notify/server.rb
|
57
|
+
# Only real option is to switch to Process.spawn? I need a windows
|
58
|
+
# machine to test it out on... Vagrant::Util::Subprocess allows spawning an
|
59
|
+
# executable, but I don't know how to make that launch the included ruby
|
60
|
+
# binary and make sure it's running the right file.
|
61
|
+
def self.daemonize! out='/dev/null', err='/dev/null'
|
62
|
+
raise 'First fork failed' if (pid = fork) == -1
|
63
|
+
return nil unless pid.nil?
|
64
|
+
Process.setsid
|
65
|
+
raise 'Second fork failed' if (pid = fork) == -1
|
66
|
+
exit unless pid.nil?
|
67
|
+
|
68
|
+
# Dir.chdir '/'
|
69
|
+
# File.umask 0000
|
70
|
+
|
71
|
+
$stdin.reopen '/dev/null'
|
72
|
+
$stdout.reopen File.new(out, "a")
|
73
|
+
$stderr.reopen File.new(err, "a")
|
74
|
+
$stdout.sync = $stderr.sync = true
|
75
|
+
|
76
|
+
Process.pid
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
def self.start vm
|
81
|
+
config = vm.config.listen_server
|
82
|
+
log "Starting listen server - #{config.ip}:#{config.port}"
|
83
|
+
|
84
|
+
status = self.status_code config
|
85
|
+
if status == :running
|
86
|
+
log 'Server already running.'
|
87
|
+
return 1
|
88
|
+
end
|
89
|
+
|
90
|
+
File.delete config.pid_file if status == :stale
|
91
|
+
|
92
|
+
# TODO: use machine name in log file name.
|
93
|
+
# TODO: use machine name in PID file and drop it from config.
|
94
|
+
pid = daemonize! '/tmp/listen.log', '/tmp/listen.log'
|
95
|
+
# Usually a daemon wants the parent to exit here, but we need vagrant to
|
96
|
+
# keep going with its init process.
|
97
|
+
return unless pid
|
98
|
+
|
99
|
+
$0 = "vagrant-listen-server - #{vm.name}"
|
100
|
+
|
101
|
+
File.write config.pid_file, pid
|
102
|
+
|
103
|
+
log "Listen server started on PID #{pid}"
|
104
|
+
|
105
|
+
clients = []
|
106
|
+
begin
|
107
|
+
server = TCPServer.new config.ip, config.port
|
108
|
+
rescue Errno::EADDRINUSE
|
109
|
+
log "Can't start server - Port in use"
|
110
|
+
exit 1
|
111
|
+
end
|
112
|
+
|
113
|
+
send_to_clients = Proc.new do |type, data|
|
114
|
+
bad_clients = []
|
115
|
+
log "Sending #{type} to #{clients.count} clients."
|
116
|
+
|
117
|
+
clients.each do |client|
|
118
|
+
begin
|
119
|
+
client.puts ({type: type, data: data}).to_json
|
120
|
+
rescue Errno::EPIPE
|
121
|
+
log "Connection broke! #{client}"
|
122
|
+
# Don't want to change the list of threads as we iterate.
|
123
|
+
bad_clients.push client
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
bad_clients.each do |client|
|
128
|
+
clients.delete client
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
callback = Proc.new do |modified, added, removed|
|
133
|
+
log "Listen fired"
|
134
|
+
send_to_clients.call :listen, [modified, added, removed]
|
135
|
+
end
|
136
|
+
|
137
|
+
folders = array_wrap config.folders
|
138
|
+
|
139
|
+
# There is a recurring bug that keeps popping up in listen where only the
|
140
|
+
# first directory is watched. Create a new listen object for each folder as
|
141
|
+
# a workaround.
|
142
|
+
# https://github.com/guard/listen/issues/243
|
143
|
+
listeners = folders.map do |folder|
|
144
|
+
Listen.to(folder, &callback)
|
145
|
+
end
|
146
|
+
|
147
|
+
listeners.each &:start
|
148
|
+
|
149
|
+
# server.accept is blocking - we need it in its own thread so we can
|
150
|
+
# continue to have listener callbacks fired, and so we can sleep and catch
|
151
|
+
# any interrupts.
|
152
|
+
Thread.new do
|
153
|
+
loop do
|
154
|
+
Thread.fork(server.accept) do |client|
|
155
|
+
log "New connection - #{client}"
|
156
|
+
clients.push client
|
157
|
+
|
158
|
+
loop do
|
159
|
+
line = client.gets.chomp
|
160
|
+
# Currently, the only message type is a ping. Don't bother checking
|
161
|
+
# type for now.
|
162
|
+
data = JSON.parse line
|
163
|
+
log 'ping received'
|
164
|
+
client.puts ({type: 'pong', data: data['message']}).to_json
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
exiting = false
|
171
|
+
Signal.trap 'INT' do
|
172
|
+
log 'SIGINT caught'
|
173
|
+
exiting = true
|
174
|
+
end
|
175
|
+
|
176
|
+
while not exiting
|
177
|
+
# Original idea was to have the server ping. This requires more work on
|
178
|
+
# the client for a basic implementation though, so now the client pings.
|
179
|
+
# send_to_clients.call :echo, 'ping'
|
180
|
+
sleep 0.5
|
181
|
+
end
|
182
|
+
|
183
|
+
listeners.each &:stop
|
184
|
+
log "Listen sleep finished"
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
def self.stop vm
|
189
|
+
log 'Killing listen server'
|
190
|
+
config = vm.config.listen_server
|
191
|
+
status = self.status_code config
|
192
|
+
unless status.is_a? Fixnum
|
193
|
+
log 'Server is not running.'
|
194
|
+
return 1
|
195
|
+
end
|
196
|
+
|
197
|
+
pid = File.read config.pid_file
|
198
|
+
Process.kill 'INT', pid.to_i
|
199
|
+
File.delete config.pid_file
|
200
|
+
end
|
201
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'action'
|
2
|
+
require_relative 'daemon'
|
2
3
|
|
3
4
|
require 'rbconfig'
|
4
5
|
os = RbConfig::CONFIG['target_os']
|
@@ -23,6 +24,11 @@ module VagrantPlugins
|
|
23
24
|
Config
|
24
25
|
end
|
25
26
|
|
27
|
+
command :listen do
|
28
|
+
require_relative 'command'
|
29
|
+
Command
|
30
|
+
end
|
31
|
+
|
26
32
|
action_hook(:listen_server, :machine_action_up) do |hook|
|
27
33
|
hook.append(Action::StartServer)
|
28
34
|
end
|
@@ -17,9 +17,13 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
|
+
# Shouldn't have to do this, but we want to make sure not to tie to an old
|
21
|
+
# version of listen and accidentally pull in the celluloid dependency.
|
22
|
+
spec.add_runtime_dependency 'listen', '~> 3.0', '>= 3.0.2'
|
23
|
+
|
24
|
+
spec.add_dependency 'rb-kqueue', '~> 0.2', '>= 0.2.3'
|
20
25
|
spec.add_dependency 'rb-inotify', '~> 0.9', '>= 0.9.5'
|
21
26
|
spec.add_dependency 'rb-fsevent', '~> 0.9', '>= 0.9.4'
|
22
|
-
spec.add_dependency 'rb-kqueue', '~> 0.2', '>= 0.2.3'
|
23
27
|
# wdm is already included in the vagrant gem spec.
|
24
28
|
# spec.add_runtime_dependency 'wdm', '~> 0.10', '>= 0.10.0'
|
25
29
|
|
metadata
CHANGED
@@ -1,37 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-listen-server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Kelso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: listen
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0
|
19
|
+
version: '3.0'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: 3.0.2
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '0
|
29
|
+
version: '3.0'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
32
|
+
version: 3.0.2
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
-
name: rb-
|
34
|
+
name: rb-kqueue
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0.2'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.2.3
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0.2'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.2.3
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rb-inotify
|
35
55
|
requirement: !ruby/object:Gem::Requirement
|
36
56
|
requirements:
|
37
57
|
- - "~>"
|
@@ -39,7 +59,7 @@ dependencies:
|
|
39
59
|
version: '0.9'
|
40
60
|
- - ">="
|
41
61
|
- !ruby/object:Gem::Version
|
42
|
-
version: 0.9.
|
62
|
+
version: 0.9.5
|
43
63
|
type: :runtime
|
44
64
|
prerelease: false
|
45
65
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -49,27 +69,27 @@ dependencies:
|
|
49
69
|
version: '0.9'
|
50
70
|
- - ">="
|
51
71
|
- !ruby/object:Gem::Version
|
52
|
-
version: 0.9.
|
72
|
+
version: 0.9.5
|
53
73
|
- !ruby/object:Gem::Dependency
|
54
|
-
name: rb-
|
74
|
+
name: rb-fsevent
|
55
75
|
requirement: !ruby/object:Gem::Requirement
|
56
76
|
requirements:
|
57
77
|
- - "~>"
|
58
78
|
- !ruby/object:Gem::Version
|
59
|
-
version: '0.
|
79
|
+
version: '0.9'
|
60
80
|
- - ">="
|
61
81
|
- !ruby/object:Gem::Version
|
62
|
-
version: 0.
|
82
|
+
version: 0.9.4
|
63
83
|
type: :runtime
|
64
84
|
prerelease: false
|
65
85
|
version_requirements: !ruby/object:Gem::Requirement
|
66
86
|
requirements:
|
67
87
|
- - "~>"
|
68
88
|
- !ruby/object:Gem::Version
|
69
|
-
version: '0.
|
89
|
+
version: '0.9'
|
70
90
|
- - ">="
|
71
91
|
- !ruby/object:Gem::Version
|
72
|
-
version: 0.
|
92
|
+
version: 0.9.4
|
73
93
|
- !ruby/object:Gem::Dependency
|
74
94
|
name: bundler
|
75
95
|
requirement: !ruby/object:Gem::Requirement
|
@@ -113,7 +133,9 @@ files:
|
|
113
133
|
- examples/node-client.js
|
114
134
|
- lib/vagrant-listen-server.rb
|
115
135
|
- lib/vagrant-listen-server/action.rb
|
136
|
+
- lib/vagrant-listen-server/command.rb
|
116
137
|
- lib/vagrant-listen-server/config.rb
|
138
|
+
- lib/vagrant-listen-server/daemon.rb
|
117
139
|
- lib/vagrant-listen-server/plugin.rb
|
118
140
|
- lib/vagrant-listen-server/version.rb
|
119
141
|
- vagrant-listen-server.gemspec
|