cbor (CBORIO) for comunication between processes.
This commit is contained in:
parent
23a5d2c729
commit
1af2dc37d9
1
Gemfile
1
Gemfile
|
@ -3,3 +3,4 @@ gem 'ruby-lxc', git: 'https://git.denkn.at/deac/ruby-lxc'
|
||||||
gem 'prometheus-client'
|
gem 'prometheus-client'
|
||||||
gem 'puma'
|
gem 'puma'
|
||||||
gem 'rack'
|
gem 'rack'
|
||||||
|
gem 'cbor'
|
||||||
|
|
54
lib/cborio.rb
Normal file
54
lib/cborio.rb
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
require 'cbor'
|
||||||
|
|
||||||
|
class CBORIO
|
||||||
|
include Enumerable
|
||||||
|
def orig_io() @io end
|
||||||
|
def unpacker() @un end
|
||||||
|
def close() @io.close end
|
||||||
|
def write( obj) @io.write CBOR.pack( obj) end
|
||||||
|
def sync() @io.sync end
|
||||||
|
def sync( v) @io.sync = v end
|
||||||
|
def self.pipe() IO.pipe.map &self.method(:new) end
|
||||||
|
def self.popen &exe
|
||||||
|
rd, wr = self.pipe
|
||||||
|
pid =
|
||||||
|
fork do
|
||||||
|
rd.close
|
||||||
|
yield wr
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
wr.close
|
||||||
|
[pid, rd]
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize io
|
||||||
|
@io, @un = io, CBOR::Unpacker.new
|
||||||
|
@io.sync = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.open io, &exe
|
||||||
|
if block_given?
|
||||||
|
s = self.new io
|
||||||
|
begin yield s
|
||||||
|
ensure s.close
|
||||||
|
end
|
||||||
|
else self.new io
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def read
|
||||||
|
return @un.read rescue EOFError
|
||||||
|
loop do
|
||||||
|
@un.feed @io.readpartial( 1024)
|
||||||
|
return @un.read rescue EOFError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def each &exe
|
||||||
|
return to_enum __method__ unless block_given?
|
||||||
|
loop { yield read }
|
||||||
|
self
|
||||||
|
rescue EOFError
|
||||||
|
self
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,35 +1,20 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
require 'json'
|
|
||||||
require 'prometheus/client'
|
require 'prometheus/client'
|
||||||
require 'lxc'
|
require 'lxc'
|
||||||
|
|
||||||
require_relative 'ns'
|
require_relative 'ns'
|
||||||
require_relative 'file-statfs'
|
require_relative 'file-statfs'
|
||||||
|
require_relative 'cborio'
|
||||||
|
require_relative 'lxc_extend'
|
||||||
require_relative 'lxc-exporter/os_release'
|
require_relative 'lxc-exporter/os_release'
|
||||||
require_relative 'lxc-exporter/mount_info'
|
require_relative 'lxc-exporter/mount_info'
|
||||||
require_relative 'lxc_extend'
|
|
||||||
|
|
||||||
=begin
|
|
||||||
class LXC::CT
|
|
||||||
def initialize name
|
|
||||||
extend Fiddle::Importer
|
|
||||||
dlload Fiddle.dlopen( nil)
|
|
||||||
|
|
||||||
extern 'lxc_container *lxc_container_new( const char* name, const char* config_path)'
|
|
||||||
|
|
||||||
def initialize name, config = nil
|
|
||||||
lxc_container_new name, config
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
=end
|
|
||||||
|
|
||||||
class LxcCollector
|
class LxcCollector
|
||||||
include Prometheus::Client
|
include Prometheus::Client
|
||||||
|
|
||||||
CTStates = { aborting: -1, stopped: 0, starting: 1, stopping: 2, running: 3 }
|
CTStates = { aborting: -1, stopped: 0, starting: 0.75, stopping: 0.25, running: 1 }
|
||||||
|
|
||||||
def statfs ct, mis
|
def statfs ct, mis
|
||||||
mis.each do |mi|
|
mis.each do |mi|
|
||||||
|
@ -81,32 +66,38 @@ class LxcCollector
|
||||||
mis = MountInfo.of pid
|
mis = MountInfo.of pid
|
||||||
NS.change pid, :pid, :mnt do
|
NS.change pid, :pid, :mnt do
|
||||||
name = ct.config_item( 'lxc.uts.name')
|
name = ct.config_item( 'lxc.uts.name')
|
||||||
|
|
||||||
|
# Filesystems
|
||||||
statfs ct, mis do |ct, mp, st|
|
statfs ct, mis do |ct, mp, st|
|
||||||
next unless st.fstypename and 0 < st.blocks
|
next unless st.fstypename and 0 < st.blocks
|
||||||
st = st.to_h.merge mp: mp, id: ct.name, name: name
|
st = st.to_h.merge mp: mp, id: ct.name, name: name
|
||||||
wr.puts [:mountpoint, st].to_json
|
wr.write [:mountpoint, st]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# OS / Distribution
|
||||||
osr = OsRelease.read
|
osr = OsRelease.read
|
||||||
if osr
|
if osr
|
||||||
wr.puts [:os_release, {
|
wr.write [:os_release, {
|
||||||
id: ct.name, name: name,
|
id: ct.name, name: name,
|
||||||
os_id: osr[:id],
|
os_id: osr[:id],
|
||||||
os_name: osr[:name],
|
os_name: osr[:name],
|
||||||
os_pretty_name: osr[:pretty_name],
|
os_pretty_name: osr[:pretty_name],
|
||||||
os_version_id: osr[:version_id].to_i,
|
os_version_id: osr[:version_id].to_i,
|
||||||
os_version_codename: osr[:version_codename]
|
os_version_codename: osr[:version_codename]
|
||||||
}].to_json
|
}]
|
||||||
|
|
||||||
case osr[:id].to_sym
|
case osr[:id].to_sym
|
||||||
|
# Special things for Debian(-based) distributions
|
||||||
when :debian
|
when :debian
|
||||||
upgradable = nil
|
upgradable = nil
|
||||||
pid =
|
pid =
|
||||||
IO.popen %w[apt list --upgradable], err: "/dev/null" do |apt|
|
IO.popen %w[apt list --upgradable], err: "/dev/null" do |apt|
|
||||||
upgradable = apt.readlines.length - 1
|
upgradable = apt.readlines.length - 1
|
||||||
end
|
end
|
||||||
wr.puts [:pkgs, {
|
wr.write [:pkgs, {
|
||||||
id: ct.name, name: name, upgradable: upgradable,
|
id: ct.name, name: name, upgradable: upgradable,
|
||||||
last_update: AptLastUpdateFile.stat.mtime.to_f,
|
last_update: AptLastUpdateFile.stat.mtime.to_f,
|
||||||
}].to_json
|
}]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -116,19 +107,13 @@ class LxcCollector
|
||||||
end
|
end
|
||||||
|
|
||||||
def collect
|
def collect
|
||||||
rd, wr = IO.pipe
|
|
||||||
pid = fork do
|
|
||||||
rd.close
|
|
||||||
forked wr
|
|
||||||
end
|
|
||||||
wr.close
|
|
||||||
LXC.containers do |ct|
|
LXC.containers do |ct|
|
||||||
labels = { id: ct.name, name: ct.config_item( 'lxc.uts.name') }
|
labels = { id: ct.name, name: ct.config_item( 'lxc.uts.name') }
|
||||||
@up.set ct.running? ? 1 : 0, labels: labels
|
@up.set ct.running? ? 1 : 0, labels: labels
|
||||||
@state.set CTStates[ct.state], labels: labels
|
@state.set CTStates[ct.state], labels: labels
|
||||||
end
|
end
|
||||||
rd.each_line do |l|
|
pid, rd = CBORIO.popen( &method( :forked))
|
||||||
l = JSON.parse l, symbolize_names: true
|
rd.each do |l|
|
||||||
case l[0].to_sym
|
case l[0].to_sym
|
||||||
|
|
||||||
when :mountpoint
|
when :mountpoint
|
||||||
|
|
Loading…
Reference in a new issue