Ubic
view release on metacpan or search on metacpan
lib/Ubic/Cmd.pm view on Meta::CPAN
unless ($count) {
# But if none of X subservices support our custom command, something is obviously wrong.
if ($service->isa('Ubic::Multiservice')) {
die "None of ".$service->full_name." subservices support $command";
}
else {
# it is unlikely that this error will happen, because we already checked that $service supports $command
die "$command unsupported";
}
}
# TODO - what if X want to implement custom command itself?
# should custom commands have different types, "try to call me in each subservice" and "call me for multiservice itself"?
return;
}
sub usage {
my $self = _obj(shift);
my $command = shift;
print STDERR "Unknown command '$command'. See 'ubic help'.\n";
exit(2); # or exit(3)? see LSB for details
}
sub traverse($$$) {
my $self = _obj(shift);
my ($service, $callback, $indent) = @_;
$indent ||= 0;
if (not defined $service) {
$service = Ubic->root_service;
}
elsif (not blessed($service)) {
$service = Ubic->service($service);
}
my $name = $service->full_name;
if ($service->isa('Ubic::Multiservice')) {
if ($service->full_name) {
print ' ' x $indent, $service->full_name, "\n";
$indent = $indent + 4;
}
for my $subservice ($service->services) {
$self->traverse($subservice, $callback, $indent); # FIXME - remember result
}
}
else {
print(' ' x $indent);
return $callback->($service, $indent);
}
}
sub print_status($$;$$) {
my $self = _obj(shift);
my $service = shift;
my $force_cached = shift;
my $results = shift || Ubic::Cmd::Results->new;
# TODO - use Credentials instead
my $user = getpwuid($>);
unless (defined $user) {
die "Can't detect user by uid $>";
}
my $max_offset = 0;
$self->traverse($service, sub {
my ($service, $indent) = @_;
my $name = $service->full_name;
print $name;
# calculating the number of tabs to separate service name from status
# status will be aligned whenever possible without sacrificing the real-time properties
# i.e., we add several tabs to align status with previous lines, but following lines can increase the number of tabs if necessary
# TODO - there are two possibilities to improve this:
# 1) look at the further *simple* services and add tabs:
# blah
# blah.a off
# blah.blahblahblah off
# blah.c off
# (current implementation wouldn't align "blah.a" line correctly)
# this would require the change to traverse() method api, though
# 2) pre-compile whole service tree before printing anything
# but output speed would suffer
my $offset = length($name) + $indent;
if ($offset < $max_offset) {
print "\t" x (int($max_offset) / 8 - int($offset / 8));
}
else {
$max_offset = $offset;
}
print "\t";
my $enabled = Ubic->is_enabled($name);
unless ($enabled) {
print "off\n";
$results->add(result('down'));
return;
}
my $status;
my $cached;
if ($force_cached or ($> and $user ne Ubic->service($name)->user)) {
$status = Ubic->cached_status($name);
$cached = 1;
}
else {
$status = eval { Ubic->status($name) };
if ($@) {
$status = result($@);
}
}
if ($status->status eq 'running') {
$results->print($status);
}
else {
$results->print($status, 'bad'); # up and not running is always bad
}
});
# TODO - print actual uplevel service's status, it can be service-specific
( run in 1.384 second using v1.01-cache-2.11-cpan-39bf76dae61 )