Class: LXC::Extra::Channel
- Inherits:
-
Object
- Object
- LXC::Extra::Channel
- Defined in:
- lib/lxc/extra/channel.rb
Overview
Bidirectional Ruby communications between a host and an LXC container. It handles bidirectional communications: the host can send a message to the container using channel.send_message, and the container can send to the host using channel.send_message as well.
This class is intended to be created before ct.attach and used by both the host and the container.
Shorthand Usage
require ‘lxc’ require ‘lxc/extra’
container = LXC::Container.new(‘simple’) channel, pid = container.open_channel do |host, number|
puts "received #{number} INSIDE!"
if number > 10
host.stop
else
host.(number+1)
end
end channel.send_message(1) channel.listen do |container, number|
puts "received #{number} OUTSIDE!"
container.(number+1) unless number > 10
end
Extended Usage
channel = Channel.new
ct.attach do
channel.listen do |host, number|
"received #{number} INSIDE!"
if number > 10
host.stop
else
host.send(number+1)
end
end
end
channel.listen do |container, number|
"received #{number} OUTSIDE!"
container.send(number+1)
end
Defined Under Namespace
Classes: Stop
Instance Attribute Summary collapse
-
#from_container ⇒ Object
readonly
Returns the value of attribute from_container.
-
#from_host ⇒ Object
readonly
Returns the value of attribute from_host.
-
#host_pid ⇒ Object
readonly
Returns the value of attribute host_pid.
-
#to_container ⇒ Object
readonly
Returns the value of attribute to_container.
-
#to_host ⇒ Object
readonly
Returns the value of attribute to_host.
Instance Method Summary collapse
-
#initialize ⇒ Channel
constructor
Create a new LXC channel.
-
#listen(&block) ⇒ Object
Listen for data from the other side.
-
#next(stop_result = Stop.singleton) ⇒ Object
Get the next result.
-
#pretend_message_was_sent(*args) ⇒ Object
Pretend a message was sent from the other side.
-
#read_fd ⇒ Object
File descriptor that receives data from the other side.
-
#send_message(*args) ⇒ Object
Send a message to the other side.
-
#stop ⇒ Object
Stop the channel.
-
#write_fd ⇒ Object
File descriptor that sends data to the other side.
Constructor Details
#initialize ⇒ Channel
Create a new LXC channel.
54 55 56 57 58 |
# File 'lib/lxc/extra/channel.rb', line 54 def initialize @from_container, @to_host = IO.pipe @from_host, @to_container = IO.pipe @host_pid = Process.pid end |
Instance Attribute Details
#from_container ⇒ Object (readonly)
Returns the value of attribute from_container.
60 61 62 |
# File 'lib/lxc/extra/channel.rb', line 60 def from_container @from_container end |
#from_host ⇒ Object (readonly)
Returns the value of attribute from_host.
62 63 64 |
# File 'lib/lxc/extra/channel.rb', line 62 def from_host @from_host end |
#host_pid ⇒ Object (readonly)
Returns the value of attribute host_pid.
64 65 66 |
# File 'lib/lxc/extra/channel.rb', line 64 def host_pid @host_pid end |
#to_container ⇒ Object (readonly)
Returns the value of attribute to_container.
63 64 65 |
# File 'lib/lxc/extra/channel.rb', line 63 def to_container @to_container end |
#to_host ⇒ Object (readonly)
Returns the value of attribute to_host.
61 62 63 |
# File 'lib/lxc/extra/channel.rb', line 61 def to_host @to_host end |
Instance Method Details
#listen(&block) ⇒ Object
Listen for data from the other side. Loops until stop is received.
Arguments
- &block
-
callback
Example
channel.listen do |*args|
puts "Received #{args} from the other side."
end
78 79 80 81 82 83 84 85 86 |
# File 'lib/lxc/extra/channel.rb', line 78 def listen(&block) while true args = self.next if args.is_a?(Stop) return end block.call(self, *args) end end |
#next(stop_result = Stop.singleton) ⇒ Object
Get the next result.
Arguments
- stop_result
-
result to return when the channel wants to shut down. Defaults to LXC::Extra::Channel::Stop.singleton
Returns
Returns nextLXC::Extra::Channel::Stop instance if the channel closes.
108 109 110 111 112 113 114 |
# File 'lib/lxc/extra/channel.rb', line 108 def next(stop_result = Stop.singleton) if read_fd.closed? stop_result else Marshal.load(read_fd) end end |
#pretend_message_was_sent(*args) ⇒ Object
Pretend a message was sent from the other side.
For debug purposes.
132 133 134 135 136 137 138 |
# File 'lib/lxc/extra/channel.rb', line 132 def (*args) if Process.pid == @host_pid Marshal.dump(args, @to_host) else Marshal.dump(args, @to_container) end end |
#read_fd ⇒ Object
File descriptor that receives data from the other side.
154 155 156 157 158 159 160 |
# File 'lib/lxc/extra/channel.rb', line 154 def read_fd if Process.pid == @host_pid @from_container else @from_host end end |
#send_message(*args) ⇒ Object
Send a message to the other side. You may send arbitrary Ruby, which will be sent with Marshal.dump.
Arguments
- args
-
a list of arguments to send. Arbitrary Ruby objects may be sent. The other side’s listen callback will receive these arguments.
96 97 98 |
# File 'lib/lxc/extra/channel.rb', line 96 def (*args) Marshal.dump(args, write_fd) end |
#stop ⇒ Object
Stop the channel. Sends a message to the other side to stop it, too.
119 120 121 122 123 124 125 |
# File 'lib/lxc/extra/channel.rb', line 119 def stop (Stop.singleton) @from_container.close @to_host.close @from_host.close @to_container.close end |
#write_fd ⇒ Object
File descriptor that sends data to the other side.
143 144 145 146 147 148 149 |
# File 'lib/lxc/extra/channel.rb', line 143 def write_fd if Process.pid == @host_pid @to_container else @to_host end end |