From: Robert 'phaylon' Sedlacek Date: Thu, 24 May 2012 02:41:49 +0000 (+0000) Subject: configuration, state generation, centralised gatherer X-Git-Tag: v0.001_001~65 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=60e1cc39c0dc98165bdeb13c0f522ac18ebb5153;p=scpubgit%2FSystem-Introspector.git configuration, state generation, centralised gatherer --- diff --git a/lib/System/Introspector/Config.pm b/lib/System/Introspector/Config.pm new file mode 100644 index 0000000..8b51c31 --- /dev/null +++ b/lib/System/Introspector/Config.pm @@ -0,0 +1,22 @@ +package System::Introspector::Config; +use Moo; +use Config::General; + +has config => (is => 'lazy'); + +has config_file => (is => 'ro', required => 1); + +sub _build_config { + my ($self) = @_; + my $reader = Config::General->new($self->config_file); + my %config = $reader->getall; + return \%config; +} + +sub groups { keys %{ $_[0]->config->{group} || {} } } + +sub has_group { exists $_[0]->config->{group}{ $_[1] } } + +sub config_for_group { $_[0]->config->{group}{ $_[1] } } + +1; diff --git a/lib/System/Introspector/Gatherer.pm b/lib/System/Introspector/Gatherer.pm new file mode 100644 index 0000000..17ac433 --- /dev/null +++ b/lib/System/Introspector/Gatherer.pm @@ -0,0 +1,12 @@ +package System::Introspector::Gatherer; +use Moo; +use Module::Runtime qw( use_module ); + +sub gather { + my ($self, $class, $args) = @_; + return use_module("System::Introspector::$class") + ->new($args) + ->gather; +} + +1; diff --git a/lib/System/Introspector/State.pm b/lib/System/Introspector/State.pm new file mode 100644 index 0000000..fae866e --- /dev/null +++ b/lib/System/Introspector/State.pm @@ -0,0 +1,90 @@ +package System::Introspector::State; +use Moo; +use Data::YAML::Writer; +use Object::Remote; +use Object::Remote::Future; +use System::Introspector::Gatherer; + +has config => (is => 'ro', required => 1); + +has introspectors => (is => 'lazy'); + +has host => (is => 'ro'); + +has storage => (is => 'ro', required => 1); + +has node_path => (is => 'lazy'); + +sub fetch { + my ($self) = @_; + my $gatherer = $self->_create_gatherer; + my $spec = $self->introspectors; + my %report; + for my $class_base (sort keys %$spec) { + $report{ $class_base } = $gatherer + ->gather($class_base, $spec->{ $class_base }); + } + return \%report; +} + +sub fetch_and_store { + my ($self) = @_; + return $self->_store($self->fetch); +} + +sub _build_node_path { + my ($self) = @_; + return defined($self->host) + ? sprintf('host/%s', $self->host) + : 'local'; +} + +sub _build_introspectors { + my ($self) = @_; + return $self->config->{introspect}; +} + +sub _store { + my ($self, $data) = @_; + my $yaml = Data::YAML::Writer->new; + my $storage = $self->storage; + my @files; + for my $class (sort keys %$data) { + my $file = sprintf '%s.yml', join '/', + node => $self->node_path, + map lc, map { + s{([a-z0-9])([A-Z])}{${1}_${2}}g; + $_; + } split m{::}, $class; + my $fh = $storage->open('>:utf8', $file, mkpath => 1); + print "Writing $file\n"; + $yaml->write($data->{$class}, $fh); + push @files, $storage->file($file); + } + $self->_cleanup(\@files); + return 1; +} + +sub _cleanup { + my ($self, $known_files) = @_; + my %known = map { ($_ => 1) } @$known_files; + my $data_dir = $self->storage->file(node => $self->node_path); + my @files = $self->storage->find_files('yml', node => $self->node_path); + for my $file (@files) { + next if $known{$file}; + print "Removing $file\n"; + unlink($file) + or die "Unable to remove '$file': $!\n"; + } + return 1; +} + +sub _create_gatherer { + my ($self) = @_; + if (defined( my $host = $self->host )) { + return System::Introspector::Gatherer->new::on($host); + } + return System::Introspector::Gatherer->new; +} + +1;