Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions lib/Dobby/Client.pm
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,60 @@ async sub delete_url ($self, $path) {
return;
}

async sub transfer_image_to_regions ($self, $image, $regions) {

my $image_id = $image->{id};

for my $region ($regions->@*) {
next if grep { $_ eq $region } $image->{regions}->@*;

my $res = await $self->http->do_request(
method => 'POST',
uri => $self->api_base . "/images/$image_id/actions",
headers => {
'Authorization' => "Bearer " . $self->bearer_token,
},

content_type => 'application/json',
content => encode_json({
type => 'transfer',
region => $region,
}),
);

next if $res->is_success;

# # # notes
# # # if an image has already been transferred we get a 422 code and this reply
# # # {
# # # "id": "unprocessable_entity",
# # # "message": "This image has already been transferred to this region."
# # # }
# # # If an image transfer is in progress we get a 422 and this reply
# # # {
# # # "id": "unprocessable_entity",
# # # "message": "The image is already being transferred to that region."
# # # }
# # # We shouldn't encounter the former (well small race between the last time we checked and the upcoming post) because we check in the for loop
# # # But we will definitely encounter cases where someone might try to spin up a box after the transfer has been requested but it isn't there yet
# # # we need to handle that case, ideally we should just handle both

# Handle errors we expect
# 1. We've already requested the transfer and it is still in progress
# 2. We've raced and the transfer has completed since we got $image
if (! $res->is_success && $res->code == 422) {
my $json = $res->decoded_content(charset => undef);
my $data = decode_json($json);
# transfer already in progress
next if $data->{message} eq "The image is already being transferred to that region.";
# race!
next if $data->{message} eq "This image has already been transferred to this region.";
}

die "error replication image $image_id to $region: " . $res->as_string;
}
}

async sub create_droplet ($self, $arg) {
state @required_keys = qw( name region size tags image ssh_keys );

Expand Down
2 changes: 2 additions & 0 deletions lib/Synergy/Reactor/InABox.pm
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ async sub handle_create ($self, $event, $switches) {
join ', ',
grep { $snapshot_regions{$_} } $self->box_datacentres->@*;

await $self->dobby->transfer_image_to_regions($snapshot, $self->box_datacentres);

if ($compatible_regions) {
return await $event->reply(
"I'm unable to create snapshot in region '$region'. Available compatible regions are $compatible_regions."
Expand Down