diff --git a/lib/OpenStack/MetaAPI.pm b/lib/OpenStack/MetaAPI.pm index 44ef017..943b5f5 100644 --- a/lib/OpenStack/MetaAPI.pm +++ b/lib/OpenStack/MetaAPI.pm @@ -101,31 +101,36 @@ sub create_vm { my $server_uid = $server->{id}; die "Failed to create server" unless _looks_valid_id($server_uid); - # we are going to wait for 5 minutes fpr the server - my $wait_time_limit = $opts{wait_time_limit} // $self->create_max_timeout; + # wait_timeout / wait_time_limit (legacy) control the polling deadline + my $wait_timeout = $opts{wait_timeout} // $opts{wait_time_limit} + // $self->create_max_timeout; + + # poll_interval controls how often we check server status + my $poll_interval = $opts{poll_interval} // $self->create_loop_sleep; my $now = time(); - my $max_time = $now + $wait_time_limit; + my $max_time = $now + $wait_timeout; my $server_is_ready; my $server_status; + my $last_status = 'UNKNOWN'; - # TODO: maybe add one alarm... while (time() < $max_time) { $server_status = $self->server_from_uid($server_uid); - if ( ref $server_status - && $server_status->{status} - && $server_status->{status} - && lc($server_status->{status}) eq 'active') { - $server_is_ready = 1; - last; + if (ref $server_status && $server_status->{status}) { + $last_status = $server_status->{status}; + if (lc($last_status) eq 'active') { + $server_is_ready = 1; + last; + } } - sleep $self->create_loop_sleep if $self->create_loop_sleep; + sleep $poll_interval if $poll_interval; } - die "Failed to create server: never came back as active" + die "Failed to create server $server_uid: " + . "status '$last_status' after ${wait_timeout}s timeout" unless $server_is_ready; # now add one IP to the server @@ -241,6 +246,8 @@ Create one server from one image with one floating IP, wait for the server to be security_group => 'default', # security group to use, by default use 'default' network => 'NETWORK_NAME or NETWORK_ID', # network group to use network_for_floating_ip => 'NETWORK_NAME or NETWORK_ID', + wait_timeout => 300, # optional, seconds to wait for ACTIVE (default: 300) + poll_interval => 5, # optional, seconds between status checks (default: 5) ); =head2 $api->delete_server( $server_id ); diff --git a/t/xtra-create-vm.t b/t/xtra-create-vm.t index d4360c4..7e8f5b6 100644 --- a/t/xtra-create-vm.t +++ b/t/xtra-create-vm.t @@ -88,8 +88,38 @@ ok $api, "got one api object" or die; like( dies { $create_vm->() }, - qr{Failed to create server: never came back as active}, - "server does not came back as active"); + qr{Failed to create server aaaaa-bbbb-ccccc-dddd: status 'UNKNOWN' after 2s timeout}, + "timeout die message includes server ID and last status"); + + note "attempt 2b: per-call wait_timeout and poll_interval"; + + { + # Reset to high defaults so only per-call opts apply + $api->create_max_timeout(600); + $api->create_loop_sleep(60); + + mock_get_request( + 'http://127.0.0.1:8774/v2.1/servers/aaaaa-bbbb-ccccc-dddd', + application_json(json_for_server()), + ); + + like( + dies { + $api->create_vm( + name => $SERVER_NAME, + image => $IMAGE_UID, + flavor => 'small', + key_name => 'My SSH Key', + network => 'net1', + network_for_floating_ip => $FLOATING_IP_NETWORK, + wait_timeout => 1, + poll_interval => 0, + ); + }, + qr{Failed to create server aaaaa-bbbb-ccccc-dddd: status 'UNKNOWN' after 1s timeout}, + "per-call wait_timeout and poll_interval override object defaults", + ); + } note "attempt 3";