2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-04 20:17:55 +00:00

refactor(dhcp): share OMAPI command runner

This commit is contained in:
Vinícius Ferrão
2026-08-31 11:11:08 -03:00
parent 362bf5eb9f
commit d1bd0fe576
3 changed files with 94 additions and 77 deletions
+77
View File
@@ -0,0 +1,77 @@
package xCAT::DHCP::OmapiRunner;
use strict;
use warnings;
use File::Temp qw(tempfile);
use POSIX qw(WNOHANG);
use Time::HiRes qw(sleep);
sub open_command_file {
my ($class, $directory) = @_;
$directory ||= $class->_command_directory();
mkdir $directory unless -d $directory;
my ($handle, $path) = tempfile('omshell.XXXXXX', DIR => $directory, UNLINK => 0);
return { handle => $handle, path => $path };
}
sub run_command_file {
my ( $class, $command_file, $omshell_path ) = @_;
my $pid = $class->_fork();
return 'fork_error' unless defined $pid;
if ( $pid == 0 ) {
open( STDIN, '<', $command_file ) or exit 127; ## no critic (InputOutput::RequireCheckedOpen)
open( STDOUT, '>', '/dev/null' ) or exit 127; ## no critic (InputOutput::RequireCheckedOpen)
open( STDERR, '>', '/dev/null' ) or exit 127; ## no critic (InputOutput::RequireCheckedOpen)
exec {$omshell_path} $omshell_path;
exit 127;
}
for ( 1 .. $class->_completion_attempts() ) {
if ( waitpid( $pid, WNOHANG ) == $pid ) {
sleep $class->_completion_delay();
return 'completed';
}
sleep $class->_poll_interval();
}
kill 'TERM', $pid;
for ( 1 .. $class->_termination_attempts() ) {
return 'terminated' if waitpid( $pid, WNOHANG ) == $pid;
sleep $class->_poll_interval();
}
kill 'KILL', $pid;
waitpid( $pid, 0 );
return 'killed';
}
sub _fork {
return fork();
}
sub _completion_attempts {
return 100;
}
sub _termination_attempts {
return 20;
}
sub _poll_interval {
return 0.1;
}
sub _completion_delay {
return 1.0;
}
sub _command_directory {
return '/tmp/xcat';
}
1;
+9 -41
View File
@@ -11,7 +11,6 @@ use strict;
use IPC::Open2;
use IPC::Open3;
use IO::Select;
use File::Temp qw(tempfile);
use Symbol qw/gensym/;
use POSIX qw/WNOHANG/;
use Time::HiRes qw(sleep);
@@ -36,6 +35,7 @@ use xCAT::SvrUtils;
use xCAT::DHCP::BootPolicy;
use xCAT::DHCP::Backend;
use xCAT::DHCP::OmapiPolicy;
use xCAT::DHCP::OmapiRunner;
use xCAT::DHCP::Range;
use xCAT::TableUtils;
use xCAT::NetworkUtils qw/getipaddr/;
@@ -412,45 +412,10 @@ sub _open_omshell_writer
{
my $settings = shift;
mkdir "/tmp/xcat" unless -d "/tmp/xcat";
my ($omshell_stdin, $command_file) = tempfile('omshell.XXXXXX', DIR => '/tmp/xcat', UNLINK => 0);
return unless $omshell_stdin;
my $command = xCAT::DHCP::OmapiRunner->open_command_file();
return unless ref($command) eq 'HASH' && $command->{handle};
return ($omshell_stdin, { command_file => $command_file, omshell_path => $settings->{omshell_path} });
}
sub _run_omshell_command_file
{
my ($command_file, $omshell_path) = @_;
my $pid = fork();
return unless defined $pid;
if ($pid == 0) {
open(STDIN, '<', $command_file) or exit 127; ## no critic (InputOutput::RequireCheckedOpen)
open(STDOUT, '>', '/dev/null') or exit 127; ## no critic (InputOutput::RequireCheckedOpen)
open(STDERR, '>', '/dev/null') or exit 127; ## no critic (InputOutput::RequireCheckedOpen)
exec { $omshell_path } $omshell_path;
exit 127;
}
for (1 .. 100) {
if (waitpid($pid, WNOHANG) == $pid) {
sleep 1.0;
return 1;
}
sleep 0.1;
}
kill 'TERM', $pid;
for (1 .. 20) {
return if waitpid($pid, WNOHANG) == $pid;
sleep 0.1;
}
kill 'KILL', $pid;
waitpid($pid, 0);
return;
return ($command->{handle}, { command_file => $command->{path}, omshell_path => $settings->{omshell_path} });
}
sub _close_omshell_writer
@@ -461,9 +426,12 @@ sub _close_omshell_writer
return unless ref($writer) eq 'HASH';
my $ok = _run_omshell_command_file($writer->{command_file}, $writer->{omshell_path});
my $status = xCAT::DHCP::OmapiRunner->run_command_file(
$writer->{command_file}, $writer->{omshell_path}
);
unlink $writer->{command_file};
syslog("local4|err", "omshell did not complete while updating DHCP reservations") unless $ok;
syslog("local4|err", "omshell did not complete while updating DHCP reservations")
unless $status eq 'completed';
}
######################################################
+8 -36
View File
@@ -10,13 +10,9 @@ BEGIN
use lib "$::XCATROOT/lib/perl";
use Getopt::Long;
use File::Temp qw(tempfile);
use Fcntl ':flock';
use IPC::Open3;
use POSIX qw/WNOHANG/;
use Symbol qw/gensym/;
use Time::HiRes qw(sleep);
use xCAT::DHCP::OmapiPolicy;
use xCAT::DHCP::OmapiRunner;
use xCAT::Table;
sub usage{
@@ -146,41 +142,17 @@ if($help){
$omshell_commands .= "close\n";
}
mkdir "/tmp/xcat" unless -d "/tmp/xcat";
my ($omshell, $command_file) = tempfile('omshell.XXXXXX', DIR => '/tmp/xcat', UNLINK => 0);
my $command = xCAT::DHCP::OmapiRunner->open_command_file();
my $omshell = ref($command) eq 'HASH' ? $command->{handle} : undef;
die "Unable to start omshell: $!" unless $omshell;
print $omshell $omshell_commands;
close($omshell);
my $pid = fork();
die "Unable to start omshell: $!" unless defined $pid;
if ($pid == 0) {
open(STDIN, '<', $command_file) or exit 127; ## no critic (InputOutput::RequireCheckedOpen)
open(STDOUT, '>', '/dev/null') or exit 127; ## no critic (InputOutput::RequireCheckedOpen)
open(STDERR, '>', '/dev/null') or exit 127; ## no critic (InputOutput::RequireCheckedOpen)
exec { $settings->{omshell_path} } $settings->{omshell_path};
exit 127;
}
for (1 .. 100) {
if (waitpid($pid, WNOHANG) == $pid) {
sleep 1.0;
unlink $command_file;
exit 0;
}
sleep 0.1;
}
kill 'TERM', $pid;
for (1 .. 20) {
if (waitpid($pid, WNOHANG) == $pid) {
unlink $command_file;
exit 0;
}
sleep 0.1;
}
kill 'KILL', $pid;
waitpid($pid, 0);
unlink $command_file;
my $status = xCAT::DHCP::OmapiRunner->run_command_file(
$command->{path}, $settings->{omshell_path}
);
die "Unable to start omshell: $!" if $status eq 'fork_error';
unlink $command->{path};
}else{
&usage;
exit 1;