@@ -121,6 +121,7 @@ DEFAULT_DISTRO_BASES = [FEDORA]
121121LATEST = "latest"
122122QUAL_NONE = "unqualified"
123123QUAL_DISTRO = "distro-qualified"
124+ QUAL_FQIN = 'fqin'
124125
125126
126127_DISCOVERED_CONTAINER_ENGINES = []
@@ -405,6 +406,53 @@ def build(cli, target):
405406 fh .write (f"{ cid } { target .image_name ()} \n " )
406407
407408
409+ class QMatcher :
410+ """Push only tags that meet the specified criteria:
411+ all - all tags;
412+ unqualified - only unqualified tags (eg. latest);
413+ distro - only distribution base qualifed tags (eg. fedora-latest);
414+ fqin - only fully qualified tags (eg. default-centos-amd64);
415+ mixed - only fqin and unqualified tags;
416+ least-qualified (default) - exactly one tag, with the least
417+ number of qualifications
418+ """
419+
420+ def __init__ (self , key ):
421+ self .qualifications = []
422+ self .count = 0
423+ self .max_matches = 0
424+
425+ if not key or key == "least-qualified" :
426+ self .qualifications = [QUAL_NONE , QUAL_DISTRO , QUAL_FQIN ]
427+ self .max_matches = 1
428+ elif key == "all" :
429+ pass
430+ elif key == "mixed" :
431+ self .qualifications = [QUAL_NONE , QUAL_FQIN ]
432+ else :
433+ try :
434+ mq = {
435+ "unqualified" : QUAL_NONE ,
436+ "distro" : QUAL_DISTRO ,
437+ "fqin" : QUAL_FQIN ,
438+ }[key ]
439+ except KeyError :
440+ raise argparse .ArgumentTypeError (
441+ "value must be one of:"
442+ " all, least-qualified, unqualified, distro, fqin;"
443+ f" not { key } "
444+ )
445+ self .qualifications = [mq ]
446+
447+ def __call__ (self , qv ):
448+ if self .max_matches and self .count >= self .max_matches :
449+ return False
450+ if not self .qualifications or qv in self .qualifications :
451+ self .count += 1
452+ return True
453+ return False
454+
455+
408456def push (cli , target ):
409457 """Command to push images."""
410458 if cli .push_state == "rebuild" :
@@ -415,15 +463,18 @@ def push(cli, target):
415463 except subprocess .CalledProcessError :
416464 build (cli , target )
417465
466+ to_push = []
418467 push_name = target .image_name ()
419- for tag , _ in target .additional_tags :
468+ for tag , qual in target .additional_tags :
420469 if tag in ("latest" , "nightly" ):
421- push_name = target .image_name (tag = tag )
422- break
470+ to_push .append ((target .image_name (tag = tag ), qual ))
423471 if tag .endswith (("-latest" , "-nightly" )):
424- push_name = target .image_name (tag = tag )
425- break
426- container_push (cli , push_name )
472+ to_push .append ((target .image_name (tag = tag ), qual ))
473+ to_push .append ((push_name , QUAL_FQIN ))
474+ qmatcher = cli .push_selected_tags or QMatcher ("" )
475+ for push_name , tag_qual in to_push :
476+ if qmatcher (tag_qual ):
477+ container_push (cli , push_name )
427478
428479
429480def print_buildfile (cli , target ):
@@ -540,6 +591,11 @@ def main():
540591 "exists - image exists; rebuild - image must be rebuilt."
541592 ),
542593 )
594+ parser .add_argument (
595+ "--push-selected-tags" ,
596+ type = QMatcher ,
597+ help = QMatcher .__doc__
598+ )
543599 parser .add_argument (
544600 "--buildfile-prefix" ,
545601 default = ".build." ,
0 commit comments