#!/usr/bin/env perl use v5.10.1; use strict; use warnings; use Carp; use File::Path qw(make_path remove_tree); use File::Temp qw/tempfile tempdir/; use IPC::Open3; use XML::LibXML; use ACU::LDAP; use ACU::Log; use ACU::Process; my %node_actions = ( "launch" => \&node_launch, ); sub node_launch { my $args = shift; # First, create a temporary directory my $dir = tempdir(); chdir( $dir ); # Extract all files to current directory for my $filename (keys %{ $args->{files} }) { open my $fh, ">", $filename or croak("$filename: $!"); print $fh $args->{files}{$filename}; close $fh; } my $doc = XML::LibXML::Document->new('1.0'); my $root = $doc->createElement("target"); $root->addChild( $doc->createAttribute("name", $ARGV[0]) ); $doc->setDocumentElement( $root ); for my $c ($args->{subtree}->getElementsByTagName("command")) { if (! exists $c->{attributes}{target} || index($c->{attributes}{target}, $ARGV[0]) != -1) { my $cmd = $doc->createElement("cmd"); if (! exists $c->{attributes}{hide}) { $root->appendChild($cmd); } my $command = $doc->createElement("command"); $command->appendText($c->{nodeValue}); $cmd->appendChild($command); my($wtr, $rdr, $rv); my $stderr = ""; eval { my $pid = open3($wtr, $rdr, $stderr, "sh", "-c", $c->{nodeValue}); waitpid( $pid, 0 ); $rv = $? >> 8; }; if ($@) { $stderr = $@ . $stderr; $rv = -1; } my $out = $doc->createElement("out"); my $str = ""; if ($rdr) { $str .= $_ while (<$rdr>); } $out->appendText($str); $cmd->appendChild($out); my $err = $doc->createElement("err"); $str = ""; if ($stderr) { $str .= $_ while (<$stderr>); } $err->appendText($str); $cmd->appendChild($err); my $ret = $doc->createElement("return"); $ret->appendText($rv); $cmd->appendChild($ret); } } chdir(); remove_tree( $dir ); return $doc->toString(); } sub process_node { my ($given_args, $args) = @_; my $action = $args->{param}{action} // "launch"; if (! exists $node_actions{$action}) { log WARN, "Unknown action '$action' for guantanamo node process."; } return $node_actions{$action}($args); } if ($#ARGV == 0) { log INFO, "Starting guantanamo.pl as node process"; Process::Client::launch("guantanamo", {"action" => "register", "nodename" => $ARGV[0]}, undef, 1); Process::register("guantanamo_".$ARGV[0], \&process_node); }