Skip to content

Commit c43052d

Browse files
committed
WIP Dobby: method to transfer image to @Regions
I'm not sure what should be handled by what. I can totally see an argument for Dobby having a method 'transfer_image_to_region()', note singular and have the InABox reactor handle transferring to multiple regions. I can also see how ignoring those 422 errors is a bit weird to have by default, might be worth having the method accept an argument on whether to ignore specific errors or to just 'die "..." unless $res->is_success'
1 parent d229920 commit c43052d

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

lib/Dobby/Client.pm

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,60 @@ async sub delete_url ($self, $path) {
142142
return;
143143
}
144144

145+
async sub transfer_image_to_regions ($self, $image, $regions) {
146+
147+
my $image_id = $image->{id};
148+
149+
for my $region ($regions->@*) {
150+
next if grep { $_ eq $region } $image->{regions}->@*;
151+
152+
my $res = await $self->http->do_request(
153+
method => 'POST',
154+
uri => $self->api_base . "/images/$image_id/actions",
155+
headers => {
156+
'Authorization' => "Bearer " . $self->bearer_token,
157+
},
158+
159+
content_type => 'application/json',
160+
content => encode_json({
161+
type => 'transfer',
162+
region => $region,
163+
}),
164+
);
165+
166+
next if $res->is_success;
167+
168+
# # # notes
169+
# # # if an image has already been transferred we get a 422 code and this reply
170+
# # # {
171+
# # # "id": "unprocessable_entity",
172+
# # # "message": "This image has already been transferred to this region."
173+
# # # }
174+
# # # If an image transfer is in progress we get a 422 and this reply
175+
# # # {
176+
# # # "id": "unprocessable_entity",
177+
# # # "message": "The image is already being transferred to that region."
178+
# # # }
179+
# # # 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
180+
# # # 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
181+
# # # we need to handle that case, ideally we should just handle both
182+
183+
# Handle errors we expect
184+
# 1. We've already requested the transfer and it is still in progress
185+
# 2. We've raced and the transfer has completed since we got $image
186+
if (! $res->is_success && $res->code == 422) {
187+
my $json = $res->decoded_content(charset => undef);
188+
my $data = decode_json($json);
189+
# transfer already in progress
190+
next if $data->{message} eq "The image is already being transferred to that region.";
191+
# race!
192+
next if $data->{message} eq "This image has already been transferred to this region.";
193+
}
194+
195+
die "error replication image $image_id to $region: " . $res->as_string;
196+
}
197+
}
198+
145199
async sub create_droplet ($self, $arg) {
146200
state @required_keys = qw( name region size tags image ssh_keys );
147201

0 commit comments

Comments
 (0)