Triggered by Gerrit: https://gerrit.opensdn.io/c/opensdn-io/tf-controller/+/3035 Obtained pipelines/main.groovy from git https://github.com/opensdn-io/tf-jenkins.git [Pipeline] Start of Pipeline [Pipeline] timestamps [Pipeline] { [Pipeline] timeout [2026-08-20T22:46:21.852Z] Timeout set to expire in 8 hr 0 min [Pipeline] { [Pipeline] node [2026-08-20T22:46:21.891Z] Running on slave-openstack-gz1_1 in /home/jenkins/workspace/pipeline-post-merge [Pipeline] { [Pipeline] stage [Pipeline] { (init) [Pipeline] cleanWs [2026-08-20T22:46:21.964Z] [WS-CLEANUP] Deleting project workspace... [2026-08-20T22:46:21.964Z] [WS-CLEANUP] Deferred wipeout is disabled by the job configuration... [2026-08-20T22:46:22.051Z] [WS-CLEANUP] done [Pipeline] checkout [2026-08-20T22:46:22.079Z] The recommended git tool is: git [2026-08-20T22:46:22.084Z] No credentials specified [2026-08-20T22:46:22.086Z] Cloning the remote Git repository [2026-08-20T22:46:22.089Z] Cloning repository https://github.com/opensdn-io/tf-jenkins.git [2026-08-20T22:46:22.089Z] > git init /home/jenkins/workspace/pipeline-post-merge/src/opensdn-io/tf-jenkins # timeout=10 [2026-08-20T22:46:22.094Z] Fetching upstream changes from https://github.com/opensdn-io/tf-jenkins.git [2026-08-20T22:46:22.094Z] > git --version # timeout=10 [2026-08-20T22:46:22.096Z] > git --version # 'git version 2.25.1' [2026-08-20T22:46:22.096Z] > git fetch --tags --force --progress -- https://github.com/opensdn-io/tf-jenkins.git +refs/heads/*:refs/remotes/origin/* # timeout=10 [2026-08-20T22:46:23.649Z] Avoid second fetch [2026-08-20T22:46:23.654Z] Checking out Revision 9c86492d4a22712d2c3b4ab27040cd93556012b4 (refs/remotes/origin/master) [2026-08-20T22:46:23.705Z] Commit message: "Merge "install cloud-init from site mirror"" [2026-08-20T22:46:23.641Z] > git config remote.origin.url https://github.com/opensdn-io/tf-jenkins.git # timeout=10 [2026-08-20T22:46:23.643Z] > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10 [2026-08-20T22:46:23.650Z] > git rev-parse refs/remotes/origin/master^{commit} # timeout=10 [2026-08-20T22:46:23.655Z] > git config core.sparsecheckout # timeout=10 [2026-08-20T22:46:23.657Z] > git checkout -f 9c86492d4a22712d2c3b4ab27040cd93556012b4 # timeout=10 [2026-08-20T22:46:23.706Z] > git rev-list --no-walk 9c86492d4a22712d2c3b4ab27040cd93556012b4 # timeout=10 [Pipeline] load [Pipeline] { (/home/jenkins/workspace/pipeline-post-merge/src/opensdn-io/tf-jenkins/pipelines/utils/gerrit.groovy) [Pipeline] } [Pipeline] // load [Pipeline] echo [2026-08-20T22:46:24.086Z] INFO: resolved gerrit URL is https://gerrit.opensdn.io/ [Pipeline] sh [2026-08-20T22:46:24.378Z] + /home/jenkins/workspace/pipeline-post-merge/src/opensdn-io/tf-jenkins/infra/gerrit/resolve_patchsets.py --gerrit https://gerrit.opensdn.io/ --review I33c9ce095ec5eb99d5f50eabf20f52dfd57df225 --branch master --changed_files --output /home/jenkins/workspace/pipeline-post-merge/patchsets-info.json [Pipeline] archiveArtifacts [2026-08-20T22:46:24.403Z] Archiving artifacts [Pipeline] sh [Pipeline] load [Pipeline] { (/home/jenkins/workspace/pipeline-post-merge/src/opensdn-io/tf-jenkins/pipelines/utils/gerrit.groovy) [Pipeline] } [Pipeline] // load [Pipeline] load [Pipeline] { (/home/jenkins/workspace/pipeline-post-merge/src/opensdn-io/tf-jenkins/pipelines/constants.groovy) [Pipeline] } [Pipeline] // load [Pipeline] load [Pipeline] { (/home/jenkins/workspace/pipeline-post-merge/src/opensdn-io/tf-jenkins/pipelines/utils/config.groovy) [Pipeline] } [Pipeline] // load [Pipeline] load [Pipeline] { (/home/jenkins/workspace/pipeline-post-merge/src/opensdn-io/tf-jenkins/pipelines/utils/jobs.groovy) [Pipeline] } [Pipeline] // load [Pipeline] load [Pipeline] { (/home/jenkins/workspace/pipeline-post-merge/src/opensdn-io/tf-jenkins/pipelines/utils/gate.groovy) [Pipeline] } [Pipeline] // load [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Pre-build) [Pipeline] echo [2026-08-20T22:46:26.031Z] Logs URL: http://nexus.gz1.opensdn.io:8082/jenkins_logs/gerrit/35/3035/2/post-merge_948 [Pipeline] echo [2026-08-20T22:46:26.053Z] terminate_runs_by_review_number: start [Pipeline] echo [2026-08-20T22:46:28.340Z] terminate_runs_by_review_number: terminated builds = [] [Pipeline] sh [Pipeline] echo [2026-08-20T22:46:28.652Z] Pipeline to run: post-merge [Pipeline] sh [Pipeline] sh [Pipeline] archiveArtifacts [2026-08-20T22:46:29.251Z] Archiving artifacts [Pipeline] readYaml [Pipeline] readYaml [Pipeline] readYaml [Pipeline] readYaml [Pipeline] readYaml [Pipeline] readYaml [Pipeline] readYaml [Pipeline] readYaml [Pipeline] readYaml [Pipeline] readYaml [Pipeline] readYaml [Pipeline] echo [2026-08-20T22:46:30.003Z] WARNING: project opensdn-io/tf-controller doesn't define pipeline post-merge [Pipeline] echo [2026-08-20T22:46:30.017Z] Streams from config: [:] [Pipeline] echo [2026-08-20T22:46:30.029Z] Jobs from config: [:] [Pipeline] echo [2026-08-20T22:46:30.043Z] Post Jobs from config: [:] [Pipeline] echo [2026-08-20T22:46:30.070Z] Notify gerrit verified=null, submit=false, msg= [2026-08-20T22:46:30.071Z] TF CI Build Started (post-merge) https://jenkins.opensdn.io/job/pipeline-post-merge/948/ [Pipeline] withCredentials [2026-08-20T22:46:30.092Z] Masking supported pattern matches of $GERRIT_API_PASSWORD [Pipeline] { [Pipeline] echo [2026-08-20T22:46:30.156Z] INFO: resolved gerrit URL is https://gerrit.opensdn.io/ [Pipeline] sh [2026-08-20T22:46:30.443Z] + /home/jenkins/workspace/pipeline-post-merge/src/opensdn-io/tf-jenkins/infra/gerrit/notify.py --gerrit https://gerrit.opensdn.io/ --user tf-gerrit --password **** --review I33c9ce095ec5eb99d5f50eabf20f52dfd57df225 --patchset 2 --branch master --message 'TF CI Build Started (post-merge) https://jenkins.opensdn.io/job/pipeline-post-merge/948/' [2026-08-20T22:46:30.444Z] DEBUG: Change: {'id': 'opensdn-io%2Ftf-controller~master~I33c9ce095ec5eb99d5f50eabf20f52dfd57df225', 'project': 'opensdn-io/tf-controller', 'branch': 'master', 'topic': 'route-target-lifecycle', 'attention_set': {}, 'removed_from_attention_set': {'1000003': {'account': {'_account_id': 1000003}, 'last_update': '2026-08-20 22:46:04.000000000', 'reason': 'Change was submitted'}, '1000001': {'account': {'_account_id': 1000001}, 'last_update': '2026-08-20 08:25:02.000000000', 'reason': 'removed on reply'}, '1000021': {'account': {'_account_id': 1000021}, 'last_update': '2026-08-20 22:46:04.000000000', 'reason': 'Change was submitted'}}, 'hashtags': [], 'change_id': 'I33c9ce095ec5eb99d5f50eabf20f52dfd57df225', 'subject': 'ST: do not leak the route-target Zookeeper index on a partial write', 'status': 'MERGED', 'created': '2026-08-06 06:10:53.000000000', 'updated': '2026-08-20 22:46:04.000000000', 'submitted': '2026-08-20 22:46:04.000000000', 'submitter': {'_account_id': 1000001}, 'insertions': 17, 'deletions': 4, 'total_comment_count': 4, 'unresolved_comment_count': 0, 'has_review_started': True, 'submission_id': '3035-route-target-lifecycle', 'meta_rev_id': '9ab53059e2f80a27318d2995802c318c5632713d', '_number': 3035, 'owner': {'_account_id': 1000021}, 'labels': {'Code-Review': {'all': [{'value': 2, 'date': '2026-08-20 08:24:54.000000000', 'permitted_voting_range': {'min': 2, 'max': 2}, '_account_id': 1000003}, {'value': 0, '_account_id': 1000001}], 'values': {'-2': 'This shall not be submitted', '-1': 'I would prefer this is not submitted as is', ' 0': 'No score', '+1': 'Looks good to me, but someone else must approve', '+2': 'Looks good to me, approved'}, 'description': '', 'default_value': 0}, 'Verified': {'all': [{'value': 0, '_account_id': 1000003}, {'value': 2, 'date': '2026-08-20 22:45:55.000000000', 'permitted_voting_range': {'min': 2, 'max': 2}, '_account_id': 1000001}], 'values': {'-2': 'Fails', '-1': 'Fails', ' 0': 'No score', '+1': 'Verified', '+2': 'Gating'}, 'description': '', 'default_value': 0}}, 'permitted_labels': {'Code-Review': [' 0', '+1', '+2'], 'Verified': ['+2']}, 'removable_labels': {}, 'removable_reviewers': [{'_account_id': 1000002}], 'reviewers': {'REVIEWER': [{'_account_id': 1000001}, {'_account_id': 1000003}], 'CC': [{'_account_id': 1000002}]}, 'pending_reviewers': {}, 'current_revision': '90b996a04263704921a1a64a90a0499ce169e55e', 'revisions': {'90b996a04263704921a1a64a90a0499ce169e55e': {'kind': 'NO_CODE_CHANGE', '_number': 2, 'created': '2026-08-20 08:24:48.000000000', 'uploader': {'_account_id': 1000003}, 'ref': 'refs/changes/35/3035/2', 'fetch': {'ssh': {'url': 'ssh://tf-gerrit@gerrit.opensdn.io:29418/opensdn-io/tf-controller', 'ref': 'refs/changes/35/3035/2'}, 'anonymous http': {'url': 'https://gerrit.opensdn.io/opensdn-io/tf-controller', 'ref': 'refs/changes/35/3035/2'}, 'http': {'url': 'https://tf-gerrit@gerrit.opensdn.io/a/opensdn-io/tf-controller', 'ref': 'refs/changes/35/3035/2'}}, 'commit': {'parents': [{'commit': '9112407ed0a26aaec3ee49b7513d267bf7e93597', 'subject': 'Switching to oneTBB: old includes removal'}], 'author': {'name': 'Charnsilp Chinprasert(Nipa)', 'email': 'justice.form@gmail.com', 'date': '2026-08-06 06:05:31.000000000', 'tz': 420}, 'committer': {'name': 'Andrey', 'email': 'andrey-mp@yandex.ru', 'date': '2026-08-20 08:24:48.000000000', 'tz': 0}, 'subject': 'ST: do not leak the route-target Zookeeper index on a partial write', 'message': 'ST: do not leak the route-target Zookeeper index on a partial write\n\nA route target is recorded in two places - an index in Zookeeper and a row in\nroute_target_table - and both alloc_route_target() and free_route_target()\nwrite them in two unguarded steps. An exception in between leaves one half\nbehind.\n\nThe two halves are not equally recoverable, because every read starts from the\nrow:\n\n rtgt_num = self.get_route_target(ri_fq_name) # Cassandra\n if rtgt_num < common.get_bgp_rtgt_min_id(asn):\n alloc_new = True\n else:\n rtgt_ri_fq_name_str = self.current_rt_allocator.read(rtgt_num) # ZK\n if (rtgt_ri_fq_name_str != ri_fq_name):\n alloc_new = True\n\nA row whose index is gone corrects itself: IndexAllocator.read() returns None,\nthe fq_name comparison fails, and a fresh index is allocated. An index whose\nrow is gone is never looked at again and is held until the cluster is rebuilt.\n\nBoth functions currently put the unrecoverable half last. alloc_route_target()\ntakes the index and then writes the row; free_route_target() deletes the row\nand then releases the index. Either failure leaks the index, and in the free\ncase it leaks it with no record of who holds it.\n\nMake the recoverable half the one that fails last: release the index if the\nrow cannot be written, and release the index before deleting the row. Neither\nchanges the success path or adds a call in the normal case.\n\nTested: tox -e pep8 passes; tox -e py39 gives 66 passed, 16 skipped, 0 failed,\nmatching the baseline. The suite shows no regression; it does not exercise a\npartial write, so it does not prove the leak is prevented - a test that forces\neach step to fail is still owed.\n\nCloses-Bug: https://github.com/OpenSDN-io/community/issues/139\nChange-Id: I33c9ce095ec5eb99d5f50eabf20f52dfd57df225\nSigned-off-by: Charnsilp Chinprasert(Nipa) \n'}, 'description': 'Edit commit message'}}, 'requirements': [], 'submit_records': [{'rule_name': 'gerrit~DefaultSubmitRule', 'status': 'CLOSED', 'labels': [{'label': 'Code-Review', 'status': 'OK', 'applied_by': {'_account_id': 1000003}}, {'label': 'Verified', 'status': 'OK', 'applied_by': {'_account_id': 1000001}}]}]} [2026-08-20T22:46:30.444Z] DEBUG: push message data: {'labels': {}, 'message': 'TF CI Build Started (post-merge) https://jenkins.opensdn.io/job/pipeline-post-merge/948/'} [Pipeline] } [Pipeline] // withCredentials [Pipeline] echo [2026-08-20T22:46:30.510Z] Notify discord for new job is started [Pipeline] echo [2026-08-20T22:46:30.555Z] INFO: resolved gerrit URL is https://gerrit.opensdn.io/ [Pipeline] echo [2026-08-20T22:46:30.578Z] Notify discord msg= [2026-08-20T22:46:30.578Z] The review was merged. [2026-08-20T22:46:30.578Z] [ST: do not leak the route-target Zookeeper index o](https://gerrit.opensdn.io/c/opensdn-io/tf-controller/+/3035) [Pipeline] withCredentials [2026-08-20T22:46:30.600Z] Masking supported pattern matches of $DISCORD_WEBHOOK_URL [Pipeline] { [Pipeline] writeFile [Pipeline] sh [2026-08-20T22:46:30.933Z] % Total % Received % Xferd Average Speed Time Time Time Current [2026-08-20T22:46:30.934Z] Dload Upload Total Spent Left Speed [2026-08-20T22:46:30.934Z] [2026-08-20T22:46:32.297Z] 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 [2026-08-20T22:46:32.553Z] 100 184 0 0 100 184 0 888 --:--:-- --:--:-- --:--:-- 884 [2026-08-20T22:46:32.553Z] 100 184 0 0 100 184 0 152 0:00:01 0:00:01 --:--:-- 152 [2026-08-20T22:46:32.553Z] 100 184 0 0 100 184 0 114 0:00:01 0:00:01 --:--:-- 114 [Pipeline] } [Pipeline] // withCredentials [Pipeline] } [Pipeline] // stage [Pipeline] echo [2026-08-20T22:46:32.680Z] Jobs results: [:] [Pipeline] stage [Pipeline] { (gerrit vote) [Pipeline] echo [2026-08-20T22:46:32.733Z] Notify gerrit verified=null, submit=false, msg= [2026-08-20T22:46:32.733Z] TF CI Build Succeeded (post-merge) in 0h 0m 6s [2026-08-20T22:46:32.733Z] [2026-08-20T22:46:32.733Z] Succeeded checks: [Pipeline] withCredentials [2026-08-20T22:46:32.753Z] Masking supported pattern matches of $GERRIT_API_PASSWORD [Pipeline] { [Pipeline] echo [2026-08-20T22:46:32.802Z] INFO: resolved gerrit URL is https://gerrit.opensdn.io/ [Pipeline] sh [2026-08-20T22:46:33.086Z] + /home/jenkins/workspace/pipeline-post-merge/src/opensdn-io/tf-jenkins/infra/gerrit/notify.py --gerrit https://gerrit.opensdn.io/ --user tf-gerrit --password **** --review I33c9ce095ec5eb99d5f50eabf20f52dfd57df225 --patchset 2 --branch master --message 'TF CI Build Succeeded (post-merge) in 0h 0m 6s [2026-08-20T22:46:33.086Z] [2026-08-20T22:46:33.086Z] Succeeded checks:' [2026-08-20T22:46:33.087Z] DEBUG: Change: {'id': 'opensdn-io%2Ftf-controller~master~I33c9ce095ec5eb99d5f50eabf20f52dfd57df225', 'project': 'opensdn-io/tf-controller', 'branch': 'master', 'topic': 'route-target-lifecycle', 'attention_set': {}, 'removed_from_attention_set': {'1000003': {'account': {'_account_id': 1000003}, 'last_update': '2026-08-20 22:46:04.000000000', 'reason': 'Change was submitted'}, '1000001': {'account': {'_account_id': 1000001}, 'last_update': '2026-08-20 08:25:02.000000000', 'reason': 'removed on reply'}, '1000021': {'account': {'_account_id': 1000021}, 'last_update': '2026-08-20 22:46:04.000000000', 'reason': 'Change was submitted'}}, 'hashtags': [], 'change_id': 'I33c9ce095ec5eb99d5f50eabf20f52dfd57df225', 'subject': 'ST: do not leak the route-target Zookeeper index on a partial write', 'status': 'MERGED', 'created': '2026-08-06 06:10:53.000000000', 'updated': '2026-08-20 22:46:30.000000000', 'submitted': '2026-08-20 22:46:04.000000000', 'submitter': {'_account_id': 1000001}, 'insertions': 17, 'deletions': 4, 'total_comment_count': 4, 'unresolved_comment_count': 0, 'has_review_started': True, 'submission_id': '3035-route-target-lifecycle', 'meta_rev_id': '0f9248d54b5e89b128a645a1a87a8c657ef959a9', '_number': 3035, 'owner': {'_account_id': 1000021}, 'labels': {'Code-Review': {'all': [{'value': 2, 'date': '2026-08-20 08:24:54.000000000', 'permitted_voting_range': {'min': 2, 'max': 2}, '_account_id': 1000003}, {'value': 0, '_account_id': 1000001}], 'values': {'-2': 'This shall not be submitted', '-1': 'I would prefer this is not submitted as is', ' 0': 'No score', '+1': 'Looks good to me, but someone else must approve', '+2': 'Looks good to me, approved'}, 'description': '', 'default_value': 0}, 'Verified': {'all': [{'value': 0, '_account_id': 1000003}, {'value': 2, 'date': '2026-08-20 22:45:55.000000000', 'permitted_voting_range': {'min': 2, 'max': 2}, '_account_id': 1000001}], 'values': {'-2': 'Fails', '-1': 'Fails', ' 0': 'No score', '+1': 'Verified', '+2': 'Gating'}, 'description': '', 'default_value': 0}}, 'permitted_labels': {'Code-Review': [' 0', '+1', '+2'], 'Verified': ['+2']}, 'removable_labels': {}, 'removable_reviewers': [{'_account_id': 1000002}], 'reviewers': {'REVIEWER': [{'_account_id': 1000001}, {'_account_id': 1000003}], 'CC': [{'_account_id': 1000002}]}, 'pending_reviewers': {}, 'current_revision': '90b996a04263704921a1a64a90a0499ce169e55e', 'revisions': {'90b996a04263704921a1a64a90a0499ce169e55e': {'kind': 'NO_CODE_CHANGE', '_number': 2, 'created': '2026-08-20 08:24:48.000000000', 'uploader': {'_account_id': 1000003}, 'ref': 'refs/changes/35/3035/2', 'fetch': {'ssh': {'url': 'ssh://tf-gerrit@gerrit.opensdn.io:29418/opensdn-io/tf-controller', 'ref': 'refs/changes/35/3035/2'}, 'anonymous http': {'url': 'https://gerrit.opensdn.io/opensdn-io/tf-controller', 'ref': 'refs/changes/35/3035/2'}, 'http': {'url': 'https://tf-gerrit@gerrit.opensdn.io/a/opensdn-io/tf-controller', 'ref': 'refs/changes/35/3035/2'}}, 'commit': {'parents': [{'commit': '9112407ed0a26aaec3ee49b7513d267bf7e93597', 'subject': 'Switching to oneTBB: old includes removal'}], 'author': {'name': 'Charnsilp Chinprasert(Nipa)', 'email': 'justice.form@gmail.com', 'date': '2026-08-06 06:05:31.000000000', 'tz': 420}, 'committer': {'name': 'Andrey', 'email': 'andrey-mp@yandex.ru', 'date': '2026-08-20 08:24:48.000000000', 'tz': 0}, 'subject': 'ST: do not leak the route-target Zookeeper index on a partial write', 'message': 'ST: do not leak the route-target Zookeeper index on a partial write\n\nA route target is recorded in two places - an index in Zookeeper and a row in\nroute_target_table - and both alloc_route_target() and free_route_target()\nwrite them in two unguarded steps. An exception in between leaves one half\nbehind.\n\nThe two halves are not equally recoverable, because every read starts from the\nrow:\n\n rtgt_num = self.get_route_target(ri_fq_name) # Cassandra\n if rtgt_num < common.get_bgp_rtgt_min_id(asn):\n alloc_new = True\n else:\n rtgt_ri_fq_name_str = self.current_rt_allocator.read(rtgt_num) # ZK\n if (rtgt_ri_fq_name_str != ri_fq_name):\n alloc_new = True\n\nA row whose index is gone corrects itself: IndexAllocator.read() returns None,\nthe fq_name comparison fails, and a fresh index is allocated. An index whose\nrow is gone is never looked at again and is held until the cluster is rebuilt.\n\nBoth functions currently put the unrecoverable half last. alloc_route_target()\ntakes the index and then writes the row; free_route_target() deletes the row\nand then releases the index. Either failure leaks the index, and in the free\ncase it leaks it with no record of who holds it.\n\nMake the recoverable half the one that fails last: release the index if the\nrow cannot be written, and release the index before deleting the row. Neither\nchanges the success path or adds a call in the normal case.\n\nTested: tox -e pep8 passes; tox -e py39 gives 66 passed, 16 skipped, 0 failed,\nmatching the baseline. The suite shows no regression; it does not exercise a\npartial write, so it does not prove the leak is prevented - a test that forces\neach step to fail is still owed.\n\nCloses-Bug: https://github.com/OpenSDN-io/community/issues/139\nChange-Id: I33c9ce095ec5eb99d5f50eabf20f52dfd57df225\nSigned-off-by: Charnsilp Chinprasert(Nipa) \n'}, 'description': 'Edit commit message'}}, 'requirements': [], 'submit_records': [{'rule_name': 'gerrit~DefaultSubmitRule', 'status': 'CLOSED', 'labels': [{'label': 'Code-Review', 'status': 'OK', 'applied_by': {'_account_id': 1000003}}, {'label': 'Verified', 'status': 'OK', 'applied_by': {'_account_id': 1000001}}]}]} [2026-08-20T22:46:33.087Z] DEBUG: push message data: {'labels': {}, 'message': 'TF CI Build Succeeded (post-merge) in 0h 0m 6s\n\nSucceeded checks:'} [Pipeline] } [Pipeline] // withCredentials [Pipeline] sh [Pipeline] archiveArtifacts [2026-08-20T22:46:33.450Z] Archiving artifacts [Pipeline] withCredentials [2026-08-20T22:46:33.491Z] Masking supported pattern matches of $LOGS_HOST_SSH_KEY [Pipeline] { [Pipeline] writeFile [Pipeline] sh [2026-08-20T22:46:33.819Z] Warning: Permanently added 'nexus.gz1.opensdn.io,212.233.90.199' (ECDSA) to the list of known hosts. [2026-08-20T22:46:34.380Z] Warning: Permanently added 'nexus.gz1.opensdn.io,212.233.90.199' (ECDSA) to the list of known hosts. [Pipeline] } [Pipeline] // withCredentials [Pipeline] } [Pipeline] // stage [Pipeline] echo [2026-08-20T22:46:35.083Z] URL of console output = https://jenkins.opensdn.io/job/pipeline-post-merge/948/consoleText [Pipeline] withCredentials [2026-08-20T22:46:35.109Z] Masking supported pattern matches of $LOGS_HOST_SSH_KEY [Pipeline] { [Pipeline] sh