2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-06-12 00:00:12 +00:00

Merge pull request #750 from zet809/add_pull_image_for_mkdocker

Add pull image for mkdocker
This commit is contained in:
chenglch
2016-03-08 02:58:18 -05:00

View File

@ -72,6 +72,7 @@ my %http_session_variable = ();
name => $host,
port => $port,
},
genreq_ptr => \&genreq;
http_req_method => $init_method,
http_req_url => $node_init_url,
node_app_state => $init_state,
@ -84,12 +85,10 @@ my %http_session_variable = ();
my %node_hash_variable = ();
# The function point used for mkdocker to generate http request, for other cmd it will point to &genreq;
my $genreq_ptr = \&genreq;
# The num of HTTP requests that is progressing
my $http_requests_in_progress = 0;
#-------------------------------------------------------
=head3 handled_commands
@ -164,11 +163,18 @@ my %command_states = (
},
mkdocker => {
all => {
genreq_ptr => \&genreq_for_mkdocker,
state_machine_engine => \&single_state_engine,
init_method => "POST",
init_url => "/containers/create?name=#NODE#",
init_state => "INIT_TO_WAIT_FOR_CREATE_DONE"
},
pullimage => {
state_machine_engine => \&single_state_engine,
init_method => "POST",
init_url => "/images/create?fromImage=#DOCKER_IMAGE#",
init_state => "INIT_TO_WAIT_FOR_IMAGE_PULL_DONE",
},
},
rmdocker => {
force => {
@ -248,6 +254,42 @@ sub http_state_code_info {
#-------------------------------------------------------
=head3 change_node_state
To change node state to the state specified, and then send out the HTTP request.
Input:
$node: the node to change state
$to_state_hash: the hash which store the destination state info
Return:
Usage example:
change_node_state($node, $command_states{$command}{$option});
=cut
#-------------------------------------------------------
sub change_node_state {
my $node = shift;
my $to_state_hash = shift;
my $node_hash = $node_hash_variable{$node};
$node_hash->{http_req_method} = $to_state_hash->{init_method};
$node_hash->{http_req_url} = $to_state_hash->{init_url};
$node_hash->{node_app_state} = $to_state_hash->{init_state};
$node_hash->{state_machine_engine} = $to_state_hash->{state_machine_engine};
$node_hash->{genreq_ptr} = $to_state_hash->{genreq_ptr};
if (!defined($node_hash->{genreq_ptr})) {
$node_hash->{genreq_ptr} = \&genreq;
}
if ($node_hash->{image} =~ /:/) {
$node_hash->{http_req_url} =~ s/#DOCKER_IMAGE#/$node_hash->{image}/;
} else {
$node_hash->{http_req_url} =~ s/#DOCKER_IMAGE#/$node_hash->{image}:latest/;
}
$node_hash->{http_req_url} =~ s/#NODE#/$node/;
sendreq($node, $node_hash);
return;
}
#-------------------------------------------------------
=head3 single_state_engine
The state_machine_engine to deal with http response
@ -258,7 +300,7 @@ sub http_state_code_info {
If there are any errors or msg, they will be outputed directly.
Else, nothing returned.
Usage example:
single_state_engine($sockfd, HTTP Response data);
single_state_engine($id, HTTP Response data);
=cut
@ -295,7 +337,18 @@ sub single_state_engine {
my $content_type = $data->header("content-type");
my $content_hash = undef;
if (defined($content_type) and $content_type =~ /json/i) {
$content_hash = decode_json $content;
if ($curr_state ne "INIT_TO_WAIT_FOR_IMAGE_PULL_DONE") {
$content_hash = decode_json $content;
}
else {
if ($content =~ /Status: Downloaded newer image/) {
}
elsif ($content =~ /\"error\":\"([^\"]*)\"/) {
@msg = ();
$msg[0] = [1, $1];
}
}
}
elsif (!defined($content_type)) {
$content_type = "undefined";
@ -348,6 +401,23 @@ sub single_state_engine {
}
}
elsif ($curr_state eq 'INIT_TO_WAIT_FOR_CREATE_DONE') {
if ($data->code eq '404') {
# To avoid pulling image loop
if (defined($node_hash_variable{$node}->{have_pulled_image})) {
return;
}
$global_callback->({node=>[{name=>[$node],"$info_flag"=>["Pull image $node_hash_variable{$node}->{image} start"]}]});
change_node_state($node, $command_states{mkdocker}{pullimage});
return;
}
}
elsif ($curr_state eq 'INIT_TO_WAIT_FOR_IMAGE_PULL_DONE') {
if ($data->is_success and !$msg[0]->[0]) {
$global_callback->({node=>[{name=>[$node],"$info_flag"=>["Pull image $node_hash_variable{$node}->{image} done"]}]});
$node_hash_variable{$node}->{have_pulled_image} = 1;
change_node_state($node, $command_states{mkdocker}{all});
return;
}
}
foreach my $tmp (@msg) {
@ -503,6 +573,9 @@ sub parse_args {
# No command-line arguments - use defaults
#############################################
if ( !defined( $args )) {
if ($cmd eq "rpower") {
return ([1, "No option specified for rpower"]);
}
return(0);
}
#############################################
@ -656,20 +729,13 @@ sub process_request {
my $init_url = undef;
my $init_state = undef;
my $state_machine_engine = undef;
my $genreq_ptr = undef;
my $mapping_hash = undef;
my $max_concur_session_allow = 20; # A variable can be set by caculated in the future
$mapping_hash = $command_states{$command}{$args->[0]};
unless($mapping_hash) {
$mapping_hash = $command_states{$command}{all};
}
unless ($mapping_hash) {
my $option = '';
if (defined($args->[0])) {
$option = $args->[0];
}
$callback->({error=>["Not support $command $option"], errorcode=>1});
return;
}
$init_method = $mapping_hash->{init_method};
$init_url = $mapping_hash->{init_url};
$state_machine_engine = $mapping_hash->{state_machine_engine};
@ -677,6 +743,10 @@ sub process_request {
if (!defined($init_state)) {
$init_state = "INIT_TO_WAIT_FOR_RSP";
}
$genreq_ptr = $mapping_hash->{genreq_ptr};
if (!defined($genreq_ptr)) {
$genreq_ptr = \&genreq;
}
if ($command eq 'lsdocker') {
my @new_noderange = ();
my $nodehm = xCAT::Table->new('nodehm');
@ -696,6 +766,7 @@ sub process_request {
$node_hash_variable{$node}->{http_req_url} = $node_init_url;
$node_hash_variable{$node}->{node_app_state} = $init_state;
$node_hash_variable{$node}->{state_machine_engine} = $state_machine_engine;
$node_hash_variable{$node}->{genreq_ptr} = $genreq_ptr;
}
else {
push @new_noderange, $node;
@ -732,6 +803,7 @@ sub process_request {
$node_hash_variable{$node}->{http_req_url} = $node_init_url;
$node_hash_variable{$node}->{node_app_state} = $init_state;
$node_hash_variable{$node}->{state_machine_engine} = $state_machine_engine;
$node_hash_variable{$node}->{genreq_ptr} = $genreq_ptr;
}
if (scalar(@errornodes)) {
$callback->({error=>["Docker host not set correct for @errornodes"], errorcode=>1});
@ -757,7 +829,6 @@ sub process_request {
$flagarg = $1;
}
}
$genreq_ptr = \&genreq_for_mkdocker;
my $nodetypetab = xCAT::Table->new('nodetype');
if (!defined($nodetypetab)) {
$callback->({error=>["Open table 'nodetype' failed"], errorcode=>1});
@ -848,8 +919,7 @@ sub process_request {
while ((scalar @nodeargs) and $http_requests_in_progress < $max_concur_session_allow) {
deal_with_rsp();
my $node = shift @nodeargs;
my $node_hash = $node_hash_variable{$node};
sendreq($node, $node_hash->{hostinfo}, $node_hash->{http_req_method}, $node_hash->{http_req_url});
sendreq($node, $node_hash_variable{$node});
}
if ($async->empty) {
last;
@ -981,38 +1051,34 @@ sub genreq_for_mkdocker {
my $content = encode_json \%info_hash;
return genreq($node, $dockerhost, $method, $api, $content);
}
#-------------------------------------------------------
=head3 sendreq
Based on the method, url create a http request and send out on the given SSL connection
Input:
Input:
$node: the docker container name
$dockerhost: hash, keys: name, port, user, pw, user, pw
$method: the http method to generate a http request
$url: the http url to generate a http request
$node_hash: the hash that store information for the $node
return: 0-undefine If no error
1-return generate http request failed;
2-return http request error message;
Usage example:
my $res = sendreq($node, \%dockerhost, 'GET', '/containers/$node/json');
my $res = sendreq($node, $node_hash);
=cut
#-------------------------------------------------------
sub sendreq {
my ($node, $dockerhost, $init_method, $init_url) = @_;
my $http_req = $genreq_ptr->($node, $dockerhost, $init_method, $init_url);
my ($node, $node_hash) = @_;
my $http_req = $node_hash->{genreq_ptr}->($node, $node_hash->{hostinfo}, $node_hash->{http_req_method}, $node_hash->{http_req_url});
# Need to Dumper to log file later
#print Dumper($http_req);
# print Dumper($http_req);
my $http_session_id = $async->add_with_opts($http_req, {});
$http_session_variable{$http_session_id} = $node;
$http_requests_in_progress++;
return undef;
}
1;