cbor (CBORIO) for comunication between processes.

This commit is contained in:
Denis Knauf 2024-01-22 14:27:06 +01:00 committed by root
parent 23a5d2c729
commit 1af2dc37d9
3 changed files with 72 additions and 32 deletions

View file

@ -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
View 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

View file

@ -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