class HaveAPI::Fs::Components::Executable

Base class for all executables. Executables can be executed either by writing `1` into them or by running them, as they contain a Ruby script.

The Ruby script communicates with the file system using {RemoteControlFile}. In short, it tells the file system to execute a component at a certain path, which results in the same action as when `1` is written to the file.

In both cases, the file system itself does the operation, the outer process only signals it to do so and then waits for a reply.

When the component is to be executed, method {#exec} is called.

Public Instance Methods

exec() click to toggle source
# File lib/haveapi/fs/components/executable.rb, line 71
def exec
  raise NotImplementedError
end
executable?() click to toggle source
# File lib/haveapi/fs/components/executable.rb, line 14
def executable?
  true
end
read() click to toggle source
# File lib/haveapi/fs/components/executable.rb, line 22
    def read
      abs_path = ::File.join(context.mountpoint, path)

      <<END
#!#{RbConfig.ruby}
#
# This action can be executed either by running this file or by writing "1" to
# it, e.g.:
#   
#   .#{abs_path}
#
# or
#
#   echo 1 > #{abs_path}
#
require 'yaml'

f = ::File.open(
    '#{::File.join(context.mountpoint, '.remote_control')}',
    'w+'
)
f.write(YAML.dump({
    action: :execute,
    path: '/#{path}',
}))
f.write(#{RemoteControlFile::MSG_DELIMITER.dump})
f.flush
f.seek(0)

ret = YAML.load(f.read)
f.close

unless ret[:status]
  warn "Action failed: \#{ret[:message]}"
  if ret[:errors]
    ret[:errors].each do |k, v|
      warn "  \#{k}: \#{v.join('; ')}"
    end
  end
end

exit(ret[:status])
END
    end
writable?() click to toggle source
# File lib/haveapi/fs/components/executable.rb, line 18
def writable?
  true
end
write(str) click to toggle source
# File lib/haveapi/fs/components/executable.rb, line 67
def write(str)
  exec if str.strip == '1'
end