2121#
2222
2323#
24- # Copyright 2024 OmniOS Community Edition (OmniOSce) Association.
24+ # Copyright 2025 OmniOS Community Edition (OmniOSce) Association.
2525# Copyright 2024 Oxide Computer Company
2626# Copyright (c) 2007, 2024, Oracle and/or its affiliates.
2727#
4141# Environment variables
4242#
4343# PKG_IMAGE - root path of target image
44- # PKG_IMAGE_TYPE [entire, partial, user] - type of image
45- # XXX or is this in the Image configuration?
44+ # PKG_SUCCESS_ON_NOP - when an operation completes with nothing to do, exit with
45+ # the success code (0) instead of the NOP one (4).
4646
4747try :
4848 import pkg .site_paths
200200tmpdirs = []
201201tmpfiles = []
202202
203+ EXIT_NOP_VAL = EXIT_OK if os .environ .get ("PKG_SUCCESS_ON_NOP" ) else EXIT_NOP
204+
203205
204206@atexit .register
205207def cleanup ():
@@ -620,7 +622,8 @@ def print_cmds(cmd_list, cmd_dic):
620622 --help or -?
621623
622624Environment:
623- PKG_IMAGE"""
625+ PKG_IMAGE
626+ PKG_SUCCESS_ON_NOP"""
624627 )
625628 )
626629 else :
@@ -898,6 +901,8 @@ def gen(meta=False):
898901 if errors :
899902 _generate_error_messages (out_json ["status" ], errors )
900903
904+ if out_json ["status" ] == EXIT_NOP :
905+ return EXIT_NOP_VAL
901906 return out_json ["status" ]
902907
903908
@@ -2499,7 +2504,7 @@ def __api_op(
24992504 if _op == PKG_OP_FIX and _noexecute and _quiet_plan :
25002505 return _verify_exit_code (_api_inst )
25012506 if _api_inst .planned_nothingtodo ():
2502- return EXIT_NOP
2507+ return EXIT_NOP_VAL
25032508 if _noexecute or _stage == API_STAGE_PLAN :
25042509 return EXIT_OK
25052510 else :
@@ -2818,6 +2823,8 @@ def __handle_client_json_api_output(out_json, op, api_inst):
28182823 display_repo_failures (out_json ["data" ]["repo_status" ])
28192824
28202825 __display_plan_messages (api_inst , frozenset ([OP_STAGE_PREP , OP_STAGE_EXEC ]))
2826+ if out_json ["status" ] == EXIT_NOP :
2827+ return EXIT_NOP_VAL
28212828 return out_json ["status" ]
28222829
28232830
@@ -3525,7 +3532,7 @@ def autoremove(
35253532
35263533 if not pargs :
35273534 msg (_ ("No removable packages for this image." ))
3528- return EXIT_NOP
3535+ return EXIT_NOP_VAL
35293536
35303537 out_json = client_api ._uninstall (
35313538 PKG_OP_UNINSTALL ,
@@ -3602,6 +3609,8 @@ def verify(
36023609
36033610 # Since the verify output has been handled by display_plan_cb, only
36043611 # status code needs to be returned.
3612+ if out_json ["status" ] == EXIT_NOP :
3613+ return EXIT_NOP_VAL
36053614 return out_json ["status" ]
36063615
36073616
@@ -3714,6 +3723,8 @@ def fix(
37143723 if "errors" in out_json :
37153724 _generate_error_messages (out_json ["status" ], out_json ["errors" ], cmd = op )
37163725
3726+ if out_json ["status" ] == EXIT_NOP :
3727+ return EXIT_NOP_VAL
37173728 return out_json ["status" ]
37183729
37193730
@@ -3937,7 +3948,7 @@ def set_mediator(
39373948 return EXIT_OOPS
39383949 else :
39393950 msg (_ ("No changes required." ))
3940- return EXIT_NOP
3951+ return EXIT_NOP_VAL
39413952
39423953 if api_inst .get_dehydrated_publishers ():
39433954 msg (
@@ -4038,7 +4049,7 @@ def unset_mediator(
40384049 return EXIT_OOPS
40394050 else :
40404051 msg (_ ("No changes required." ))
4041- return EXIT_NOP
4052+ return EXIT_NOP_VAL
40424053
40434054 if not quiet :
40444055 __display_plan (api_inst , verbose , noexecute )
@@ -4172,7 +4183,7 @@ def unfreeze(api_inst, args):
41724183 try :
41734184 pkgs = api_inst .freeze_pkgs (pargs , unfreeze = True , dry_run = dry_run )
41744185 if not pkgs :
4175- return EXIT_NOP
4186+ return EXIT_NOP_VAL
41764187 for s in pkgs :
41774188 logger .info (_ ("{0} was unfrozen." ).format (s ))
41784189 return EXIT_OK
@@ -5594,6 +5605,8 @@ def publisher_set(
55945605 add_info = {"repo_uri" : repo_uri },
55955606 )
55965607
5608+ if out_json ["status" ] == EXIT_NOP :
5609+ return EXIT_NOP_VAL
55975610 return out_json ["status" ]
55985611
55995612
@@ -5608,6 +5621,8 @@ def publisher_unset(api_inst, pargs):
56085621 out_json ["status" ], out_json ["errors" ], cmd = "unset-publisher"
56095622 )
56105623
5624+ if out_json ["status" ] == EXIT_NOP :
5625+ return EXIT_NOP_VAL
56115626 return out_json ["status" ]
56125627
56135628
@@ -7202,7 +7217,7 @@ def update_format(api_inst, pargs):
72027217 return EXIT_OK
72037218
72047219 logger .info (_ ("Image format already current." ))
7205- return EXIT_NOP
7220+ return EXIT_NOP_VAL
72067221
72077222
72087223def print_version (pargs ):
0 commit comments