@@ -11,7 +11,7 @@ use mahler::{
1111use tokio:: sync:: RwLock ;
1212
1313use super :: util:: state;
14- use crate :: oci:: { Client as Docker , Error as DockerError , ImageUri } ;
14+ use crate :: oci:: { Client as Docker , Error as DockerError , ImageRef , ImageUri } ;
1515use crate :: oci:: { Credentials , RegistryAuth , RegistryAuthClient , RegistryAuthError } ;
1616use crate :: util:: types:: Uuid ;
1717
@@ -209,23 +209,34 @@ fn request_registry_token_for_new_images(
209209 release
210210 . services
211211 . iter ( )
212- . filter ( |( service_name, svc) | {
213- // if the service image has not been downloaded
214- !device. images . contains_key ( & svc. image ) &&
215- // and there is no service from a different release
212+ . filter_map ( |( svc_name, svc) | {
213+ if let ImageRef :: Uri ( img_uri) = & svc. image {
214+ Some ( ( svc_name, img_uri) )
215+ } else {
216+ None
217+ }
218+ } )
219+ . filter ( |( svc_name, svc_img) | {
220+ // ignore the image if it already exists
221+ if device. images . contains_key ( svc_img) {
222+ return false ;
223+ }
224+
216225 find_installed_service (
217226 & device,
218227 app_uuid. clone ( ) ,
219228 commit. clone ( ) ,
220- ( * service_name ) . clone ( ) ,
229+ ( * svc_name ) . clone ( ) ,
221230 )
222- // or there is a service and the digest doesn't match the target digest
231+ // if the image is for a new service or the existing service has a
232+ // different digest (which means a new download), then add it to the
233+ // authorization list
223234 . is_none_or ( |s| {
224- s. image . digest ( ) . is_none ( ) || s. image . digest ( ) != svc . image . digest ( )
235+ s. image . digest ( ) . is_none ( ) || s. image . digest ( ) != svc_img . digest ( )
225236 } )
226237 } )
227238 // then select the image
228- . map ( |( _, svc ) | & svc . image )
239+ . map ( |( _, svc_img ) | svc_img )
229240 } )
230241 } )
231242 . collect ( ) ;
@@ -265,29 +276,36 @@ fn fetch_release_images(
265276 let images_to_install: Vec < ImageUri > = tgt_release
266277 . services
267278 . into_iter ( )
268- . filter ( |( service_name, svc) | {
269- // if the service image has not been downloaded
270- !device. images . contains_key ( & svc. image ) &&
271- // and there is no service from a different release
279+ . filter_map ( |( svc_name, svc) | {
280+ if let ImageRef :: Uri ( img_uri) = svc. image {
281+ Some ( ( svc_name, img_uri) )
282+ } else {
283+ None
284+ }
285+ } )
286+ . filter ( |( svc_name, svc_img) | {
287+ // ignore the image if it already exists
288+ if device. images . contains_key ( svc_img) {
289+ return false ;
290+ }
291+
272292 find_installed_service (
273- & device,
274- app_uuid. clone ( ) ,
275- commit. clone ( ) ,
276- ( * service_name) . clone ( ) ,
277- )
278- // or if there is a service, then only chose it if it has the same digest
279- // as the target service
280- . is_none_or ( |s| {
281- s. image . digest ( ) . is_some ( ) && svc. image . digest ( ) == s. image . digest ( )
282- } )
293+ & device,
294+ app_uuid. clone ( ) ,
295+ commit. clone ( ) ,
296+ ( * svc_name) . clone ( ) ,
297+ )
298+ // select the image if it is for a new service or the existing service image has the
299+ // same digest (which means we are just re-tagging)
300+ . is_none_or ( |s| s. image . digest ( ) . is_some ( ) && svc_img. digest ( ) == s. image . digest ( ) )
283301 } )
284302 // remove duplicate digests
285- . fold ( Vec :: < ImageUri > :: new ( ) , |mut acc, ( _, svc ) | {
303+ . fold ( Vec :: < ImageUri > :: new ( ) , |mut acc, ( _, svc_img ) | {
286304 if acc
287305 . iter ( )
288- . all ( |img| img. digest ( ) . is_none ( ) || img. digest ( ) != svc . image . digest ( ) )
306+ . all ( |img| img. digest ( ) . is_none ( ) || img. digest ( ) != svc_img . digest ( ) )
289307 {
290- acc. push ( svc . image ) ;
308+ acc. push ( svc_img ) ;
291309 }
292310 acc
293311 } ) ;
@@ -415,18 +433,24 @@ fn fetch_service_image(
415433 Target ( tgt) : Target < TargetService > ,
416434 Args ( ( app_uuid, commit, service_name) ) : Args < ( Uuid , Uuid , String ) > ,
417435) -> Option < Task > {
418- // tell the planner to skip this task if the image already exists
419- if device. images . contains_key ( & tgt. image ) {
436+ let tgt_img = if let ImageRef :: Uri ( img) = tgt. image {
437+ // Skip this task if the image already exists
438+ if device. images . contains_key ( & img) {
439+ return None ;
440+ }
441+ img
442+ } else {
443+ // also skip if the target image is not a Uri
420444 return None ;
421- }
445+ } ;
422446
423447 // If there is a service with the same name in any other releases of the service
424448 // and the service image has as different digest then we skip the fetch as
425449 // that pull will need deltas and needs to be handled by another task
426450 if find_installed_service ( & device, app_uuid, commit, service_name)
427- . is_none_or ( |svc| svc. image . digest ( ) . is_some ( ) && tgt . image . digest ( ) == svc. image . digest ( ) )
451+ . is_none_or ( |svc| svc. image . digest ( ) . is_some ( ) && tgt_img . digest ( ) == svc. image . digest ( ) )
428452 {
429- return Some ( create_image. with_arg ( "image_name" , tgt . image ) ) ;
453+ return Some ( create_image. with_arg ( "image_name" , tgt_img ) ) ;
430454 }
431455
432456 None
@@ -443,7 +467,11 @@ fn install_service(
443467 Path ( job_path) : Path ,
444468) -> IO < Option < Service > , state:: ReadWriteError > {
445469 // Skip the task if the image for the service doesn't exist yet
446- if device. images . keys ( ) . all ( |img| img != & tgt. image ) {
470+ if let ImageRef :: Uri ( tgt_img) = & tgt. image {
471+ if !device. images . contains_key ( tgt_img) {
472+ return svc. into ( ) ;
473+ }
474+ } else {
447475 return svc. into ( ) ;
448476 }
449477
@@ -472,10 +500,13 @@ fn remove_image(
472500 // only remove the image if it not being used by any service
473501 if device. apps . values ( ) . any ( |app| {
474502 app. releases . values ( ) . any ( |release| {
475- release
476- . services
477- . values ( )
478- . any ( |s| s. image == image_name. clone ( ) )
503+ release. services . values ( ) . any ( |s| {
504+ if let ImageRef :: Uri ( s_img) = & s. image {
505+ s_img == & image_name
506+ } else {
507+ false
508+ }
509+ } )
479510 } )
480511 } ) {
481512 return img_ptr. into ( ) ;
0 commit comments