mirror of
https://github.com/containers/skopeo.git
synced 2025-05-07 15:36:31 +00:00
Compare commits
435 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1942cd2ba7 | ||
|
c228b1dba4 | ||
|
6c3096231c | ||
|
f8432950fa | ||
|
7ef7c49749 | ||
|
2bd609a0dd | ||
|
0f95b2bff9 | ||
|
159095c102 | ||
|
4d32babb91 | ||
|
eff578f537 | ||
|
bb26ea90f9 | ||
|
4c55fce106 | ||
|
ee84e9ae0a | ||
|
5cf5a11e04 | ||
|
47bf2b4ef7 | ||
|
320a3e0775 | ||
|
9bf0c3bf7c | ||
|
ed34be71c6 | ||
|
32b8827d78 | ||
|
3755a3db63 | ||
|
44877b3af2 | ||
|
f4d30802b2 | ||
|
d66183b129 | ||
|
b74989dfbc | ||
|
25481e1a88 | ||
|
990ac07ff5 | ||
|
53a1b69591 | ||
|
c5ccf21893 | ||
|
f9e03e6c04 | ||
|
b39bf85a1a | ||
|
a6ff545f30 | ||
|
4920d7f172 | ||
|
c7dca2e3ac | ||
|
5b135b92a8 | ||
|
119816b17c | ||
|
f5c34db79d | ||
|
ddc2848b66 | ||
|
b6b6415286 | ||
|
610f30db60 | ||
|
f7ab0ed03a | ||
|
ecdf380b0c | ||
|
0e68f7bebd | ||
|
c6d7c5916a | ||
|
edfeb73504 | ||
|
f37a82cddf | ||
|
ba2f8b7ace | ||
|
11fc49b491 | ||
|
b78fa41e42 | ||
|
e8d9f916e0 | ||
|
da1bf9f7e3 | ||
|
5b0b0d3954 | ||
|
5b30cfe29c | ||
|
d62cbd6178 | ||
|
7983f20adb | ||
|
8d000f4522 | ||
|
1f49b2c0c0 | ||
|
f745bb46bc | ||
|
a31470d7a4 | ||
|
ec21960402 | ||
|
1a38d97653 | ||
|
115f3727e8 | ||
|
49569bcf69 | ||
|
e7e09255b4 | ||
|
dd71592115 | ||
|
9c0f31dcce | ||
|
9fda7e7304 | ||
|
a0799484c8 | ||
|
603d37c588 | ||
|
a51828764c | ||
|
cb7a78c860 | ||
|
b8637922e2 | ||
|
48abc39c54 | ||
|
56ccf09c68 | ||
|
ceabd93f4a | ||
|
03fa889da5 | ||
|
c87f3aeaac | ||
|
15132e6c1e | ||
|
e7fe80b5df | ||
|
4080a631b1 | ||
|
b88f8eccaa | ||
|
cc743c3c0f | ||
|
a88629df99 | ||
|
91c6aa613d | ||
|
9d3331be7b | ||
|
d00ea33dfa | ||
|
0f5d87a9c0 | ||
|
7bd0dc216f | ||
|
5d0807795d | ||
|
547141ce57 | ||
|
1de2d3bad9 | ||
|
a185498c73 | ||
|
070f2bcfaf | ||
|
fad5a31a42 | ||
|
41e4b1b7ac | ||
|
5744b9b49d | ||
|
e9340fbc69 | ||
|
934ea727a4 | ||
|
22ab1a3717 | ||
|
8a44fe6c8b | ||
|
2d79fec20c | ||
|
c7aaed7397 | ||
|
9d73060a2e | ||
|
0283441cf1 | ||
|
5c968d67b8 | ||
|
690b1ef3e3 | ||
|
841a1b61ae | ||
|
8c78c03347 | ||
|
8c2eff1dae | ||
|
a5916e63cc | ||
|
f88186e688 | ||
|
ff462b3dad | ||
|
a3ffb772e1 | ||
|
8c20592d78 | ||
|
44d0f7103a | ||
|
20746ae273 | ||
|
64361bde06 | ||
|
955233070b | ||
|
bd1ac4668f | ||
|
2b3701b7be | ||
|
59ec554738 | ||
|
83d0e76b83 | ||
|
04d65888a3 | ||
|
958d586c45 | ||
|
137a912c55 | ||
|
dbf619c027 | ||
|
52895bc6cd | ||
|
d18677e479 | ||
|
b78a415987 | ||
|
0eb4ad2f54 | ||
|
5eba061489 | ||
|
9764c99dbd | ||
|
54d235403a | ||
|
a81cb65fac | ||
|
7d6169d219 | ||
|
85fa4dff42 | ||
|
8380f284c7 | ||
|
ed0efc6932 | ||
|
3315da48b5 | ||
|
ab53f64473 | ||
|
c737e5daea | ||
|
653db36664 | ||
|
0633de6350 | ||
|
6483de4894 | ||
|
3d2c80f58f | ||
|
b5a13bccfd | ||
|
eae9e8862c | ||
|
392aa3f70f | ||
|
b68afb1a73 | ||
|
0eb0ac3707 | ||
|
2a47dff7e1 | ||
|
631555fc83 | ||
|
83efeea4f3 | ||
|
da5c8d6e7b | ||
|
deda96636b | ||
|
17ea741413 | ||
|
fb777d3906 | ||
|
bf5987896a | ||
|
568d5d1c6f | ||
|
f333a897f6 | ||
|
1866ecbda2 | ||
|
f7801f77cc | ||
|
b116c5bdce | ||
|
e288827449 | ||
|
27baed919d | ||
|
4863e05f5f | ||
|
a71a8b4c48 | ||
|
4541d649a6 | ||
|
96f3804385 | ||
|
be26f2eb2f | ||
|
e9755957df | ||
|
74488c4b86 | ||
|
2a3c8ee5b1 | ||
|
87f199fbaf | ||
|
f423f01d1b | ||
|
c5eaf49918 | ||
|
186e9b4f0b | ||
|
8896960688 | ||
|
f818827f6d | ||
|
0c25d2c9fb | ||
|
bae8ccd7fb | ||
|
181429435e | ||
|
293ac065b7 | ||
|
e354a1431a | ||
|
34f0644177 | ||
|
0a73f20a51 | ||
|
fa1762f52b | ||
|
15f69ac611 | ||
|
33a629dd7a | ||
|
78d7940b94 | ||
|
bc57843bdf | ||
|
8d3fb4b390 | ||
|
5e0eeadd93 | ||
|
c0cc7ed28a | ||
|
3161b9faf8 | ||
|
602c121f51 | ||
|
4da797e353 | ||
|
7fbdd71411 | ||
|
3f66d002f2 | ||
|
5fece3398f | ||
|
43d066e0ce | ||
|
194619b0f8 | ||
|
142f20f78e | ||
|
10a9e24d0e | ||
|
6ad77a1bc4 | ||
|
03ca12ed56 | ||
|
9b96038384 | ||
|
bda9935e0c | ||
|
01ad0ed01c | ||
|
61ec80a222 | ||
|
60b5f0e814 | ||
|
f240ce07ac | ||
|
f291e8868b | ||
|
ee6181427f | ||
|
cb58f402f4 | ||
|
0fd65fb746 | ||
|
e39efb10e1 | ||
|
7da6ea07ca | ||
|
9ceee81a48 | ||
|
6d2672c924 | ||
|
dcf8a16c6a | ||
|
b113a2de35 | ||
|
4c9ec00ae4 | ||
|
9166a97bbb | ||
|
795705e41c | ||
|
bebbbaee46 | ||
|
2f45e4888a | ||
|
6b13950b11 | ||
|
f02a396ce5 | ||
|
115a6de9a6 | ||
|
a4c46d491f | ||
|
a817006786 | ||
|
dd5ce5d93e | ||
|
229c9fadc1 | ||
|
0d16d65dc5 | ||
|
6e0b7a126e | ||
|
b53eaf47f3 | ||
|
b9620327ab | ||
|
502f0cae62 | ||
|
3151e088bf | ||
|
02917be5f6 | ||
|
d38276137e | ||
|
f64a376157 | ||
|
df598d7f5b | ||
|
d74fae1766 | ||
|
17da582650 | ||
|
d2357b38fa | ||
|
38e29cdfb6 | ||
|
5af7b5dba1 | ||
|
84558d451d | ||
|
bbaa4b97d4 | ||
|
39dccc2aae | ||
|
ebf2eac05a | ||
|
d17c809348 | ||
|
88aad2e56b | ||
|
3e657b1f70 | ||
|
815ee59f7f | ||
|
d99c8d25ba | ||
|
ef518e3bad | ||
|
299848119c | ||
|
f616003b98 | ||
|
379ea70912 | ||
|
f35c536efa | ||
|
b97655fa16 | ||
|
9d0d1f3823 | ||
|
a79286cfa2 | ||
|
b6086ab75f | ||
|
0a1358dce6 | ||
|
37ff33dd55 | ||
|
0847edc556 | ||
|
7a0790b71f | ||
|
527a8655a5 | ||
|
19c7373efa | ||
|
b95b8b2815 | ||
|
ce8e984694 | ||
|
68ff5596b1 | ||
|
0763578dd6 | ||
|
f3af6d84a9 | ||
|
dc6c287304 | ||
|
2eb81856a4 | ||
|
ff5f4aaf3f | ||
|
cd71084908 | ||
|
3f82e0b23a | ||
|
44dbc156e1 | ||
|
8c3c22204c | ||
|
4d940944fb | ||
|
779a795896 | ||
|
388c50cbb7 | ||
|
77bb7e44a1 | ||
|
bedd5ea6c9 | ||
|
8ec36afef9 | ||
|
7cf3d3d1d6 | ||
|
b269085cd6 | ||
|
b3c36dbfd5 | ||
|
08e80b74a5 | ||
|
6d813c8ddf | ||
|
658c16afa3 | ||
|
49b43551d8 | ||
|
6ef29fd327 | ||
|
6bc2d13da8 | ||
|
25a4f08ee2 | ||
|
26f6b12a20 | ||
|
2a39d37cc8 | ||
|
5bf59a3706 | ||
|
3ccc89bb4a | ||
|
d244a61155 | ||
|
513a4f1ab3 | ||
|
7649059a0d | ||
|
dcf937e170 | ||
|
017cdf3255 | ||
|
2ac5beab4d | ||
|
e33585367a | ||
|
60a609bec8 | ||
|
3ebe3fbff0 | ||
|
2b6c7ad225 | ||
|
ceef4fd063 | ||
|
eb5bdfa94a | ||
|
ea61840040 | ||
|
0ed9eb1d96 | ||
|
1d70f69326 | ||
|
0872441c69 | ||
|
591851356c | ||
|
273e2d0c60 | ||
|
de2249ab3b | ||
|
8d325c332e | ||
|
0a90de625b | ||
|
4bad19ccff | ||
|
12b94decb5 | ||
|
463f0663f3 | ||
|
3cb058221f | ||
|
6b69928e1b | ||
|
2ee73922cc | ||
|
84562998c3 | ||
|
57eb3d2368 | ||
|
5848194b9b | ||
|
d4e8198106 | ||
|
49ba503590 | ||
|
3d33861439 | ||
|
50159e219c | ||
|
02edf9bce9 | ||
|
d91a6df64f | ||
|
37fbdd5e75 | ||
|
b8e0096809 | ||
|
8d04b4a9f6 | ||
|
a694164b16 | ||
|
f3d7b25bde | ||
|
9bfc125bed | ||
|
1c72e39720 | ||
|
a37421560d | ||
|
a75ed81668 | ||
|
4a43163fba | ||
|
f2220f960d | ||
|
c9dc0ef01e | ||
|
d84b1267ef | ||
|
763c5555aa | ||
|
9821af6f11 | ||
|
04ca9ed686 | ||
|
3bcba04d57 | ||
|
47aae0d334 | ||
|
836f2814bd | ||
|
8e3d109ef4 | ||
|
5e754557b8 | ||
|
3eacbe5ae2 | ||
|
7a2e66af24 | ||
|
d0411727aa | ||
|
16b6f0ade5 | ||
|
d5ac962b5e | ||
|
31e471f9a3 | ||
|
05567b7d64 | ||
|
cc4be6a404 | ||
|
ae51021023 | ||
|
2e7afb7ff3 | ||
|
874350b8f0 | ||
|
47a25ea926 | ||
|
269b2f86af | ||
|
3290caf850 | ||
|
99e3c44865 | ||
|
dc507579bc | ||
|
6d6d5b7b1c | ||
|
f4dae8362b | ||
|
78ddfd9dd5 | ||
|
a7ed170cb5 | ||
|
e46c71c302 | ||
|
a71fa6dbc2 | ||
|
549fc86253 | ||
|
7001d7014e | ||
|
cca855ac6e | ||
|
7c10c77c5b | ||
|
2ffc4ec356 | ||
|
ebf35ce38f | ||
|
086701bd75 | ||
|
9db48e50bc | ||
|
9644304892 | ||
|
1523edca6a | ||
|
a80f634f60 | ||
|
4a35c66cae | ||
|
4d80bf8c7d | ||
|
39308abb37 | ||
|
2db09313ac | ||
|
905c674dc2 | ||
|
95f6eac4a0 | ||
|
d7c99d50a5 | ||
|
dbf465d6ea | ||
|
55abe69da7 | ||
|
439dd5f403 | ||
|
40e7bcadc4 | ||
|
f0b07848dc | ||
|
a384105b32 | ||
|
8b6774b4a5 | ||
|
de7e8dbfa1 | ||
|
e294a38099 | ||
|
a1b5b96151 | ||
|
c3e2b20299 | ||
|
8f2a7c65ff | ||
|
812a02af41 | ||
|
09f282e468 | ||
|
5980989f66 | ||
|
9fd98112e4 | ||
|
cd3eb8b19b | ||
|
122bf968cf | ||
|
d39f17c995 | ||
|
149fec0a88 | ||
|
8197722446 | ||
|
d77f71530f | ||
|
e779ef5eb8 | ||
|
c941d813f3 | ||
|
a6239eec70 | ||
|
b412ed6e3a | ||
|
8b4cda842f | ||
|
58ff9fdb27 | ||
|
6baa928c1b | ||
|
177d4adb20 | ||
|
695538a31a | ||
|
4baf4fe9a2 | ||
|
758def9a12 | ||
|
e32dfefbfd |
51
.cirrus.yml
51
.cirrus.yml
@ -21,7 +21,7 @@ env:
|
|||||||
SCRIPT_BASE: "./contrib/cirrus"
|
SCRIPT_BASE: "./contrib/cirrus"
|
||||||
|
|
||||||
# Google-cloud VM Images
|
# Google-cloud VM Images
|
||||||
IMAGE_SUFFIX: "c20240102t155643z-f39f38d13"
|
IMAGE_SUFFIX: "c20250422t130822z-f42f41d13"
|
||||||
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
|
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
|
||||||
|
|
||||||
# Container FQIN's
|
# Container FQIN's
|
||||||
@ -62,12 +62,12 @@ doccheck_task:
|
|||||||
cpu: 4
|
cpu: 4
|
||||||
memory: 8
|
memory: 8
|
||||||
env:
|
env:
|
||||||
BUILDTAGS: &withopengpg 'btrfs_noversion libdm_no_deferred_remove containers_image_openpgp'
|
BUILDTAGS: &withopengpg 'containers_image_openpgp'
|
||||||
script: |
|
script: |
|
||||||
# TODO: Can't use 'runner.sh setup' inside container. However,
|
# TODO: Can't use 'runner.sh setup' inside container. However,
|
||||||
# removing the pre-installed package is the only necessary step
|
# removing the pre-installed package is the only necessary step
|
||||||
# at the time of this comment.
|
# at the time of this comment.
|
||||||
dnf erase -y skopeo # Guarantee non-interference
|
dnf remove -y skopeo # Guarantee non-interference
|
||||||
"${SKOPEO_PATH}/${SCRIPT_BASE}/runner.sh" build
|
"${SKOPEO_PATH}/${SCRIPT_BASE}/runner.sh" build
|
||||||
"${SKOPEO_PATH}/${SCRIPT_BASE}/runner.sh" doccheck
|
"${SKOPEO_PATH}/${SCRIPT_BASE}/runner.sh" doccheck
|
||||||
|
|
||||||
@ -81,20 +81,33 @@ osx_task:
|
|||||||
$CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*'
|
$CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*'
|
||||||
depends_on:
|
depends_on:
|
||||||
- validate
|
- validate
|
||||||
macos_instance:
|
persistent_worker: &mac_pw
|
||||||
image: ghcr.io/cirruslabs/macos-ventura-base:latest
|
labels:
|
||||||
setup_script: |
|
os: darwin
|
||||||
export PATH=$GOPATH/bin:$PATH
|
arch: arm64
|
||||||
brew update
|
purpose: prod
|
||||||
brew install gpgme go go-md2man
|
env:
|
||||||
make tools
|
CIRRUS_WORKING_DIR: "$HOME/ci/task-${CIRRUS_TASK_ID}"
|
||||||
test_script: |
|
# Prevent cache-pollution fron one task to the next.
|
||||||
export PATH=$GOPATH/bin:$PATH
|
GOPATH: "$CIRRUS_WORKING_DIR/.go"
|
||||||
go version
|
GOCACHE: "$CIRRUS_WORKING_DIR/.go/cache"
|
||||||
go env
|
GOENV: "$CIRRUS_WORKING_DIR/.go/support"
|
||||||
make validate-local test-unit-local bin/skopeo
|
GOSRC: "$HOME/ci/task-${CIRRUS_TASK_ID}"
|
||||||
sudo make install
|
TMPDIR: "/private/tmp/ci"
|
||||||
/usr/local/bin/skopeo -v
|
# This host is/was shared with potentially many other CI tasks.
|
||||||
|
# The previous task may have been canceled or aborted.
|
||||||
|
prep_script: &mac_cleanup "contrib/cirrus/mac_cleanup.sh"
|
||||||
|
test_script:
|
||||||
|
- export PATH=$GOPATH/bin:$PATH
|
||||||
|
- go version
|
||||||
|
- go env
|
||||||
|
- make tools
|
||||||
|
- make validate-local test-unit-local bin/skopeo
|
||||||
|
- bin/skopeo -v
|
||||||
|
# This host is/was shared with potentially many other CI tasks.
|
||||||
|
# Ensure nothing is left running while waiting for the next task.
|
||||||
|
always:
|
||||||
|
task_cleanup_script: *mac_cleanup
|
||||||
|
|
||||||
|
|
||||||
cross_task:
|
cross_task:
|
||||||
@ -138,7 +151,7 @@ ostree-rs-ext_task:
|
|||||||
dockerfile: contrib/cirrus/ostree_ext.dockerfile
|
dockerfile: contrib/cirrus/ostree_ext.dockerfile
|
||||||
docker_arguments: # required build-args
|
docker_arguments: # required build-args
|
||||||
BASE_FQIN: quay.io/coreos-assembler/fcos-buildroot:testing-devel
|
BASE_FQIN: quay.io/coreos-assembler/fcos-buildroot:testing-devel
|
||||||
CIRRUS_IMAGE_VERSION: 2
|
CIRRUS_IMAGE_VERSION: 3
|
||||||
env:
|
env:
|
||||||
EXT_REPO_NAME: ostree-rs-ext
|
EXT_REPO_NAME: ostree-rs-ext
|
||||||
EXT_REPO_HOME: $CIRRUS_WORKING_DIR/../$EXT_REPO_NAME
|
EXT_REPO_HOME: $CIRRUS_WORKING_DIR/../$EXT_REPO_NAME
|
||||||
@ -181,7 +194,7 @@ test_skopeo_task:
|
|||||||
matrix:
|
matrix:
|
||||||
- name: "Skopeo Test" # N/B: Name ref. by hack/get_fqin.sh
|
- name: "Skopeo Test" # N/B: Name ref. by hack/get_fqin.sh
|
||||||
env:
|
env:
|
||||||
BUILDTAGS: 'btrfs_noversion libdm_no_deferred_remove'
|
BUILDTAGS: ''
|
||||||
- name: "Skopeo Test w/ opengpg"
|
- name: "Skopeo Test w/ opengpg"
|
||||||
env:
|
env:
|
||||||
BUILDTAGS: *withopengpg
|
BUILDTAGS: *withopengpg
|
||||||
|
1
.fmf/version
Normal file
1
.fmf/version
Normal file
@ -0,0 +1 @@
|
|||||||
|
1
|
7
.github/workflows/check_cirrus_cron.yml
vendored
7
.github/workflows/check_cirrus_cron.yml
vendored
@ -17,4 +17,9 @@ jobs:
|
|||||||
# Ref: https://docs.github.com/en/actions/using-workflows/reusing-workflows
|
# Ref: https://docs.github.com/en/actions/using-workflows/reusing-workflows
|
||||||
call_cron_failures:
|
call_cron_failures:
|
||||||
uses: containers/podman/.github/workflows/check_cirrus_cron.yml@main
|
uses: containers/podman/.github/workflows/check_cirrus_cron.yml@main
|
||||||
secrets: inherit
|
secrets:
|
||||||
|
SECRET_CIRRUS_API_KEY: ${{secrets.SECRET_CIRRUS_API_KEY}}
|
||||||
|
ACTION_MAIL_SERVER: ${{secrets.ACTION_MAIL_SERVER}}
|
||||||
|
ACTION_MAIL_USERNAME: ${{secrets.ACTION_MAIL_USERNAME}}
|
||||||
|
ACTION_MAIL_PASSWORD: ${{secrets.ACTION_MAIL_PASSWORD}}
|
||||||
|
ACTION_MAIL_SENDER: ${{secrets.ACTION_MAIL_SENDER}}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
# See also:
|
# See also:
|
||||||
# https://github.com/containers/podman/blob/main/.github/workflows/discussion_lock.yml
|
# https://github.com/containers/podman/blob/main/.github/workflows/issue_pr_lock.yml
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
@ -12,7 +12,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
# Ref: https://docs.github.com/en/actions/using-workflows/reusing-workflows
|
# Ref: https://docs.github.com/en/actions/using-workflows/reusing-workflows
|
||||||
closed_issue_discussion_lock:
|
closed_issue_discussion_lock:
|
||||||
uses: containers/podman/.github/workflows/discussion_lock.yml@main
|
uses: containers/podman/.github/workflows/issue_pr_lock.yml@main
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
19
.github/workflows/rerun_cirrus_cron.yml
vendored
19
.github/workflows/rerun_cirrus_cron.yml
vendored
@ -1,19 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
# See also: https://github.com/containers/podman/blob/main/.github/workflows/rerun_cirrus_cron.yml
|
|
||||||
|
|
||||||
on:
|
|
||||||
# Note: This only applies to the default branch.
|
|
||||||
schedule:
|
|
||||||
# N/B: This should correspond to a period slightly after
|
|
||||||
# the last job finishes running. See job defs. at:
|
|
||||||
# https://cirrus-ci.com/settings/repository/6706677464432640
|
|
||||||
- cron: '01 01 * * 1-5'
|
|
||||||
# Debug: Allow triggering job manually in github-actions WebUI
|
|
||||||
workflow_dispatch: {}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# Ref: https://docs.github.com/en/actions/using-workflows/reusing-workflows
|
|
||||||
call_cron_rerun:
|
|
||||||
uses: containers/podman/.github/workflows/rerun_cirrus_cron.yml@main
|
|
||||||
secrets: inherit
|
|
@ -1,3 +1,13 @@
|
|||||||
---
|
version: "2"
|
||||||
run:
|
linters:
|
||||||
timeout: 5m
|
settings:
|
||||||
|
staticcheck:
|
||||||
|
checks:
|
||||||
|
# Compared to golangci-lint v2.0.2 defaults, we don’t exclude
|
||||||
|
# ST1003, ST1016, ST1020, ST1021, ST1022 as we don't hit those.
|
||||||
|
- all
|
||||||
|
- -ST1000 # Incorrect or missing package comment.
|
||||||
|
- -ST1005 # Incorrectly formatted error string.
|
||||||
|
exclusions:
|
||||||
|
presets:
|
||||||
|
- std-error-handling
|
||||||
|
130
.packit.yaml
130
.packit.yaml
@ -6,34 +6,86 @@
|
|||||||
# supported Fedora and CentOS Stream arches.
|
# supported Fedora and CentOS Stream arches.
|
||||||
# They do not block the current Cirrus-based workflow.
|
# They do not block the current Cirrus-based workflow.
|
||||||
|
|
||||||
specfile_path: rpm/skopeo.spec
|
downstream_package_name: skopeo
|
||||||
upstream_tag_template: v{version}
|
upstream_tag_template: v{version}
|
||||||
|
|
||||||
|
# These files get synced from upstream to downstream (Fedora / CentOS Stream) on every
|
||||||
|
# propose-downstream job. This is done so tests maintained upstream can be run
|
||||||
|
# downstream in Zuul CI and Bodhi.
|
||||||
|
# Ref: https://packit.dev/docs/configuration#files_to_sync
|
||||||
|
files_to_sync:
|
||||||
|
- src: rpm/gating.yaml
|
||||||
|
dest: gating.yaml
|
||||||
|
delete: true
|
||||||
|
- src: plans/
|
||||||
|
dest: plans/
|
||||||
|
delete: true
|
||||||
|
mkpath: true
|
||||||
|
- src: systemtest/tmt/
|
||||||
|
dest: test/tmt/
|
||||||
|
delete: true
|
||||||
|
mkpath: true
|
||||||
|
- src: .fmf/
|
||||||
|
dest: .fmf/
|
||||||
|
delete: true
|
||||||
|
- .packit.yaml
|
||||||
|
|
||||||
|
packages:
|
||||||
|
skopeo-fedora:
|
||||||
|
pkg_tool: fedpkg
|
||||||
|
specfile_path: rpm/skopeo.spec
|
||||||
|
skopeo-centos:
|
||||||
|
pkg_tool: centpkg
|
||||||
|
specfile_path: rpm/skopeo.spec
|
||||||
|
skopeo-eln:
|
||||||
|
specfile_path: rpm/skopeo.spec
|
||||||
|
|
||||||
srpm_build_deps:
|
srpm_build_deps:
|
||||||
- make
|
- make
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
- job: copr_build
|
- job: copr_build
|
||||||
trigger: pull_request
|
trigger: pull_request
|
||||||
notifications:
|
packages: [skopeo-fedora]
|
||||||
|
notifications: &copr_build_failure_notification
|
||||||
failure_comment:
|
failure_comment:
|
||||||
message: "Ephemeral COPR build failed. @containers/packit-build please check."
|
message: "Ephemeral COPR build failed. @containers/packit-build please check."
|
||||||
|
targets: &fedora_copr_targets
|
||||||
|
# This should generally be fedora-all-*, but we exclude Fedora 40 because it does not have Go 1.23.
|
||||||
|
- fedora-latest-stable-x86_64
|
||||||
|
- fedora-latest-stable-aarch64
|
||||||
|
- fedora-development-x86_64
|
||||||
|
- fedora-development-aarch64
|
||||||
enable_net: true
|
enable_net: true
|
||||||
|
|
||||||
|
- job: copr_build
|
||||||
|
trigger: pull_request
|
||||||
|
packages: [skopeo-eln]
|
||||||
|
notifications: *copr_build_failure_notification
|
||||||
targets:
|
targets:
|
||||||
- fedora-all-x86_64
|
fedora-eln-x86_64:
|
||||||
- fedora-all-aarch64
|
additional_repos:
|
||||||
- fedora-eln-x86_64
|
- "https://kojipkgs.fedoraproject.org/repos/eln-build/latest/x86_64/"
|
||||||
- fedora-eln-aarch64
|
fedora-eln-aarch64:
|
||||||
- centos-stream+epel-next-8-x86_64
|
additional_repos:
|
||||||
- centos-stream+epel-next-8-aarch64
|
- "https://kojipkgs.fedoraproject.org/repos/eln-build/latest/aarch64/"
|
||||||
- centos-stream+epel-next-9-x86_64
|
enable_net: true
|
||||||
- centos-stream+epel-next-9-aarch64
|
|
||||||
additional_repos:
|
- job: copr_build
|
||||||
- "copr://rhcontainerbot/podman-next"
|
trigger: pull_request
|
||||||
|
packages: [skopeo-centos]
|
||||||
|
notifications: *copr_build_failure_notification
|
||||||
|
targets: ¢os_copr_targets
|
||||||
|
- centos-stream-9-x86_64
|
||||||
|
- centos-stream-9-aarch64
|
||||||
|
- centos-stream-10-x86_64
|
||||||
|
- centos-stream-10-aarch64
|
||||||
|
enable_net: true
|
||||||
|
|
||||||
# Run on commit to main branch
|
# Run on commit to main branch
|
||||||
- job: copr_build
|
- job: copr_build
|
||||||
trigger: commit
|
trigger: commit
|
||||||
|
packages: [skopeo-fedora]
|
||||||
notifications:
|
notifications:
|
||||||
failure_comment:
|
failure_comment:
|
||||||
message: "podman-next COPR build failed. @containers/packit-build please check."
|
message: "podman-next COPR build failed. @containers/packit-build please check."
|
||||||
@ -42,18 +94,56 @@ jobs:
|
|||||||
project: podman-next
|
project: podman-next
|
||||||
enable_net: true
|
enable_net: true
|
||||||
|
|
||||||
|
# Tests on Fedora for main branch
|
||||||
|
- job: tests
|
||||||
|
trigger: pull_request
|
||||||
|
packages: [skopeo-fedora]
|
||||||
|
notifications: &test_failure_notification
|
||||||
|
failure_comment:
|
||||||
|
message: "Tests failed. @containers/packit-build please check."
|
||||||
|
targets: *fedora_copr_targets
|
||||||
|
tf_extra_params:
|
||||||
|
environments:
|
||||||
|
- artifacts:
|
||||||
|
- type: repository-file
|
||||||
|
id: https://copr.fedorainfracloud.org/coprs/rhcontainerbot/podman-next/repo/fedora-$releasever/rhcontainerbot-podman-next-fedora-$releasever.repo
|
||||||
|
|
||||||
|
# Tests on CentOS Stream for main branch
|
||||||
|
- job: tests
|
||||||
|
trigger: pull_request
|
||||||
|
packages: [skopeo-centos]
|
||||||
|
notifications: *test_failure_notification
|
||||||
|
targets: *centos_copr_targets
|
||||||
|
tf_extra_params:
|
||||||
|
environments:
|
||||||
|
- artifacts:
|
||||||
|
- type: repository-file
|
||||||
|
id: https://copr.fedorainfracloud.org/coprs/rhcontainerbot/podman-next/repo/centos-stream-$releasever/rhcontainerbot-podman-next-centos-stream-$releasever.repo
|
||||||
|
|
||||||
|
# Sync to Fedora
|
||||||
- job: propose_downstream
|
- job: propose_downstream
|
||||||
trigger: release
|
trigger: release
|
||||||
|
packages: [skopeo-fedora]
|
||||||
|
update_release: false
|
||||||
|
dist_git_branches: &fedora_targets
|
||||||
|
- fedora-all
|
||||||
|
|
||||||
|
# Sync to CentOS Stream
|
||||||
|
- job: propose_downstream
|
||||||
|
trigger: release
|
||||||
|
packages: [skopeo-centos]
|
||||||
update_release: false
|
update_release: false
|
||||||
dist_git_branches:
|
dist_git_branches:
|
||||||
- fedora-all
|
- c10s
|
||||||
|
|
||||||
|
# Fedora Koji build
|
||||||
- job: koji_build
|
- job: koji_build
|
||||||
trigger: commit
|
trigger: commit
|
||||||
dist_git_branches:
|
packages: [skopeo-fedora]
|
||||||
- fedora-all
|
sidetag_group: podman-releases
|
||||||
|
# Dependents are not rpm dependencies, but the package whose bodhi update
|
||||||
- job: bodhi_update
|
# should include this package.
|
||||||
trigger: commit
|
# Ref: https://packit.dev/docs/fedora-releases-guide/releasing-multiple-packages
|
||||||
dist_git_branches:
|
dependents:
|
||||||
- fedora-branched # rawhide updates are created automatically
|
- podman
|
||||||
|
dist_git_branches: *fedora_targets
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
## The skopeo Project Community Code of Conduct
|
## The skopeo Project Community Code of Conduct
|
||||||
|
|
||||||
The skopeo project follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/main/CODE-OF-CONDUCT.md).
|
The skopeo project, as part of Podman Container Tools, follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).
|
||||||
|
@ -148,9 +148,13 @@ When new PRs for [containers/image](https://github.com/containers/image) break `
|
|||||||
|
|
||||||
## Communications
|
## Communications
|
||||||
|
|
||||||
For general questions, or discussions, please use the
|
For general questions, or discussions, please use the
|
||||||
IRC channel on `irc.libera.chat` called `#container-projects`
|
[#podman](https://app.slack.com/client/T08PSQ7BQ/C08MXJLCFCN) channel on the [CNCF
|
||||||
that has been setup.
|
Slack](https://cloud-native.slack.com).
|
||||||
|
|
||||||
|
For development related discussions, please use the
|
||||||
|
[#podman-dev](https://app.slack.com/client/T08PSQ7BQ/C08NTKCDC1W) channel on the CNCF
|
||||||
|
Slack.
|
||||||
|
|
||||||
For discussions around issues/bugs and features, you can use the github
|
For discussions around issues/bugs and features, you can use the github
|
||||||
[issues](https://github.com/containers/skopeo/issues)
|
[issues](https://github.com/containers/skopeo/issues)
|
||||||
|
3
GOVERNANCE.md
Normal file
3
GOVERNANCE.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
## The Skopeo Project Community Governance
|
||||||
|
|
||||||
|
The Skopeo project, as part of Podman Container Tools, follows the [Podman Project Governance](https://github.com/containers/podman/blob/main/GOVERNANCE.md).
|
29
MAINTAINERS.md
Normal file
29
MAINTAINERS.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Skopeo Maintainers
|
||||||
|
|
||||||
|
[GOVERNANCE.md](https://github.com/containers/podman/blob/main/GOVERNANCE.md)
|
||||||
|
describes the project's governance and the Project Roles used below.
|
||||||
|
|
||||||
|
## Maintainers
|
||||||
|
|
||||||
|
| Maintainer | GitHub ID | Project Roles | Affiliation |
|
||||||
|
|-------------------|----------------------------------------------------------|----------------------------------|----------------------------------------------|
|
||||||
|
| Brent Baude | [baude](https://github.com/baude) | Core Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Nalin Dahyabhai | [nalind](https://github.com/nalind) | Core Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Matthew Heon | [mheon](https://github.com/mheon) | Core Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Paul Holzinger | [Luap99](https://github.com/Luap99) | Core Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Giuseppe Scrivano | [giuseppe](https://github.com/giuseppe) | Core Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Miloslav Trmač | [mtrmac](https://github.com/mtrmac) | Core Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Neil Smith | [Neil-Smith](https://github.com/Neil-Smith) | Community Manager | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Tom Sweeney | [TomSweeneyRedHat](https://github.com/TomSweeneyRedHat/) | Maintainer and Community Manager | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Lokesh Mandvekar | [lsm5](https://github.com/lsm5) | Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Dan Walsh | [rhatdan](https://github.com/rhatdan) | Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Ashley Cui | [ashley-cui](https://github.com/ashley-cui) | Reviewer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
| Valentin Rothberg | [vrothberg](https://github.com/vrothberg) | Reviewer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||||
|
|
||||||
|
## Alumni
|
||||||
|
|
||||||
|
None at present
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
The structure of this document was based off of the equivalent one in the [CRI-O Project](https://github.com/cri-o/cri-o/blob/main/MAINTAINERS.md).
|
15
Makefile
15
Makefile
@ -27,7 +27,7 @@ GOARCH ?= $(shell go env GOARCH)
|
|||||||
# N/B: This value is managed by Renovate, manual changes are
|
# N/B: This value is managed by Renovate, manual changes are
|
||||||
# possible, as long as they don't disturb the formatting
|
# possible, as long as they don't disturb the formatting
|
||||||
# (i.e. DO NOT ADD A 'v' prefix!)
|
# (i.e. DO NOT ADD A 'v' prefix!)
|
||||||
GOLANGCI_LINT_VERSION := 1.55.2
|
GOLANGCI_LINT_VERSION := 2.1.6
|
||||||
|
|
||||||
ifeq ($(GOBIN),)
|
ifeq ($(GOBIN),)
|
||||||
GOBIN := $(GOPATH)/bin
|
GOBIN := $(GOPATH)/bin
|
||||||
@ -90,14 +90,13 @@ SKOPEO_LDFLAGS := -ldflags '-X main.gitCommit=${GIT_COMMIT} $(EXTRA_LDFLAGS)'
|
|||||||
MANPAGES_MD = $(wildcard docs/*.md)
|
MANPAGES_MD = $(wildcard docs/*.md)
|
||||||
MANPAGES ?= $(MANPAGES_MD:%.md=%)
|
MANPAGES ?= $(MANPAGES_MD:%.md=%)
|
||||||
|
|
||||||
BTRFS_BUILD_TAG = $(shell hack/btrfs_tag.sh) $(shell hack/btrfs_installed_tag.sh)
|
BTRFS_BUILD_TAG = $(shell hack/btrfs_installed_tag.sh)
|
||||||
LIBDM_BUILD_TAG = $(shell hack/libdm_tag.sh)
|
|
||||||
LIBSUBID_BUILD_TAG = $(shell hack/libsubid_tag.sh)
|
LIBSUBID_BUILD_TAG = $(shell hack/libsubid_tag.sh)
|
||||||
LOCAL_BUILD_TAGS = $(BTRFS_BUILD_TAG) $(LIBDM_BUILD_TAG) $(LIBSUBID_BUILD_TAG)
|
LOCAL_BUILD_TAGS = $(BTRFS_BUILD_TAG) $(LIBSUBID_BUILD_TAG)
|
||||||
BUILDTAGS += $(LOCAL_BUILD_TAGS)
|
BUILDTAGS += $(LOCAL_BUILD_TAGS)
|
||||||
|
|
||||||
ifeq ($(DISABLE_CGO), 1)
|
ifeq ($(DISABLE_CGO), 1)
|
||||||
override BUILDTAGS = exclude_graphdriver_devicemapper exclude_graphdriver_btrfs containers_image_openpgp
|
override BUILDTAGS = exclude_graphdriver_btrfs containers_image_openpgp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# make all DEBUG=1
|
# make all DEBUG=1
|
||||||
@ -238,7 +237,11 @@ test-all-local: validate-local validate-docs test-unit-local
|
|||||||
validate-local:
|
validate-local:
|
||||||
hack/validate-git-marks.sh
|
hack/validate-git-marks.sh
|
||||||
hack/validate-gofmt.sh
|
hack/validate-gofmt.sh
|
||||||
GOBIN=$(GOBIN) hack/validate-lint.sh
|
$(GOBIN)/golangci-lint run --build-tags "${BUILDTAGS}"
|
||||||
|
# An extra run with --tests=false allows detecting code unused outside of tests;
|
||||||
|
# ideally the linter should be able to find this automatically.
|
||||||
|
# Since everything is already cached, this additional run doesn't take much time.
|
||||||
|
$(GOBIN)/golangci-lint run --build-tags "${BUILDTAGS}" --tests=false
|
||||||
BUILDTAGS="${BUILDTAGS}" hack/validate-vet.sh
|
BUILDTAGS="${BUILDTAGS}" hack/validate-vet.sh
|
||||||
|
|
||||||
# This invokes bin/skopeo, hence cannot be run as part of validate-local
|
# This invokes bin/skopeo, hence cannot be run as part of validate-local
|
||||||
|
17
OWNERS
17
OWNERS
@ -1,17 +1,22 @@
|
|||||||
approvers:
|
approvers:
|
||||||
- mtrmac
|
- baude
|
||||||
|
- giuseppe
|
||||||
- lsm5
|
- lsm5
|
||||||
- TomSweeneyRedHat
|
- Luap99
|
||||||
|
- mheon
|
||||||
|
- mtrmac
|
||||||
|
- nalind
|
||||||
- rhatdan
|
- rhatdan
|
||||||
- vrothberg
|
- TomSweeneyRedHat
|
||||||
reviewers:
|
reviewers:
|
||||||
- ashley-cui
|
- ashley-cui
|
||||||
|
- baude
|
||||||
- giuseppe
|
- giuseppe
|
||||||
- containers/image-maintainers
|
|
||||||
- lsm5
|
- lsm5
|
||||||
|
- Luap99
|
||||||
|
- mheon
|
||||||
- mtrmac
|
- mtrmac
|
||||||
- QiWang19
|
- nalind
|
||||||
- rhatdan
|
- rhatdan
|
||||||
- runcom
|
|
||||||
- TomSweeneyRedHat
|
- TomSweeneyRedHat
|
||||||
- vrothberg
|
- vrothberg
|
||||||
|
10
README.md
10
README.md
@ -1,4 +1,6 @@
|
|||||||
<img src="https://cdn.rawgit.com/containers/skopeo/main/docs/skopeo.svg" width="250" alt="Skopeo">
|
<p align="center">
|
||||||
|
<img src="https://cdn.rawgit.com/containers/skopeo/main/docs/skopeo.svg" width="250" alt="Skopeo">
|
||||||
|
</p>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
@ -45,6 +47,8 @@ Skopeo works with API V2 container image registries such as [docker.io](https://
|
|||||||
For a detailed description how to install or build skopeo, see
|
For a detailed description how to install or build skopeo, see
|
||||||
[install.md](./install.md).
|
[install.md](./install.md).
|
||||||
|
|
||||||
|
Skopeo is also available as a Container Image on [quay.io](https://quay.io/skopeo/stable). For more information, see the [Skopeo Image](https://github.com/containers/image_build/blob/main/skopeo/README.md) page.
|
||||||
|
|
||||||
## Inspecting a repository
|
## Inspecting a repository
|
||||||
`skopeo` is able to _inspect_ a repository on a container registry and fetch images layers.
|
`skopeo` is able to _inspect_ a repository on a container registry and fetch images layers.
|
||||||
The _inspect_ command fetches the repository's manifest and it is able to show you a `docker inspect`-like
|
The _inspect_ command fetches the repository's manifest and it is able to show you a `docker inspect`-like
|
||||||
@ -211,8 +215,8 @@ Please read the [contribution guide](CONTRIBUTING.md) if you want to collaborate
|
|||||||
| [skopeo-login(1)](/docs/skopeo-login.1.md) | Login to a container registry. |
|
| [skopeo-login(1)](/docs/skopeo-login.1.md) | Login to a container registry. |
|
||||||
| [skopeo-logout(1)](/docs/skopeo-logout.1.md) | Logout of a container registry. |
|
| [skopeo-logout(1)](/docs/skopeo-logout.1.md) | Logout of a container registry. |
|
||||||
| [skopeo-manifest-digest(1)](/docs/skopeo-manifest-digest.1.md) | Compute a manifest digest for a manifest-file and write it to standard output. |
|
| [skopeo-manifest-digest(1)](/docs/skopeo-manifest-digest.1.md) | Compute a manifest digest for a manifest-file and write it to standard output. |
|
||||||
| [skopeo-standalone-sign(1)](/docs/skopeo-standalone-sign.1.md) | Debugging tool - Publish and sign an image in one step. |
|
| [skopeo-standalone-sign(1)](/docs/skopeo-standalone-sign.1.md) | Debugging tool - Sign an image locally without uploading. |
|
||||||
| [skopeo-standalone-verify(1)](/docs/skopeo-standalone-verify.1.md)| Verify an image signature. |
|
| [skopeo-standalone-verify(1)](/docs/skopeo-standalone-verify.1.md)| Debugging tool - Verify an image signature from local files. |
|
||||||
| [skopeo-sync(1)](/docs/skopeo-sync.1.md) | Synchronize images between registry repositories and local directories. |
|
| [skopeo-sync(1)](/docs/skopeo-sync.1.md) | Synchronize images between registry repositories and local directories. |
|
||||||
|
|
||||||
License
|
License
|
||||||
|
12
ROADMAP.md
Normal file
12
ROADMAP.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Skopeo Roadmap
|
||||||
|
|
||||||
|
Skopeo intends to mostly continue to be a very thin CLI wrapper over the [https://github.com/containers/image](containers/image) library, with most features being added there, not to this repo. A typical new Skopeo feature would only add a CLI for a recent containers/image feature.
|
||||||
|
|
||||||
|
## Future feature focus (most of the work must be done in the containers/image library)
|
||||||
|
|
||||||
|
* OCI artifact support.
|
||||||
|
* Integration of composefs.
|
||||||
|
* Partial pull support (zstd:chunked).
|
||||||
|
* Performance and stability improvements.
|
||||||
|
* Reductions to the size of the Skopeo binary.
|
||||||
|
* `skopeo sync` exists, and bugs in it should be fixed, but we don’t have much of an ambition to compete with much larger projects like [https://github.com/openshift/oc-mirror](oc-mirror).
|
@ -1,16 +1,59 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/containers/image/v5/directory"
|
||||||
|
"github.com/containers/image/v5/docker"
|
||||||
|
dockerArchive "github.com/containers/image/v5/docker/archive"
|
||||||
|
ociArchive "github.com/containers/image/v5/oci/archive"
|
||||||
|
oci "github.com/containers/image/v5/oci/layout"
|
||||||
|
"github.com/containers/image/v5/sif"
|
||||||
|
"github.com/containers/image/v5/tarball"
|
||||||
"github.com/containers/image/v5/transports"
|
"github.com/containers/image/v5/transports"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// autocompleteSupportedTransports list all supported transports with the colon suffix.
|
func autocompleteImageNames(cmd *cobra.Command, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) {
|
||||||
func autocompleteSupportedTransports(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
transport, details, haveTransport := strings.Cut(toComplete, ":")
|
||||||
tps := transports.ListNames()
|
if !haveTransport {
|
||||||
suggestions := make([]string, 0, len(tps))
|
transports := supportedTransportSuggestions()
|
||||||
for _, tp := range tps {
|
return transports, cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp
|
||||||
suggestions = append(suggestions, tp+":")
|
|
||||||
}
|
}
|
||||||
return suggestions, cobra.ShellCompDirectiveNoFileComp
|
switch transport {
|
||||||
|
case ociArchive.Transport.Name(), dockerArchive.Transport.Name():
|
||||||
|
// Can have [:{*reference|@source-index}]
|
||||||
|
// FIXME: `oci-archive:/path/to/a.oci:<TAB>` completes paths
|
||||||
|
return nil, cobra.ShellCompDirectiveNoSpace
|
||||||
|
case sif.Transport.Name():
|
||||||
|
return nil, cobra.ShellCompDirectiveDefault
|
||||||
|
|
||||||
|
// Both directory and oci should have ShellCompDirectiveFilterDirs to complete only directories, but it doesn't currently work in bash: https://github.com/spf13/cobra/issues/2242
|
||||||
|
case oci.Transport.Name():
|
||||||
|
// Can have '[:{reference|@source-index}]'
|
||||||
|
// FIXME: `oci:/path/to/dir/:<TAB>` completes paths
|
||||||
|
return nil, cobra.ShellCompDirectiveDefault | cobra.ShellCompDirectiveNoSpace
|
||||||
|
case directory.Transport.Name():
|
||||||
|
return nil, cobra.ShellCompDirectiveDefault
|
||||||
|
|
||||||
|
case docker.Transport.Name():
|
||||||
|
if details == "" {
|
||||||
|
return []cobra.Completion{transport + "://"}, cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
|
||||||
|
// supportedTransportSuggestions list all supported transports with the colon suffix.
|
||||||
|
func supportedTransportSuggestions() []string {
|
||||||
|
tps := transports.ListNames()
|
||||||
|
suggestions := make([]cobra.Completion, 0, len(tps))
|
||||||
|
for _, tp := range tps {
|
||||||
|
// ListNames is generally expected to filter out deprecated transports.
|
||||||
|
// tarball: is not deprecated, but it is only usable from a Go caller (using tarball.ConfigUpdater),
|
||||||
|
// so don’t offer it on the CLI.
|
||||||
|
if tp != tarball.Transport.Name() {
|
||||||
|
suggestions = append(suggestions, tp+":")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return suggestions
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ type copyOptions struct {
|
|||||||
encryptLayer []int // The list of layers to encrypt
|
encryptLayer []int // The list of layers to encrypt
|
||||||
encryptionKeys []string // Keys needed to encrypt the image
|
encryptionKeys []string // Keys needed to encrypt the image
|
||||||
decryptionKeys []string // Keys needed to decrypt the image
|
decryptionKeys []string // Keys needed to decrypt the image
|
||||||
|
imageParallelCopies uint // Maximum number of parallel requests when copying images
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyCmd(global *globalOptions) *cobra.Command {
|
func copyCmd(global *globalOptions) *cobra.Command {
|
||||||
@ -70,7 +71,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format
|
|||||||
`, strings.Join(transports.ListNames(), ", ")),
|
`, strings.Join(transports.ListNames(), ", ")),
|
||||||
RunE: commandAction(opts.run),
|
RunE: commandAction(opts.run),
|
||||||
Example: `skopeo copy docker://quay.io/skopeo/stable:latest docker://registry.example.com/skopeo:latest`,
|
Example: `skopeo copy docker://quay.io/skopeo/stable:latest docker://registry.example.com/skopeo:latest`,
|
||||||
ValidArgsFunction: autocompleteSupportedTransports,
|
ValidArgsFunction: autocompleteImageNames,
|
||||||
}
|
}
|
||||||
adjustUsage(cmd)
|
adjustUsage(cmd)
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
@ -95,6 +96,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format
|
|||||||
flags.StringSliceVar(&opts.encryptionKeys, "encryption-key", []string{}, "*Experimental* key with the encryption protocol to use needed to encrypt the image (e.g. jwe:/path/to/key.pem)")
|
flags.StringSliceVar(&opts.encryptionKeys, "encryption-key", []string{}, "*Experimental* key with the encryption protocol to use needed to encrypt the image (e.g. jwe:/path/to/key.pem)")
|
||||||
flags.IntSliceVar(&opts.encryptLayer, "encrypt-layer", []int{}, "*Experimental* the 0-indexed layer indices, with support for negative indexing (e.g. 0 is the first layer, -1 is the last layer)")
|
flags.IntSliceVar(&opts.encryptLayer, "encrypt-layer", []int{}, "*Experimental* the 0-indexed layer indices, with support for negative indexing (e.g. 0 is the first layer, -1 is the last layer)")
|
||||||
flags.StringSliceVar(&opts.decryptionKeys, "decryption-key", []string{}, "*Experimental* key needed to decrypt the image")
|
flags.StringSliceVar(&opts.decryptionKeys, "decryption-key", []string{}, "*Experimental* key needed to decrypt the image")
|
||||||
|
flags.UintVar(&opts.imageParallelCopies, "image-parallel-copies", 0, "Maximum number of image layers to be copied (pulled/pushed) simultaneously. Not setting this field will fall back to containers/image defaults.")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,6 +302,7 @@ func (opts *copyOptions) run(args []string, stdout io.Writer) (retErr error) {
|
|||||||
OciDecryptConfig: decConfig,
|
OciDecryptConfig: decConfig,
|
||||||
OciEncryptLayers: encLayers,
|
OciEncryptLayers: encLayers,
|
||||||
OciEncryptConfig: encConfig,
|
OciEncryptConfig: encConfig,
|
||||||
|
MaxParallelDownloads: opts.imageParallelCopies,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
18
cmd/skopeo/copy_test.go
Normal file
18
cmd/skopeo/copy_test.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestCopy(t *testing.T) {
|
||||||
|
// Invalid command-line arguments
|
||||||
|
for _, args := range [][]string{
|
||||||
|
{},
|
||||||
|
{"a1"},
|
||||||
|
{"a1", "a2", "a3"},
|
||||||
|
} {
|
||||||
|
out, err := runSkopeo(append([]string{"--insecure-policy", "copy"}, args...)...)
|
||||||
|
assertTestFailed(t, out, err, "Exactly two arguments expected")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Much more test coverage
|
||||||
|
// Actual feature tests exist in integration and systemtest
|
||||||
|
}
|
@ -37,7 +37,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format
|
|||||||
`, strings.Join(transports.ListNames(), ", ")),
|
`, strings.Join(transports.ListNames(), ", ")),
|
||||||
RunE: commandAction(opts.run),
|
RunE: commandAction(opts.run),
|
||||||
Example: `skopeo delete docker://registry.example.com/example/pause:latest`,
|
Example: `skopeo delete docker://registry.example.com/example/pause:latest`,
|
||||||
ValidArgsFunction: autocompleteSupportedTransports,
|
ValidArgsFunction: autocompleteImageNames,
|
||||||
}
|
}
|
||||||
adjustUsage(cmd)
|
adjustUsage(cmd)
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
@ -53,7 +53,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format
|
|||||||
Example: `skopeo inspect docker://registry.fedoraproject.org/fedora
|
Example: `skopeo inspect docker://registry.fedoraproject.org/fedora
|
||||||
skopeo inspect --config docker://docker.io/alpine
|
skopeo inspect --config docker://docker.io/alpine
|
||||||
skopeo inspect --format "Name: {{.Name}} Digest: {{.Digest}}" docker://registry.access.redhat.com/ubi8`,
|
skopeo inspect --format "Name: {{.Name}} Digest: {{.Digest}}" docker://registry.access.redhat.com/ubi8`,
|
||||||
ValidArgsFunction: autocompleteSupportedTransports,
|
ValidArgsFunction: autocompleteImageNames,
|
||||||
}
|
}
|
||||||
adjustUsage(cmd)
|
adjustUsage(cmd)
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
@ -106,8 +106,9 @@ func (opts *inspectOptions) run(args []string, stdout io.Writer) (retErr error)
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
unparsedInstance := image.UnparsedInstance(src, nil)
|
||||||
if err := retry.IfNecessary(ctx, func() error {
|
if err := retry.IfNecessary(ctx, func() error {
|
||||||
rawManifest, _, err = src.GetManifest(ctx, nil)
|
rawManifest, _, err = unparsedInstance.Manifest(ctx)
|
||||||
return err
|
return err
|
||||||
}, opts.retryOpts); err != nil {
|
}, opts.retryOpts); err != nil {
|
||||||
return fmt.Errorf("Error retrieving manifest for image: %w", err)
|
return fmt.Errorf("Error retrieving manifest for image: %w", err)
|
||||||
@ -122,7 +123,7 @@ func (opts *inspectOptions) run(args []string, stdout io.Writer) (retErr error)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
img, err := image.FromUnparsedImage(ctx, sys, image.UnparsedInstance(src, nil))
|
img, err := image.FromUnparsedImage(ctx, sys, unparsedInstance)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error parsing manifest for image: %w", err)
|
return fmt.Errorf("Error parsing manifest for image: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -151,12 +151,22 @@ func (opts *layersOptions) run(args []string, stdout io.Writer) (retErr error) {
|
|||||||
}, opts.retryOpts); err != nil {
|
}, opts.retryOpts); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := dest.PutBlob(ctx, r, types.BlobInfo{Digest: bd.digest, Size: blobSize}, cache, bd.isConfig); err != nil {
|
defer func() {
|
||||||
if closeErr := r.Close(); closeErr != nil {
|
if err := r.Close(); err != nil {
|
||||||
return fmt.Errorf("%w (close error: %v)", err, closeErr)
|
retErr = noteCloseFailure(retErr, fmt.Sprintf("closing blob %q", bd.digest.String()), err)
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
verifier := bd.digest.Verifier()
|
||||||
|
tr := io.TeeReader(r, verifier)
|
||||||
|
if _, err := dest.PutBlob(ctx, tr, types.BlobInfo{Digest: bd.digest, Size: blobSize}, cache, bd.isConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if _, err := io.Copy(io.Discard, tr); err != nil { // Ensure we process all of tr, so that we can validate the digest.
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !verifier.Verified() {
|
||||||
|
return fmt.Errorf("corrupt blob %q", bd.digest.String())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var manifest []byte
|
var manifest []byte
|
||||||
|
@ -6,7 +6,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"maps"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/retry"
|
"github.com/containers/common/pkg/retry"
|
||||||
@ -16,7 +17,6 @@ import (
|
|||||||
"github.com/containers/image/v5/transports/alltransports"
|
"github.com/containers/image/v5/transports/alltransports"
|
||||||
"github.com/containers/image/v5/types"
|
"github.com/containers/image/v5/types"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/exp/maps"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// tagListOutput is the output format of (skopeo list-tags), primarily so that we can format it with a simple json.MarshalIndent.
|
// tagListOutput is the output format of (skopeo list-tags), primarily so that we can format it with a simple json.MarshalIndent.
|
||||||
@ -38,8 +38,7 @@ var transportHandlers = map[string]func(ctx context.Context, sys *types.SystemCo
|
|||||||
|
|
||||||
// supportedTransports returns all the supported transports
|
// supportedTransports returns all the supported transports
|
||||||
func supportedTransports(joinStr string) string {
|
func supportedTransports(joinStr string) string {
|
||||||
res := maps.Keys(transportHandlers)
|
res := slices.Sorted(maps.Keys(transportHandlers))
|
||||||
sort.Strings(res)
|
|
||||||
return strings.Join(res, joinStr)
|
return strings.Join(res, joinStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,16 +77,12 @@ See skopeo-list-tags(1) section "REPOSITORY NAMES" for the expected format
|
|||||||
// Customized version of the alltransports.ParseImageName and docker.ParseReference that does not place a default tag in the reference
|
// Customized version of the alltransports.ParseImageName and docker.ParseReference that does not place a default tag in the reference
|
||||||
// Would really love to not have this, but needed to enforce tag-less and digest-less names
|
// Would really love to not have this, but needed to enforce tag-less and digest-less names
|
||||||
func parseDockerRepositoryReference(refString string) (types.ImageReference, error) {
|
func parseDockerRepositoryReference(refString string) (types.ImageReference, error) {
|
||||||
if !strings.HasPrefix(refString, docker.Transport.Name()+"://") {
|
dockerRefString, ok := strings.CutPrefix(refString, docker.Transport.Name()+"://")
|
||||||
|
if !ok {
|
||||||
return nil, fmt.Errorf("docker: image reference %s does not start with %s://", refString, docker.Transport.Name())
|
return nil, fmt.Errorf("docker: image reference %s does not start with %s://", refString, docker.Transport.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
_, dockerImageName, hasColon := strings.Cut(refString, ":")
|
ref, err := reference.ParseNormalizedNamed(dockerRefString)
|
||||||
if !hasColon {
|
|
||||||
return nil, fmt.Errorf(`Invalid image name "%s", expected colon-separated transport:reference`, refString)
|
|
||||||
}
|
|
||||||
|
|
||||||
ref, err := reference.ParseNormalizedNamed(strings.TrimPrefix(dockerImageName, "//"))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -54,3 +54,17 @@ func TestDockerRepositoryReferenceParserDrift(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListTags(t *testing.T) {
|
||||||
|
// Invalid command-line arguments
|
||||||
|
for _, args := range [][]string{
|
||||||
|
{},
|
||||||
|
{"a1", "a2"},
|
||||||
|
} {
|
||||||
|
out, err := runSkopeo(append([]string{"list-tags"}, args...)...)
|
||||||
|
assertTestFailed(t, out, err, "Exactly one non-option argument expected")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Much more test coverage
|
||||||
|
// Actual feature tests exist in systemtest
|
||||||
|
}
|
||||||
|
@ -129,6 +129,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
rootCmd, _ := createApp()
|
rootCmd, _ := createApp()
|
||||||
if err := rootCmd.Execute(); err != nil {
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
if isNotFoundImageError(err) {
|
||||||
|
logrus.StandardLogger().Log(logrus.FatalLevel, err)
|
||||||
|
logrus.Exit(2)
|
||||||
|
}
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
//go:build !windows
|
//go:build !windows
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -73,13 +72,10 @@ import (
|
|||||||
|
|
||||||
"github.com/containers/image/v5/image"
|
"github.com/containers/image/v5/image"
|
||||||
"github.com/containers/image/v5/manifest"
|
"github.com/containers/image/v5/manifest"
|
||||||
ocilayout "github.com/containers/image/v5/oci/layout"
|
|
||||||
"github.com/containers/image/v5/pkg/blobinfocache"
|
"github.com/containers/image/v5/pkg/blobinfocache"
|
||||||
"github.com/containers/image/v5/transports"
|
"github.com/containers/image/v5/transports"
|
||||||
"github.com/containers/image/v5/transports/alltransports"
|
"github.com/containers/image/v5/transports/alltransports"
|
||||||
"github.com/containers/image/v5/types"
|
"github.com/containers/image/v5/types"
|
||||||
dockerdistributionerrcode "github.com/docker/distribution/registry/api/errcode"
|
|
||||||
dockerdistributionapi "github.com/docker/distribution/registry/api/v2"
|
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -96,7 +92,8 @@ import (
|
|||||||
// 0.2.4: Added OpenImageOptional
|
// 0.2.4: Added OpenImageOptional
|
||||||
// 0.2.5: Added LayerInfoJSON
|
// 0.2.5: Added LayerInfoJSON
|
||||||
// 0.2.6: Policy Verification before pulling OCI
|
// 0.2.6: Policy Verification before pulling OCI
|
||||||
const protocolVersion = "0.2.6"
|
// 0.2.7: Added GetLayerInfoPiped
|
||||||
|
const protocolVersion = "0.2.7"
|
||||||
|
|
||||||
// maxMsgSize is the current limit on a packet size.
|
// maxMsgSize is the current limit on a packet size.
|
||||||
// Note that all non-metadata (i.e. payload data) is sent over a pipe.
|
// Note that all non-metadata (i.e. payload data) is sent over a pipe.
|
||||||
@ -219,25 +216,6 @@ func (h *proxyHandler) OpenImage(args []any) (replyBuf, error) {
|
|||||||
return h.openImageImpl(args, false)
|
return h.openImageImpl(args, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isDockerManifestUnknownError is a copy of code from containers/image,
|
|
||||||
// please update there first.
|
|
||||||
func isDockerManifestUnknownError(err error) bool {
|
|
||||||
var ec dockerdistributionerrcode.ErrorCoder
|
|
||||||
if !errors.As(err, &ec) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return ec.ErrorCode() == dockerdistributionapi.ErrorCodeManifestUnknown
|
|
||||||
}
|
|
||||||
|
|
||||||
// isNotFoundImageError heuristically attempts to determine whether an error
|
|
||||||
// is saying the remote source couldn't find the image (as opposed to an
|
|
||||||
// authentication error, an I/O error etc.)
|
|
||||||
// TODO drive this into containers/image properly
|
|
||||||
func isNotFoundImageError(err error) bool {
|
|
||||||
return isDockerManifestUnknownError(err) ||
|
|
||||||
errors.Is(err, ocilayout.ImageNotFoundError{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *proxyHandler) openImageImpl(args []any, allowNotFound bool) (retReplyBuf replyBuf, retErr error) {
|
func (h *proxyHandler) openImageImpl(args []any, allowNotFound bool) (retReplyBuf replyBuf, retErr error) {
|
||||||
h.lock.Lock()
|
h.lock.Lock()
|
||||||
defer h.lock.Unlock()
|
defer h.lock.Unlock()
|
||||||
@ -299,7 +277,7 @@ func (h *proxyHandler) openImageImpl(args []any, allowNotFound bool) (retReplyBu
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenImage accepts a string image reference i.e. TRANSPORT:REF - like `skopeo copy`.
|
// OpenImageOptional accepts a string image reference i.e. TRANSPORT:REF - like `skopeo copy`.
|
||||||
// The return value is an opaque integer handle. If the image does not exist, zero
|
// The return value is an opaque integer handle. If the image does not exist, zero
|
||||||
// is returned.
|
// is returned.
|
||||||
func (h *proxyHandler) OpenImageOptional(args []any) (replyBuf, error) {
|
func (h *proxyHandler) OpenImageOptional(args []any) (replyBuf, error) {
|
||||||
@ -641,9 +619,10 @@ func (h *proxyHandler) GetBlob(args []any) (replyBuf, error) {
|
|||||||
|
|
||||||
// GetLayerInfo returns data about the layers of an image, useful for reading the layer contents.
|
// GetLayerInfo returns data about the layers of an image, useful for reading the layer contents.
|
||||||
//
|
//
|
||||||
// This needs to be called since the data returned by GetManifest() does not allow to correctly
|
// This is the same as GetLayerInfoPiped, but returns its contents inline. This is subject to
|
||||||
// calling GetBlob() for the containers-storage: transport (which doesn’t store the original compressed
|
// failure for large images (because we use SOCK_SEQPACKET which has a maximum buffer size)
|
||||||
// representations referenced in the manifest).
|
// and is hence only retained for backwards compatibility. Callers are expected to use
|
||||||
|
// the semver to know whether they can call the new API.
|
||||||
func (h *proxyHandler) GetLayerInfo(args []any) (replyBuf, error) {
|
func (h *proxyHandler) GetLayerInfo(args []any) (replyBuf, error) {
|
||||||
h.lock.Lock()
|
h.lock.Lock()
|
||||||
defer h.lock.Unlock()
|
defer h.lock.Unlock()
|
||||||
@ -689,6 +668,59 @@ func (h *proxyHandler) GetLayerInfo(args []any) (replyBuf, error) {
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLayerInfoPiped returns data about the layers of an image, useful for reading the layer contents.
|
||||||
|
//
|
||||||
|
// This needs to be called since the data returned by GetManifest() does not allow to correctly
|
||||||
|
// calling GetBlob() for the containers-storage: transport (which doesn’t store the original compressed
|
||||||
|
// representations referenced in the manifest).
|
||||||
|
func (h *proxyHandler) GetLayerInfoPiped(args []any) (replyBuf, error) {
|
||||||
|
h.lock.Lock()
|
||||||
|
defer h.lock.Unlock()
|
||||||
|
|
||||||
|
var ret replyBuf
|
||||||
|
|
||||||
|
if h.sysctx == nil {
|
||||||
|
return ret, fmt.Errorf("client error: must invoke Initialize")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) != 1 {
|
||||||
|
return ret, fmt.Errorf("found %d args, expecting (imgid)", len(args))
|
||||||
|
}
|
||||||
|
|
||||||
|
imgref, err := h.parseImageFromID(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
err = h.cacheTargetManifest(imgref)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
img := imgref.cachedimg
|
||||||
|
|
||||||
|
layerInfos, err := img.LayerInfosForCopy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if layerInfos == nil {
|
||||||
|
layerInfos = img.LayerInfos()
|
||||||
|
}
|
||||||
|
|
||||||
|
layers := make([]convertedLayerInfo, 0, len(layerInfos))
|
||||||
|
for _, layer := range layerInfos {
|
||||||
|
layers = append(layers, convertedLayerInfo{layer.Digest, layer.Size, layer.MediaType})
|
||||||
|
}
|
||||||
|
|
||||||
|
serialized, err := json.Marshal(&layers)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
return h.returnBytes(nil, serialized)
|
||||||
|
}
|
||||||
|
|
||||||
// FinishPipe waits for the worker goroutine to finish, and closes the write side of the pipe.
|
// FinishPipe waits for the worker goroutine to finish, and closes the write side of the pipe.
|
||||||
func (h *proxyHandler) FinishPipe(args []any) (replyBuf, error) {
|
func (h *proxyHandler) FinishPipe(args []any) (replyBuf, error) {
|
||||||
h.lock.Lock()
|
h.lock.Lock()
|
||||||
@ -709,6 +741,7 @@ func (h *proxyHandler) FinishPipe(args []any) (replyBuf, error) {
|
|||||||
|
|
||||||
// Wait for the goroutine to complete
|
// Wait for the goroutine to complete
|
||||||
f.wg.Wait()
|
f.wg.Wait()
|
||||||
|
logrus.Debug("Completed pipe goroutine")
|
||||||
// And only now do we close the write half; this forces the client to call this API
|
// And only now do we close the write half; this forces the client to call this API
|
||||||
f.w.Close()
|
f.w.Close()
|
||||||
// Propagate any errors from the goroutine worker
|
// Propagate any errors from the goroutine worker
|
||||||
@ -730,6 +763,7 @@ func (h *proxyHandler) close() {
|
|||||||
|
|
||||||
// send writes a reply buffer to the socket
|
// send writes a reply buffer to the socket
|
||||||
func (buf replyBuf) send(conn *net.UnixConn, err error) error {
|
func (buf replyBuf) send(conn *net.UnixConn, err error) error {
|
||||||
|
logrus.Debugf("Sending reply: err=%v value=%v pipeid=%v", err, buf.value, buf.pipeid)
|
||||||
replyToSerialize := reply{
|
replyToSerialize := reply{
|
||||||
Success: err == nil,
|
Success: err == nil,
|
||||||
Value: buf.value,
|
Value: buf.value,
|
||||||
@ -804,6 +838,8 @@ func (h *proxyHandler) processRequest(readBytes []byte) (rb replyBuf, terminate
|
|||||||
err = fmt.Errorf("invalid request: %v", err)
|
err = fmt.Errorf("invalid request: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
logrus.Debugf("Executing method %s", req.Method)
|
||||||
|
|
||||||
// Dispatch on the method
|
// Dispatch on the method
|
||||||
switch req.Method {
|
switch req.Method {
|
||||||
case "Initialize":
|
case "Initialize":
|
||||||
@ -824,6 +860,8 @@ func (h *proxyHandler) processRequest(readBytes []byte) (rb replyBuf, terminate
|
|||||||
rb, err = h.GetBlob(req.Args)
|
rb, err = h.GetBlob(req.Args)
|
||||||
case "GetLayerInfo":
|
case "GetLayerInfo":
|
||||||
rb, err = h.GetLayerInfo(req.Args)
|
rb, err = h.GetLayerInfo(req.Args)
|
||||||
|
case "GetLayerInfoPiped":
|
||||||
|
rb, err = h.GetLayerInfoPiped(req.Args)
|
||||||
case "FinishPipe":
|
case "FinishPipe":
|
||||||
rb, err = h.FinishPipe(req.Args)
|
rb, err = h.FinishPipe(req.Args)
|
||||||
case "Shutdown":
|
case "Shutdown":
|
||||||
@ -867,6 +905,7 @@ func (opts *proxyOptions) run(args []string, stdout io.Writer) error {
|
|||||||
|
|
||||||
rb, terminate, err := handler.processRequest(readbuf)
|
rb, terminate, err := handler.processRequest(readbuf)
|
||||||
if terminate {
|
if terminate {
|
||||||
|
logrus.Debug("terminating")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
//go:build windows
|
//go:build windows
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -10,14 +10,17 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver/v3"
|
||||||
commonFlag "github.com/containers/common/pkg/flag"
|
commonFlag "github.com/containers/common/pkg/flag"
|
||||||
"github.com/containers/common/pkg/retry"
|
"github.com/containers/common/pkg/retry"
|
||||||
"github.com/containers/image/v5/copy"
|
"github.com/containers/image/v5/copy"
|
||||||
"github.com/containers/image/v5/directory"
|
"github.com/containers/image/v5/directory"
|
||||||
"github.com/containers/image/v5/docker"
|
"github.com/containers/image/v5/docker"
|
||||||
"github.com/containers/image/v5/docker/reference"
|
"github.com/containers/image/v5/docker/reference"
|
||||||
|
"github.com/containers/image/v5/manifest"
|
||||||
"github.com/containers/image/v5/pkg/cli"
|
"github.com/containers/image/v5/pkg/cli"
|
||||||
"github.com/containers/image/v5/pkg/cli/sigstore"
|
"github.com/containers/image/v5/pkg/cli/sigstore"
|
||||||
"github.com/containers/image/v5/signature/signer"
|
"github.com/containers/image/v5/signature/signer"
|
||||||
@ -26,7 +29,6 @@ import (
|
|||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -45,6 +47,7 @@ type syncOptions struct {
|
|||||||
format commonFlag.OptionalString // Force conversion of the image to a specified format
|
format commonFlag.OptionalString // Force conversion of the image to a specified format
|
||||||
source string // Source repository name
|
source string // Source repository name
|
||||||
destination string // Destination registry name
|
destination string // Destination registry name
|
||||||
|
digestFile string // Write digest to this file
|
||||||
scoped bool // When true, namespace copied images at destination using the source repository name
|
scoped bool // When true, namespace copied images at destination using the source repository name
|
||||||
all bool // Copy all of the images if an image in the source is a list
|
all bool // Copy all of the images if an image in the source is a list
|
||||||
dryRun bool // Don't actually copy anything, just output what it would have done
|
dryRun bool // Don't actually copy anything, just output what it would have done
|
||||||
@ -71,6 +74,7 @@ type tlsVerifyConfig struct {
|
|||||||
type registrySyncConfig struct {
|
type registrySyncConfig struct {
|
||||||
Images map[string][]string // Images map images name to slices with the images' references (tags, digests)
|
Images map[string][]string // Images map images name to slices with the images' references (tags, digests)
|
||||||
ImagesByTagRegex map[string]string `yaml:"images-by-tag-regex"` // Images map images name to regular expression with the images' tags
|
ImagesByTagRegex map[string]string `yaml:"images-by-tag-regex"` // Images map images name to regular expression with the images' tags
|
||||||
|
ImagesBySemver map[string]string `yaml:"images-by-semver"` // ImagesBySemver maps a repository to a semver constraint (e.g. '>=3.14') to match images' tags to
|
||||||
Credentials types.DockerAuthConfig // Username and password used to authenticate with the registry
|
Credentials types.DockerAuthConfig // Username and password used to authenticate with the registry
|
||||||
TLSVerify tlsVerifyConfig `yaml:"tls-verify"` // TLS verification mode (enabled by default)
|
TLSVerify tlsVerifyConfig `yaml:"tls-verify"` // TLS verification mode (enabled by default)
|
||||||
CertDir string `yaml:"cert-dir"` // Path to the TLS certificates of the registry
|
CertDir string `yaml:"cert-dir"` // Path to the TLS certificates of the registry
|
||||||
@ -119,6 +123,7 @@ See skopeo-sync(1) for details.
|
|||||||
flags.StringVarP(&opts.destination, "dest", "d", "", "DESTINATION transport type")
|
flags.StringVarP(&opts.destination, "dest", "d", "", "DESTINATION transport type")
|
||||||
flags.BoolVar(&opts.scoped, "scoped", false, "Images at DESTINATION are prefix using the full source image path as scope")
|
flags.BoolVar(&opts.scoped, "scoped", false, "Images at DESTINATION are prefix using the full source image path as scope")
|
||||||
flags.StringVar(&opts.appendSuffix, "append-suffix", "", "String to append to DESTINATION tags")
|
flags.StringVar(&opts.appendSuffix, "append-suffix", "", "String to append to DESTINATION tags")
|
||||||
|
flags.StringVar(&opts.digestFile, "digestfile", "", "Write the digests and Image References of the resulting images to the specified file, separated by newlines")
|
||||||
flags.BoolVarP(&opts.all, "all", "a", false, "Copy all images if SOURCE-IMAGE is a list")
|
flags.BoolVarP(&opts.all, "all", "a", false, "Copy all images if SOURCE-IMAGE is a list")
|
||||||
flags.BoolVar(&opts.dryRun, "dry-run", false, "Run without actually copying data")
|
flags.BoolVar(&opts.dryRun, "dry-run", false, "Run without actually copying data")
|
||||||
flags.BoolVar(&opts.preserveDigests, "preserve-digests", false, "Preserve digests of images and lists")
|
flags.BoolVar(&opts.preserveDigests, "preserve-digests", false, "Preserve digests of images and lists")
|
||||||
@ -304,6 +309,14 @@ func imagesToCopyFromRegistry(registryName string, cfg registrySyncConfig, sourc
|
|||||||
serverCtx.DockerAuthConfig = &cfg.Credentials
|
serverCtx.DockerAuthConfig = &cfg.Credentials
|
||||||
}
|
}
|
||||||
var repoDescList []repoDescriptor
|
var repoDescList []repoDescriptor
|
||||||
|
|
||||||
|
if len(cfg.Images) == 0 && len(cfg.ImagesByTagRegex) == 0 && len(cfg.ImagesBySemver) == 0 {
|
||||||
|
logrus.WithFields(logrus.Fields{
|
||||||
|
"registry": registryName,
|
||||||
|
}).Warn("No images specified for registry")
|
||||||
|
return repoDescList, nil
|
||||||
|
}
|
||||||
|
|
||||||
for imageName, refs := range cfg.Images {
|
for imageName, refs := range cfg.Images {
|
||||||
repoLogger := logrus.WithFields(logrus.Fields{
|
repoLogger := logrus.WithFields(logrus.Fields{
|
||||||
"repo": imageName,
|
"repo": imageName,
|
||||||
@ -368,63 +381,146 @@ func imagesToCopyFromRegistry(registryName string, cfg registrySyncConfig, sourc
|
|||||||
Context: serverCtx})
|
Context: serverCtx})
|
||||||
}
|
}
|
||||||
|
|
||||||
for imageName, tagRegex := range cfg.ImagesByTagRegex {
|
// include repository descriptors for cfg.ImagesByTagRegex
|
||||||
repoLogger := logrus.WithFields(logrus.Fields{
|
{
|
||||||
"repo": imageName,
|
filterCollection, err := tagRegexFilterCollection(cfg.ImagesByTagRegex)
|
||||||
"registry": registryName,
|
|
||||||
})
|
|
||||||
repoRef, err := parseRepositoryReference(fmt.Sprintf("%s/%s", registryName, imageName))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
repoLogger.Error("Error parsing repository name, skipping")
|
|
||||||
logrus.Error(err)
|
logrus.Error(err)
|
||||||
continue
|
} else {
|
||||||
|
additionalRepoDescList := filterSourceReferences(serverCtx, registryName, filterCollection)
|
||||||
|
repoDescList = append(repoDescList, additionalRepoDescList...)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
repoLogger.Info("Processing repo")
|
// include repository descriptors for cfg.ImagesBySemver
|
||||||
|
{
|
||||||
var sourceReferences []types.ImageReference
|
filterCollection, err := semverFilterCollection(cfg.ImagesBySemver)
|
||||||
|
|
||||||
tagReg, err := regexp.Compile(tagRegex)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
repoLogger.WithFields(logrus.Fields{
|
|
||||||
"regex": tagRegex,
|
|
||||||
}).Error("Error parsing regex, skipping")
|
|
||||||
logrus.Error(err)
|
logrus.Error(err)
|
||||||
continue
|
} else {
|
||||||
|
additionalRepoDescList := filterSourceReferences(serverCtx, registryName, filterCollection)
|
||||||
|
repoDescList = append(repoDescList, additionalRepoDescList...)
|
||||||
}
|
}
|
||||||
|
|
||||||
repoLogger.Info("Querying registry for image tags")
|
|
||||||
allSourceReferences, err := imagesToCopyFromRepo(serverCtx, repoRef)
|
|
||||||
if err != nil {
|
|
||||||
repoLogger.Error("Error processing repo, skipping")
|
|
||||||
logrus.Error(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
repoLogger.Infof("Start filtering using the regular expression: %v", tagRegex)
|
|
||||||
for _, sReference := range allSourceReferences {
|
|
||||||
tagged, isTagged := sReference.DockerReference().(reference.Tagged)
|
|
||||||
if !isTagged {
|
|
||||||
repoLogger.Errorf("Internal error, reference %s does not have a tag, skipping", sReference.DockerReference())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if tagReg.MatchString(tagged.Tag()) {
|
|
||||||
sourceReferences = append(sourceReferences, sReference)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(sourceReferences) == 0 {
|
|
||||||
repoLogger.Warnf("No refs to sync found")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
repoDescList = append(repoDescList, repoDescriptor{
|
|
||||||
ImageRefs: sourceReferences,
|
|
||||||
Context: serverCtx})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return repoDescList, nil
|
return repoDescList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// filterFunc is a function used to limit the initial set of image references
|
||||||
|
// using tags, patterns, semver, etc.
|
||||||
|
type filterFunc func(*logrus.Entry, types.ImageReference) bool
|
||||||
|
|
||||||
|
// filterCollection is a map of repository names to filter functions.
|
||||||
|
type filterCollection map[string]filterFunc
|
||||||
|
|
||||||
|
// filterSourceReferences lists tags for images specified in the collection and
|
||||||
|
// filters them using assigned filter functions.
|
||||||
|
// It returns a list of repoDescriptors.
|
||||||
|
func filterSourceReferences(sys *types.SystemContext, registryName string, collection filterCollection) []repoDescriptor {
|
||||||
|
var repoDescList []repoDescriptor
|
||||||
|
for repoName, filter := range collection {
|
||||||
|
logger := logrus.WithFields(logrus.Fields{
|
||||||
|
"repo": repoName,
|
||||||
|
"registry": registryName,
|
||||||
|
})
|
||||||
|
|
||||||
|
repoRef, err := parseRepositoryReference(fmt.Sprintf("%s/%s", registryName, repoName))
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Error parsing repository name, skipping")
|
||||||
|
logrus.Error(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("Processing repo")
|
||||||
|
|
||||||
|
var sourceReferences []types.ImageReference
|
||||||
|
|
||||||
|
logger.Info("Querying registry for image tags")
|
||||||
|
sourceReferences, err = imagesToCopyFromRepo(sys, repoRef)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Error processing repo, skipping")
|
||||||
|
logrus.Error(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var filteredSourceReferences []types.ImageReference
|
||||||
|
for _, ref := range sourceReferences {
|
||||||
|
if filter(logger, ref) {
|
||||||
|
filteredSourceReferences = append(filteredSourceReferences, ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(filteredSourceReferences) == 0 {
|
||||||
|
logger.Warnf("No refs to sync found")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
repoDescList = append(repoDescList, repoDescriptor{
|
||||||
|
ImageRefs: filteredSourceReferences,
|
||||||
|
Context: sys,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return repoDescList
|
||||||
|
}
|
||||||
|
|
||||||
|
// tagRegexFilterCollection converts a map of (repository name, tag regex) pairs
|
||||||
|
// into a filterCollection, which is a map of (repository name, filter function)
|
||||||
|
// pairs.
|
||||||
|
func tagRegexFilterCollection(collection map[string]string) (filterCollection, error) {
|
||||||
|
filters := filterCollection{}
|
||||||
|
|
||||||
|
for repoName, tagRegex := range collection {
|
||||||
|
pattern, err := regexp.Compile(tagRegex)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
f := func(logger *logrus.Entry, sourceReference types.ImageReference) bool {
|
||||||
|
tagged, isTagged := sourceReference.DockerReference().(reference.Tagged)
|
||||||
|
if !isTagged {
|
||||||
|
logger.Errorf("Internal error, reference %s does not have a tag, skipping", sourceReference.DockerReference())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return pattern.MatchString(tagged.Tag())
|
||||||
|
}
|
||||||
|
filters[repoName] = f
|
||||||
|
}
|
||||||
|
|
||||||
|
return filters, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// semverFilterCollection converts a map of (repository name, array of semver constraints) pairs
|
||||||
|
// into a filterCollection, which is a map of (repository name, filter function)
|
||||||
|
// pairs.
|
||||||
|
func semverFilterCollection(collection map[string]string) (filterCollection, error) {
|
||||||
|
filters := filterCollection{}
|
||||||
|
|
||||||
|
for repoName, constraintString := range collection {
|
||||||
|
constraint, err := semver.NewConstraint(constraintString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
f := func(logger *logrus.Entry, sourceReference types.ImageReference) bool {
|
||||||
|
tagged, isTagged := sourceReference.DockerReference().(reference.Tagged)
|
||||||
|
if !isTagged {
|
||||||
|
logger.Errorf("Internal error, reference %s does not have a tag, skipping", sourceReference.DockerReference())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
tagVersion, err := semver.NewVersion(tagged.Tag())
|
||||||
|
if err != nil {
|
||||||
|
logger.Tracef("Tag %q cannot be parsed as semver, skipping", tagged.Tag())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return constraint.Check(tagVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
filters[repoName] = f
|
||||||
|
}
|
||||||
|
|
||||||
|
return filters, nil
|
||||||
|
}
|
||||||
|
|
||||||
// imagesToCopy retrieves all the images to copy from a specified sync source
|
// imagesToCopy retrieves all the images to copy from a specified sync source
|
||||||
// and transport.
|
// and transport.
|
||||||
// It returns a slice of repository descriptors, where each descriptor is a
|
// It returns a slice of repository descriptors, where each descriptor is a
|
||||||
@ -489,13 +585,6 @@ func imagesToCopy(source string, transport string, sourceCtx *types.SystemContex
|
|||||||
return descriptors, err
|
return descriptors, err
|
||||||
}
|
}
|
||||||
for registryName, registryConfig := range cfg {
|
for registryName, registryConfig := range cfg {
|
||||||
if len(registryConfig.Images) == 0 && len(registryConfig.ImagesByTagRegex) == 0 {
|
|
||||||
logrus.WithFields(logrus.Fields{
|
|
||||||
"registry": registryName,
|
|
||||||
}).Warn("No images specified for registry")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
descs, err := imagesToCopyFromRegistry(registryName, registryConfig, *sourceCtx)
|
descs, err := imagesToCopyFromRegistry(registryName, registryConfig, *sourceCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return descriptors, fmt.Errorf("Failed to retrieve list of images from registry %q: %w", registryName, err)
|
return descriptors, fmt.Errorf("Failed to retrieve list of images from registry %q: %w", registryName, err)
|
||||||
@ -637,10 +726,24 @@ func (opts *syncOptions) run(args []string, stdout io.Writer) (retErr error) {
|
|||||||
logrus.Warn("Running in dry-run mode")
|
logrus.Warn("Running in dry-run mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var digestFile *os.File
|
||||||
|
if opts.digestFile != "" && !opts.dryRun {
|
||||||
|
digestFile, err = os.OpenFile(opts.digestFile, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating digest file: %w", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := digestFile.Close(); err != nil {
|
||||||
|
retErr = noteCloseFailure(retErr, "closing digest file", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
for _, srcRepo := range srcRepoList {
|
for _, srcRepo := range srcRepoList {
|
||||||
options.SourceCtx = srcRepo.Context
|
options.SourceCtx = srcRepo.Context
|
||||||
for counter, ref := range srcRepo.ImageRefs {
|
for counter, ref := range srcRepo.ImageRefs {
|
||||||
var destSuffix string
|
var destSuffix string
|
||||||
|
var manifestBytes []byte
|
||||||
switch ref.Transport() {
|
switch ref.Transport() {
|
||||||
case docker.Transport:
|
case docker.Transport:
|
||||||
// docker -> dir or docker -> docker
|
// docker -> dir or docker -> docker
|
||||||
@ -672,7 +775,7 @@ func (opts *syncOptions) run(args []string, stdout io.Writer) (retErr error) {
|
|||||||
} else {
|
} else {
|
||||||
logrus.WithFields(fromToFields).Infof("Copying image ref %d/%d", counter+1, len(srcRepo.ImageRefs))
|
logrus.WithFields(fromToFields).Infof("Copying image ref %d/%d", counter+1, len(srcRepo.ImageRefs))
|
||||||
if err = retry.IfNecessary(ctx, func() error {
|
if err = retry.IfNecessary(ctx, func() error {
|
||||||
_, err = copy.Image(ctx, policyContext, destRef, ref, &options)
|
manifestBytes, err = copy.Image(ctx, policyContext, destRef, ref, &options)
|
||||||
return err
|
return err
|
||||||
}, opts.retryOpts); err != nil {
|
}, opts.retryOpts); err != nil {
|
||||||
if !opts.keepGoing {
|
if !opts.keepGoing {
|
||||||
@ -684,7 +787,19 @@ func (opts *syncOptions) run(args []string, stdout io.Writer) (retErr error) {
|
|||||||
logrus.WithError(err).Errorf("Error copying ref %q", transports.ImageName(ref))
|
logrus.WithError(err).Errorf("Error copying ref %q", transports.ImageName(ref))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Ensure that we log the manifest digest to a file only if the copy operation was successful
|
||||||
|
if opts.digestFile != "" {
|
||||||
|
manifestDigest, err := manifest.Digest(manifestBytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
outputStr := fmt.Sprintf("%s %s", manifestDigest.String(), transports.ImageName(destRef))
|
||||||
|
if _, err = digestFile.WriteString(outputStr + "\n"); err != nil {
|
||||||
|
return fmt.Errorf("Failed to write digest to file %q: %w", opts.digestFile, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
imagesNumber++
|
imagesNumber++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,3 +44,18 @@ func TestTLSVerifyConfig(t *testing.T) {
|
|||||||
err := yaml.Unmarshal([]byte(`tls-verify: "not a valid bool"`), &config)
|
err := yaml.Unmarshal([]byte(`tls-verify: "not a valid bool"`), &config)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSync(t *testing.T) {
|
||||||
|
// Invalid command-line arguments
|
||||||
|
for _, args := range [][]string{
|
||||||
|
{},
|
||||||
|
{"a1"},
|
||||||
|
{"a1", "a2", "a3"},
|
||||||
|
} {
|
||||||
|
out, err := runSkopeo(append([]string{"sync"}, args...)...)
|
||||||
|
assertTestFailed(t, out, err, "Exactly two arguments expected")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Much more test coverage
|
||||||
|
// Actual feature tests exist in integration and systemtest
|
||||||
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
//go:build !linux
|
//go:build !linux
|
||||||
// +build !linux
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
func reexecIfNecessaryForImages(inputImageNames ...string) error {
|
func reexecIfNecessaryForImages(_ ...string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/containers/image/v5/transports/alltransports"
|
"github.com/containers/image/v5/transports/alltransports"
|
||||||
"github.com/containers/storage/pkg/unshare"
|
"github.com/containers/storage/pkg/unshare"
|
||||||
"github.com/syndtr/gocapability/capability"
|
"github.com/moby/sys/capability"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var neededCapabilities = []capability.Cap{
|
var neededCapabilities = []capability.Cap{
|
||||||
|
@ -7,14 +7,19 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
commonFlag "github.com/containers/common/pkg/flag"
|
commonFlag "github.com/containers/common/pkg/flag"
|
||||||
"github.com/containers/common/pkg/retry"
|
"github.com/containers/common/pkg/retry"
|
||||||
"github.com/containers/image/v5/directory"
|
"github.com/containers/image/v5/directory"
|
||||||
"github.com/containers/image/v5/manifest"
|
"github.com/containers/image/v5/manifest"
|
||||||
|
ocilayout "github.com/containers/image/v5/oci/layout"
|
||||||
"github.com/containers/image/v5/pkg/compression"
|
"github.com/containers/image/v5/pkg/compression"
|
||||||
|
"github.com/containers/image/v5/storage"
|
||||||
"github.com/containers/image/v5/transports/alltransports"
|
"github.com/containers/image/v5/transports/alltransports"
|
||||||
"github.com/containers/image/v5/types"
|
"github.com/containers/image/v5/types"
|
||||||
|
dockerdistributionerrcode "github.com/docker/distribution/registry/api/errcode"
|
||||||
|
dockerdistributionapi "github.com/docker/distribution/registry/api/v2"
|
||||||
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -22,7 +27,7 @@ import (
|
|||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
// errorShouldDisplayUsage is a subtype of error used by command handlers to indicate that cli.ShowSubcommandHelp should be called.
|
// errorShouldDisplayUsage is a subtype of error used by command handlers to indicate that the command’s help should be included.
|
||||||
type errorShouldDisplayUsage struct {
|
type errorShouldDisplayUsage struct {
|
||||||
error
|
error
|
||||||
}
|
}
|
||||||
@ -58,7 +63,8 @@ func commandAction(handler func(args []string, stdout io.Writer) error) func(cmd
|
|||||||
err := handler(args, c.OutOrStdout())
|
err := handler(args, c.OutOrStdout())
|
||||||
var shouldDisplayUsage errorShouldDisplayUsage
|
var shouldDisplayUsage errorShouldDisplayUsage
|
||||||
if errors.As(err, &shouldDisplayUsage) {
|
if errors.As(err, &shouldDisplayUsage) {
|
||||||
return c.Help()
|
c.SetOut(c.ErrOrStderr()) // This mutates c, but we are failing anyway.
|
||||||
|
_ = c.Help() // Even if this failed, we prefer to report the original error
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -179,6 +185,7 @@ func retryFlags() (pflag.FlagSet, *retry.Options) {
|
|||||||
opts := retry.Options{}
|
opts := retry.Options{}
|
||||||
fs := pflag.FlagSet{}
|
fs := pflag.FlagSet{}
|
||||||
fs.IntVar(&opts.MaxRetry, "retry-times", 0, "the number of times to possibly retry")
|
fs.IntVar(&opts.MaxRetry, "retry-times", 0, "the number of times to possibly retry")
|
||||||
|
fs.DurationVar(&opts.Delay, "retry-delay", 0*time.Second, "Fixed delay between retries. If not set, retry uses an exponential backoff delay.")
|
||||||
return fs, &opts
|
return fs, &opts
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,8 +200,8 @@ func (opts *imageOptions) newSystemContext() (*types.SystemContext, error) {
|
|||||||
ctx.AuthFilePath = opts.shared.authFilePath
|
ctx.AuthFilePath = opts.shared.authFilePath
|
||||||
ctx.DockerDaemonHost = opts.dockerDaemonHost
|
ctx.DockerDaemonHost = opts.dockerDaemonHost
|
||||||
ctx.DockerDaemonCertPath = opts.dockerCertPath
|
ctx.DockerDaemonCertPath = opts.dockerCertPath
|
||||||
if opts.dockerImageOptions.authFilePath.Present() {
|
if opts.authFilePath.Present() {
|
||||||
ctx.AuthFilePath = opts.dockerImageOptions.authFilePath.Value()
|
ctx.AuthFilePath = opts.authFilePath.Value()
|
||||||
}
|
}
|
||||||
if opts.deprecatedTLSVerify != nil && opts.deprecatedTLSVerify.tlsVerify.Present() {
|
if opts.deprecatedTLSVerify != nil && opts.deprecatedTLSVerify.tlsVerify.Present() {
|
||||||
// If both this deprecated option and a non-deprecated option is present, we use the latter value.
|
// If both this deprecated option and a non-deprecated option is present, we use the latter value.
|
||||||
@ -406,3 +413,23 @@ func promptForPassphrase(privateKeyFile string, stdin, stdout *os.File) (string,
|
|||||||
fmt.Fprintf(stdout, "\n")
|
fmt.Fprintf(stdout, "\n")
|
||||||
return string(passphrase), nil
|
return string(passphrase), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isNotFoundImageError heuristically attempts to determine whether an error
|
||||||
|
// is saying the remote source couldn't find the image (as opposed to an
|
||||||
|
// authentication error, an I/O error etc.)
|
||||||
|
// TODO drive this into containers/image properly
|
||||||
|
func isNotFoundImageError(err error) bool {
|
||||||
|
return isDockerManifestUnknownError(err) ||
|
||||||
|
errors.Is(err, storage.ErrNoSuchImage) ||
|
||||||
|
errors.Is(err, ocilayout.ImageNotFoundError{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// isDockerManifestUnknownError is a copy of code from containers/image,
|
||||||
|
// please update there first.
|
||||||
|
func isDockerManifestUnknownError(err error) bool {
|
||||||
|
var ec dockerdistributionerrcode.ErrorCoder
|
||||||
|
if !errors.As(err, &ec) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return ec.ErrorCode() == dockerdistributionapi.ErrorCodeManifestUnknown
|
||||||
|
}
|
||||||
|
40
contrib/cirrus/mac_cleanup.sh
Executable file
40
contrib/cirrus/mac_cleanup.sh
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script is intended to be called by Cirrus-CI on a Mac M1 persistent worker.
|
||||||
|
# It performs a best-effort attempt at cleaning up from one task execution to the next.
|
||||||
|
# Since it run both before and after tasks, it must exit cleanly if there was a cleanup
|
||||||
|
# failure (i.e. file or directory not found).
|
||||||
|
|
||||||
|
# Help anybody debugging side-effects, since failures are ignored (by necessity).
|
||||||
|
set +e -x
|
||||||
|
|
||||||
|
# These are the main processes which could leak out of testing.
|
||||||
|
killall podman vfkit gvproxy make go ginkgo
|
||||||
|
|
||||||
|
mkdir -p $TMPDIR
|
||||||
|
|
||||||
|
# Golang will leave behind lots of read-only bits, ref:
|
||||||
|
# https://go.dev/ref/mod#module-cache
|
||||||
|
# However other tools/scripts could also set things read-only.
|
||||||
|
# At this point in CI, we really want all this stuff gone-gone,
|
||||||
|
# so there's actually zero-chance it can interfere.
|
||||||
|
chmod -R u+w $TMPDIR/* $TMPDIR/.??*
|
||||||
|
|
||||||
|
# This is defined as $TMPDIR during setup. Name must be kept
|
||||||
|
# "short" as sockets may reside here. Darwin suffers from
|
||||||
|
# the same limited socket-pathname character-length restriction
|
||||||
|
# as Linux.
|
||||||
|
rm -rf $TMPDIR/* $TMPDIR/.??*
|
||||||
|
|
||||||
|
# Don't change or clobber anything under $CIRRUS_WORKING_DIR for
|
||||||
|
# the currently running task. But make sure we have write permission
|
||||||
|
# (go get sets dependencies ro) for everything else, before removing it.
|
||||||
|
# First make everything writeable - see the "Golang will..." comment above.
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
find "$HOME/ci" -mindepth 1 -maxdepth 1 \
|
||||||
|
-not -name "*task-${CIRRUS_TASK_ID}*" -prune -exec chmod -R u+w '{}' +
|
||||||
|
find "$HOME/ci" -mindepth 1 -maxdepth 1 \
|
||||||
|
-not -name "*task-${CIRRUS_TASK_ID}*" -prune -exec rm -rf '{}' +
|
||||||
|
|
||||||
|
# Bash scripts exit with the status of the last command.
|
||||||
|
true
|
@ -8,7 +8,7 @@ ARG CIRRUS_IMAGE_VERSION
|
|||||||
ENV CIRRUS_IMAGE_VERSION=$CIRRUS_IMAGE_VERSION
|
ENV CIRRUS_IMAGE_VERSION=$CIRRUS_IMAGE_VERSION
|
||||||
ADD https://sh.rustup.rs /var/tmp/rustup_installer.sh
|
ADD https://sh.rustup.rs /var/tmp/rustup_installer.sh
|
||||||
|
|
||||||
RUN dnf erase -y rust && \
|
RUN dnf remove -y rust && \
|
||||||
chmod +x /var/tmp/rustup_installer.sh && \
|
chmod +x /var/tmp/rustup_installer.sh && \
|
||||||
/var/tmp/rustup_installer.sh -y --default-toolchain stable --profile minimal
|
/var/tmp/rustup_installer.sh -y --default-toolchain stable --profile minimal
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ _run_setup() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# VM's come with the distro. skopeo package pre-installed
|
# VM's come with the distro. skopeo package pre-installed
|
||||||
dnf erase -y skopeo
|
dnf remove -y skopeo
|
||||||
|
|
||||||
msg "Removing systemd-resolved from nsswitch.conf"
|
msg "Removing systemd-resolved from nsswitch.conf"
|
||||||
# /etc/resolv.conf is already set to bypass systemd-resolvd
|
# /etc/resolv.conf is already set to bypass systemd-resolvd
|
||||||
@ -128,7 +128,7 @@ _run_system() {
|
|||||||
make test-system-local BUILDTAGS="$BUILDTAGS"
|
make test-system-local BUILDTAGS="$BUILDTAGS"
|
||||||
}
|
}
|
||||||
|
|
||||||
req_env_vars SKOPEO_PATH BUILDTAGS
|
req_env_vars SKOPEO_PATH
|
||||||
|
|
||||||
handler="_run_${1}"
|
handler="_run_${1}"
|
||||||
if [ "$(type -t $handler)" != "function" ]; then
|
if [ "$(type -t $handler)" != "function" ]; then
|
||||||
|
@ -1,68 +1,2 @@
|
|||||||
[comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***)
|
The skopeo container image build context and automation have been
|
||||||
[comment]: <> ()
|
moved to [https://github.com/containers/image_build/tree/main/skopeo](https://github.com/containers/image_build/tree/main/skopeo)
|
||||||
[comment]: <> (ANY changes made to this file, once committed/merged must)
|
|
||||||
[comment]: <> (be manually copy/pasted -in markdown- into the description)
|
|
||||||
[comment]: <> (field on Quay at the following locations:)
|
|
||||||
[comment]: <> ()
|
|
||||||
[comment]: <> (https://quay.io/repository/containers/skopeo)
|
|
||||||
[comment]: <> (https://quay.io/repository/skopeo/stable)
|
|
||||||
[comment]: <> (https://quay.io/repository/skopeo/testing)
|
|
||||||
[comment]: <> (https://quay.io/repository/skopeo/upstream)
|
|
||||||
[comment]: <> ()
|
|
||||||
[comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***)
|
|
||||||
|
|
||||||
<img src="https://cdn.rawgit.com/containers/skopeo/main/docs/skopeo.svg" width="250">
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
# skopeoimage
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This directory contains the Containerfiles necessary to create the skopeoimage container
|
|
||||||
images that are housed on quay.io under the skopeo account. All repositories where
|
|
||||||
the images live are public and can be pulled without credentials. These container images are secured and the
|
|
||||||
resulting containers can run safely with privileges within the container.
|
|
||||||
|
|
||||||
The container images are built using the latest Fedora and then Skopeo is installed into them.
|
|
||||||
The ENTRYPOINT of the container is set to execute the `skopeo` binary.
|
|
||||||
|
|
||||||
The container images are:
|
|
||||||
|
|
||||||
* `quay.io/containers/skopeo:v<version>` and `quay.io/skopeo/stable:v<version>` -
|
|
||||||
These images are built daily. These images are intended contain an unchanging
|
|
||||||
and stable version of skopeo. For the most recent `<version>` tags (`vX`,
|
|
||||||
`vX.Y`, and `vX.Y.Z`) the image contents will be updated daily to incorporate
|
|
||||||
(especially) security updates. For build details, please[see the configuration
|
|
||||||
file](stable/Containerfile).
|
|
||||||
* `quay.io/containers/skopeo:latest` and `quay.io/skopeo/stable:latest` -
|
|
||||||
Built daily using the same Containerfile as above. The skopeo version
|
|
||||||
will remain the "latest" available in Fedora, however the other image
|
|
||||||
contents may vary compared to the version-tagged images.
|
|
||||||
* `quay.io/skopeo/testing:latest` - This image is built daily, using the
|
|
||||||
latest version of Skopeo that was in the Fedora `updates-testing` repository.
|
|
||||||
The image is Built with [the testing Containerfile](testing/Containerfile).
|
|
||||||
* `quay.io/skopeo/upstream:latest` - This image is built daily using the latest
|
|
||||||
code found in this GitHub repository. Due to the image changing frequently,
|
|
||||||
it's not guaranteed to be stable or even executable. The image is built with
|
|
||||||
[the upstream Containerfile](upstream/Containerfile).
|
|
||||||
|
|
||||||
|
|
||||||
## Sample Usage
|
|
||||||
|
|
||||||
Although not required, it is suggested that [Podman](https://github.com/containers/podman) be used with these container images.
|
|
||||||
|
|
||||||
```
|
|
||||||
# Get Help on Skopeo
|
|
||||||
podman run docker://quay.io/skopeo/stable:latest --help
|
|
||||||
|
|
||||||
# Get help on the Skopeo Copy command
|
|
||||||
podman run docker://quay.io/skopeo/stable:latest copy --help
|
|
||||||
|
|
||||||
# Copy the Skopeo container image from quay.io to
|
|
||||||
# a private registry
|
|
||||||
podman run docker://quay.io/skopeo/stable:latest copy docker://quay.io/skopeo/stable docker://registry.internal.company.com/skopeo
|
|
||||||
|
|
||||||
# Inspect the fedora:latest image
|
|
||||||
podman run docker://quay.io/skopeo/stable:latest inspect --config docker://registry.fedoraproject.org/fedora:latest | jq
|
|
||||||
```
|
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
# stable/Containerfile
|
|
||||||
#
|
|
||||||
# Build a Skopeo container image from the latest
|
|
||||||
# stable version of Skopeo on the Fedoras Updates System.
|
|
||||||
# https://bodhi.fedoraproject.org/updates/?search=skopeo
|
|
||||||
# This image can be used to create a secured container
|
|
||||||
# that runs safely with privileges within the container.
|
|
||||||
#
|
|
||||||
FROM registry.fedoraproject.org/fedora:latest
|
|
||||||
|
|
||||||
# Don't include container-selinux and remove
|
|
||||||
# directories used by dnf that are just taking
|
|
||||||
# up space.
|
|
||||||
# TODO: rpm --setcaps... needed due to Fedora (base) image builds
|
|
||||||
# being (maybe still?) affected by
|
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1995337#c3
|
|
||||||
RUN dnf -y update && \
|
|
||||||
rpm --setcaps shadow-utils 2>/dev/null && \
|
|
||||||
dnf -y install skopeo fuse-overlayfs \
|
|
||||||
--exclude container-selinux && \
|
|
||||||
dnf clean all && \
|
|
||||||
rm -rf /var/cache /var/log/dnf* /var/log/yum.*
|
|
||||||
|
|
||||||
RUN useradd skopeo && \
|
|
||||||
echo skopeo:100000:65536 > /etc/subuid && \
|
|
||||||
echo skopeo:100000:65536 > /etc/subgid
|
|
||||||
|
|
||||||
# Copy & modify the defaults to provide reference if runtime changes needed.
|
|
||||||
# Changes here are required for running with fuse-overlay storage inside container.
|
|
||||||
RUN sed -e 's|^#mount_program|mount_program|g' \
|
|
||||||
-e '/additionalimage.*/a "/var/lib/shared",' \
|
|
||||||
-e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \
|
|
||||||
/usr/share/containers/storage.conf \
|
|
||||||
> /etc/containers/storage.conf
|
|
||||||
|
|
||||||
# Setup the ability to use additional stores
|
|
||||||
# with this container image.
|
|
||||||
RUN mkdir -p /var/lib/shared/overlay-images \
|
|
||||||
/var/lib/shared/overlay-layers && \
|
|
||||||
touch /var/lib/shared/overlay-images/images.lock && \
|
|
||||||
touch /var/lib/shared/overlay-layers/layers.lock
|
|
||||||
|
|
||||||
# Point to the Authorization file
|
|
||||||
ENV REGISTRY_AUTH_FILE=/tmp/auth.json
|
|
||||||
|
|
||||||
# Set the entrypoint
|
|
||||||
ENTRYPOINT ["/usr/bin/skopeo"]
|
|
@ -1,49 +0,0 @@
|
|||||||
# testing/Containerfile
|
|
||||||
#
|
|
||||||
# Build a Skopeo container image from the latest
|
|
||||||
# version of Skopeo that is in updates-testing
|
|
||||||
# on the Fedoras Updates System.
|
|
||||||
# https://bodhi.fedoraproject.org/updates/?search=skopeo
|
|
||||||
# This image can be used to create a secured container
|
|
||||||
# that runs safely with privileges within the container.
|
|
||||||
#
|
|
||||||
FROM registry.fedoraproject.org/fedora:latest
|
|
||||||
|
|
||||||
# Don't include container-selinux and remove
|
|
||||||
# directories used by dnf that are just taking
|
|
||||||
# up space.
|
|
||||||
# TODO: rpm --setcaps... needed due to Fedora (base) image builds
|
|
||||||
# being (maybe still?) affected by
|
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1995337#c3
|
|
||||||
RUN dnf -y update && \
|
|
||||||
rpm --setcaps shadow-utils 2>/dev/null && \
|
|
||||||
dnf -y install skopeo fuse-overlayfs \
|
|
||||||
--exclude container-selinux \
|
|
||||||
--enablerepo updates-testing && \
|
|
||||||
dnf clean all && \
|
|
||||||
rm -rf /var/cache /var/log/dnf* /var/log/yum.*
|
|
||||||
|
|
||||||
RUN useradd skopeo && \
|
|
||||||
echo skopeo:100000:65536 > /etc/subuid && \
|
|
||||||
echo skopeo:100000:65536 > /etc/subgid
|
|
||||||
|
|
||||||
# Copy & modify the defaults to provide reference if runtime changes needed.
|
|
||||||
# Changes here are required for running with fuse-overlay storage inside container.
|
|
||||||
RUN sed -e 's|^#mount_program|mount_program|g' \
|
|
||||||
-e '/additionalimage.*/a "/var/lib/shared",' \
|
|
||||||
-e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \
|
|
||||||
/usr/share/containers/storage.conf \
|
|
||||||
> /etc/containers/storage.conf
|
|
||||||
|
|
||||||
# Setup the ability to use additional stores
|
|
||||||
# with this container image.
|
|
||||||
RUN mkdir -p /var/lib/shared/overlay-images \
|
|
||||||
/var/lib/shared/overlay-layers && \
|
|
||||||
touch /var/lib/shared/overlay-images/images.lock && \
|
|
||||||
touch /var/lib/shared/overlay-layers/layers.lock
|
|
||||||
|
|
||||||
# Point to the Authorization file
|
|
||||||
ENV REGISTRY_AUTH_FILE=/tmp/auth.json
|
|
||||||
|
|
||||||
# Set the entrypoint
|
|
||||||
ENTRYPOINT ["/usr/bin/skopeo"]
|
|
@ -1,50 +0,0 @@
|
|||||||
# upstream/Containerfile
|
|
||||||
#
|
|
||||||
# Build a Skopeo container image from the latest
|
|
||||||
# upstream version of Skopeo on GitHub.
|
|
||||||
# https://github.com/containers/skopeo
|
|
||||||
# This image can be used to create a secured container
|
|
||||||
# that runs safely with privileges within the container.
|
|
||||||
#
|
|
||||||
FROM registry.fedoraproject.org/fedora:latest
|
|
||||||
|
|
||||||
# Don't include container-selinux and remove
|
|
||||||
# directories used by dnf that are just taking
|
|
||||||
# up space.
|
|
||||||
# TODO: rpm --setcaps... needed due to Fedora (base) image builds
|
|
||||||
# being (maybe still?) affected by
|
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1995337#c3
|
|
||||||
RUN dnf -y update && \
|
|
||||||
rpm --setcaps shadow-utils 2>/dev/null && \
|
|
||||||
dnf -y install 'dnf-command(copr)' --enablerepo=updates-testing && \
|
|
||||||
dnf -y copr enable rhcontainerbot/podman-next && \
|
|
||||||
dnf -y install skopeo \
|
|
||||||
--exclude container-selinux \
|
|
||||||
--enablerepo=updates-testing && \
|
|
||||||
dnf clean all && \
|
|
||||||
rm -rf /var/cache /var/log/dnf* /var/log/yum.*
|
|
||||||
|
|
||||||
RUN useradd skopeo && \
|
|
||||||
echo skopeo:100000:65536 > /etc/subuid && \
|
|
||||||
echo skopeo:100000:65536 > /etc/subgid
|
|
||||||
|
|
||||||
# Copy & modify the defaults to provide reference if runtime changes needed.
|
|
||||||
# Changes here are required for running with fuse-overlay storage inside container.
|
|
||||||
RUN sed -e 's|^#mount_program|mount_program|g' \
|
|
||||||
-e '/additionalimage.*/a "/var/lib/shared",' \
|
|
||||||
-e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \
|
|
||||||
/usr/share/containers/storage.conf \
|
|
||||||
> /etc/containers/storage.conf
|
|
||||||
|
|
||||||
# Setup the ability to use additional stores
|
|
||||||
# with this container image.
|
|
||||||
RUN mkdir -p /var/lib/shared/overlay-images \
|
|
||||||
/var/lib/shared/overlay-layers && \
|
|
||||||
touch /var/lib/shared/overlay-images/images.lock && \
|
|
||||||
touch /var/lib/shared/overlay-layers/layers.lock
|
|
||||||
|
|
||||||
# Point to the Authorization file
|
|
||||||
ENV REGISTRY_AUTH_FILE=/tmp/auth.json
|
|
||||||
|
|
||||||
# Set the entrypoint
|
|
||||||
ENTRYPOINT ["/usr/bin/skopeo"]
|
|
@ -183,6 +183,8 @@ Existing signatures, if any, are preserved as well.
|
|||||||
**--dest-compress-format** _format_
|
**--dest-compress-format** _format_
|
||||||
|
|
||||||
Specifies the compression format to use. Supported values are: `gzip`, `zstd` and `zstd:chunked`.
|
Specifies the compression format to use. Supported values are: `gzip`, `zstd` and `zstd:chunked`.
|
||||||
|
`zstd:chunked` is incompatible with encrypting images,
|
||||||
|
and will be treated as `zstd` with a warning in that case.
|
||||||
|
|
||||||
**--dest-compress-level** _format_
|
**--dest-compress-level** _format_
|
||||||
|
|
||||||
@ -202,7 +204,11 @@ Precompute digests to ensure layers are not uploaded that already exist on the d
|
|||||||
|
|
||||||
**--retry-times**
|
**--retry-times**
|
||||||
|
|
||||||
The number of times to retry. Retry wait time will be exponentially increased based on the number of failed attempts.
|
The number of times to retry.
|
||||||
|
|
||||||
|
**--retry-delay**
|
||||||
|
|
||||||
|
Fixed delay between retries. If not set (or set to 0s), retry wait time will be exponentially increased based on the number of failed attempts.
|
||||||
|
|
||||||
**--src-username**
|
**--src-username**
|
||||||
|
|
||||||
@ -220,6 +226,10 @@ The username to access the destination registry.
|
|||||||
|
|
||||||
The password to access the destination registry.
|
The password to access the destination registry.
|
||||||
|
|
||||||
|
**--image-parallel-copies** _n_
|
||||||
|
|
||||||
|
Maximum number of image layers to be copied (pulled/pushed) simultaneously. Not setting this field will fall back to containers/image defaults.
|
||||||
|
|
||||||
## EXAMPLES
|
## EXAMPLES
|
||||||
|
|
||||||
To just copy an image from one registry to another:
|
To just copy an image from one registry to another:
|
||||||
|
@ -66,7 +66,11 @@ Bearer token for accessing the registry.
|
|||||||
|
|
||||||
**--retry-times**
|
**--retry-times**
|
||||||
|
|
||||||
The number of times to retry. Retry wait time will be exponentially increased based on the number of failed attempts.
|
The number of times to retry.
|
||||||
|
|
||||||
|
**--retry-delay**
|
||||||
|
|
||||||
|
Fixed delay between retries. If not set (or set to 0s), retry wait time will be exponentially increased based on the number of failed attempts.
|
||||||
|
|
||||||
**--shared-blob-dir** _directory_
|
**--shared-blob-dir** _directory_
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ The private key is encrypted with a passphrase;
|
|||||||
if one is not provided using an option, this command prompts for it interactively.
|
if one is not provided using an option, this command prompts for it interactively.
|
||||||
|
|
||||||
The private key is written to _prefix_**.private** .
|
The private key is written to _prefix_**.private** .
|
||||||
The private key is written to _prefix_**.pub** .
|
The public key is written to _prefix_**.pub** .
|
||||||
|
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
|
@ -65,7 +65,11 @@ Registry token for accessing the registry.
|
|||||||
|
|
||||||
**--retry-times**
|
**--retry-times**
|
||||||
|
|
||||||
The number of times to retry; retry wait time will be exponentially increased based on the number of failed attempts.
|
The number of times to retry.
|
||||||
|
|
||||||
|
**--retry-delay**
|
||||||
|
|
||||||
|
Fixed delay between retries. If not set (or set to 0s), retry wait time will be exponentially increased based on the number of failed attempts.
|
||||||
|
|
||||||
**--shared-blob-dir** _directory_
|
**--shared-blob-dir** _directory_
|
||||||
|
|
||||||
|
@ -39,7 +39,11 @@ Bearer token for accessing the registry.
|
|||||||
|
|
||||||
**--retry-times**
|
**--retry-times**
|
||||||
|
|
||||||
The number of times to retry. Retry wait time will be exponentially increased based on the number of failed attempts.
|
The number of times to retry.
|
||||||
|
|
||||||
|
**--retry-delay**
|
||||||
|
|
||||||
|
Fixed delay between retries. If not set (or set to 0s), retry wait time will be exponentially increased based on the number of failed attempts.
|
||||||
|
|
||||||
**--tls-verify**=_bool_
|
**--tls-verify**=_bool_
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
% skopeo-standalone-sign(1)
|
% skopeo-standalone-sign(1)
|
||||||
|
|
||||||
## NAME
|
## NAME
|
||||||
skopeo\-standalone-sign - Debugging tool - Publish and sign an image in one step.
|
skopeo\-standalone-sign - Debugging tool - Sign an image locally without uploading.
|
||||||
|
|
||||||
## SYNOPSIS
|
## SYNOPSIS
|
||||||
**skopeo standalone-sign** [*options*] _manifest_ _docker-reference_ _key-fingerprint_ **--output**|**-o** _signature_
|
**skopeo standalone-sign** [*options*] _manifest_ _docker-reference_ _key-fingerprint_ **--output**|**-o** _signature_
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
% skopeo-standalone-verify(1)
|
% skopeo-standalone-verify(1)
|
||||||
|
|
||||||
## NAME
|
## NAME
|
||||||
skopeo\-standalone\-verify - Verify an image signature.
|
skopeo\-standalone\-verify - Debugging tool - Verify an image signature from local files.
|
||||||
|
|
||||||
## SYNOPSIS
|
## SYNOPSIS
|
||||||
**skopeo standalone-verify** _manifest_ _docker-reference_ _key-fingerprints_ _signature_
|
**skopeo standalone-verify** _manifest_ _docker-reference_ _key-fingerprints_ _signature_
|
||||||
|
@ -68,6 +68,16 @@ Print usage statement.
|
|||||||
|
|
||||||
**--append-suffix** _tag-suffix_ String to append to destination tags.
|
**--append-suffix** _tag-suffix_ String to append to destination tags.
|
||||||
|
|
||||||
|
**--digestfile** _path_
|
||||||
|
|
||||||
|
After copying the images from source, write the digest of the resulting images along with Image Reference.
|
||||||
|
|
||||||
|
```
|
||||||
|
sha256:bf91f90823248017a4f920fb541727fa8368dc6cf377a7debbd271cf6a31c8a7 docker://myhost.com/alpine:edge
|
||||||
|
sha256:31603596830fc7e56753139f9c2c6bd3759e48a850659506ebfb885d1cf3aef5 docker://myhost.com/postgres:14.3
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
**--preserve-digests**
|
**--preserve-digests**
|
||||||
|
|
||||||
Preserve the digests during copying. Fail if the digest cannot be preserved.
|
Preserve the digests during copying. Fail if the digest cannot be preserved.
|
||||||
@ -113,7 +123,13 @@ The passphare to use when signing with `--sign-by` or `--sign-by-sigstore-privat
|
|||||||
|
|
||||||
**--dest-registry-token** _Bearer token_ for accessing the destination registry.
|
**--dest-registry-token** _Bearer token_ for accessing the destination registry.
|
||||||
|
|
||||||
**--retry-times** the number of times to retry, retry wait time will be exponentially increased based on the number of failed attempts.
|
**--retry-times**
|
||||||
|
|
||||||
|
The number of times to retry.
|
||||||
|
|
||||||
|
**--retry-delay**
|
||||||
|
|
||||||
|
Fixed delay between retries. If not set (or set to 0s), retry wait time will be exponentially increased based on the number of failed attempts.
|
||||||
|
|
||||||
**--keep-going**
|
**--keep-going**
|
||||||
If any errors occur during copying of images, those errors are logged and the process continues syncing rest of the images and finally fails at the end.
|
If any errors occur during copying of images, those errors are logged and the process continues syncing rest of the images and finally fails at the end.
|
||||||
@ -219,6 +235,8 @@ registry.example.com:
|
|||||||
- "sha256:0000000000000000000000000000000011111111111111111111111111111111"
|
- "sha256:0000000000000000000000000000000011111111111111111111111111111111"
|
||||||
images-by-tag-regex:
|
images-by-tag-regex:
|
||||||
nginx: ^1\.13\.[12]-alpine-perl$
|
nginx: ^1\.13\.[12]-alpine-perl$
|
||||||
|
images-by-semver:
|
||||||
|
alpine: ">= 3.12.0"
|
||||||
credentials:
|
credentials:
|
||||||
username: john
|
username: john
|
||||||
password: this is a secret
|
password: this is a secret
|
||||||
@ -239,6 +257,14 @@ This will copy the following images:
|
|||||||
- Repository `registry.example.com/redis`: images tagged "1.0" and "2.0" along with image with digest "sha256:0000000000000000000000000000000011111111111111111111111111111111".
|
- Repository `registry.example.com/redis`: images tagged "1.0" and "2.0" along with image with digest "sha256:0000000000000000000000000000000011111111111111111111111111111111".
|
||||||
- Repository `registry.example.com/nginx`: images tagged "1.13.1-alpine-perl" and "1.13.2-alpine-perl".
|
- Repository `registry.example.com/nginx`: images tagged "1.13.1-alpine-perl" and "1.13.2-alpine-perl".
|
||||||
- Repository `quay.io/coreos/etcd`: images tagged "latest".
|
- Repository `quay.io/coreos/etcd`: images tagged "latest".
|
||||||
|
- Repository `registry.example.com/alpine`: all images with tags match the semantic version constraint ">= 3.12.0" ("3.12.0, "3.12.1", ... ,"4.0.0", ...)
|
||||||
|
|
||||||
|
The full list of possible semantic version comparisons can be found in the
|
||||||
|
upstream library's documentation:
|
||||||
|
https://github.com/Masterminds/semver/tree/v3.2.0#basic-comparisons.
|
||||||
|
|
||||||
|
Version ordering and precedence is understood as defined here:
|
||||||
|
https://semver.org/#spec-item-11.
|
||||||
|
|
||||||
For the registry `registry.example.com`, the "john"/"this is a secret" credentials are used, with server TLS certificates located at `/home/john/certs`.
|
For the registry `registry.example.com`, the "john"/"this is a secret" credentials are used, with server TLS certificates located at `/home/john/certs`.
|
||||||
|
|
||||||
|
@ -110,10 +110,19 @@ Print the version number
|
|||||||
| [skopeo-login(1)](skopeo-login.1.md) | Login to a container registry. |
|
| [skopeo-login(1)](skopeo-login.1.md) | Login to a container registry. |
|
||||||
| [skopeo-logout(1)](skopeo-logout.1.md) | Logout of a container registry. |
|
| [skopeo-logout(1)](skopeo-logout.1.md) | Logout of a container registry. |
|
||||||
| [skopeo-manifest-digest(1)](skopeo-manifest-digest.1.md) | Compute a manifest digest for a manifest-file and write it to standard output. |
|
| [skopeo-manifest-digest(1)](skopeo-manifest-digest.1.md) | Compute a manifest digest for a manifest-file and write it to standard output. |
|
||||||
| [skopeo-standalone-sign(1)](skopeo-standalone-sign.1.md) | Debugging tool - Publish and sign an image in one step. |
|
| [skopeo-standalone-sign(1)](skopeo-standalone-sign.1.md) | Debugging tool - Sign an image locally without uploading. |
|
||||||
| [skopeo-standalone-verify(1)](skopeo-standalone-verify.1.md)| Verify an image signature. |
|
| [skopeo-standalone-verify(1)](skopeo-standalone-verify.1.md)| Debugging tool - Verify an image signature from local files. |
|
||||||
| [skopeo-sync(1)](skopeo-sync.1.md)| Synchronize images between registry repositories and local directories. |
|
| [skopeo-sync(1)](skopeo-sync.1.md)| Synchronize images between registry repositories and local directories. |
|
||||||
|
|
||||||
|
## EXIT STATUS
|
||||||
|
`skopeo` exits with status 0 on success, non-zero on error.
|
||||||
|
|
||||||
|
Details about the exit statuses:
|
||||||
|
|
||||||
|
**1** Generic error, details can be found in the error message.
|
||||||
|
|
||||||
|
**2** The input image cannot be found. Note that this is best effort and for remote registries the status often cannot be reliably reported.
|
||||||
|
|
||||||
## FILES
|
## FILES
|
||||||
**/etc/containers/policy.json**
|
**/etc/containers/policy.json**
|
||||||
Default trust policy file, if **--policy** is not specified.
|
Default trust policy file, if **--policy** is not specified.
|
||||||
|
187
go.mod
187
go.mod
@ -1,133 +1,136 @@
|
|||||||
module github.com/containers/skopeo
|
module github.com/containers/skopeo
|
||||||
|
|
||||||
go 1.19
|
// Minimum required golang version
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
// Warning: Ensure the "go" and "toolchain" versions match exactly to prevent unwanted auto-updates
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/containers/common v0.57.2
|
github.com/Masterminds/semver/v3 v3.3.1
|
||||||
github.com/containers/image/v5 v5.29.1
|
github.com/containers/common v0.62.3
|
||||||
github.com/containers/ocicrypt v1.1.9
|
github.com/containers/image/v5 v5.34.3
|
||||||
github.com/containers/storage v1.51.0
|
github.com/containers/ocicrypt v1.2.1
|
||||||
|
github.com/containers/storage v1.58.0
|
||||||
github.com/docker/distribution v2.8.3+incompatible
|
github.com/docker/distribution v2.8.3+incompatible
|
||||||
|
github.com/moby/sys/capability v0.4.0
|
||||||
github.com/opencontainers/go-digest v1.0.0
|
github.com/opencontainers/go-digest v1.0.0
|
||||||
github.com/opencontainers/image-spec v1.1.0-rc5
|
github.com/opencontainers/image-spec v1.1.1
|
||||||
github.com/opencontainers/image-tools v1.0.0-rc3
|
github.com/opencontainers/image-tools v1.0.0-rc3
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spf13/cobra v1.8.0
|
github.com/spf13/cobra v1.9.1
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.6
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.10.0
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
|
golang.org/x/term v0.32.0
|
||||||
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b
|
|
||||||
golang.org/x/term v0.16.0
|
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
dario.cat/mergo v1.0.0 // indirect
|
dario.cat/mergo v1.0.1 // indirect
|
||||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||||
github.com/Microsoft/hcsshim v0.12.0-rc.1 // indirect
|
github.com/Microsoft/hcsshim v0.12.9 // indirect
|
||||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
|
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
|
||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||||
github.com/containerd/cgroups/v3 v3.0.2 // indirect
|
github.com/containerd/cgroups/v3 v3.0.5 // indirect
|
||||||
github.com/containerd/containerd v1.7.9 // indirect
|
github.com/containerd/errdefs v0.3.0 // indirect
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
|
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||||
|
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
|
||||||
|
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
|
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
|
||||||
github.com/coreos/go-oidc/v3 v3.7.0 // indirect
|
github.com/coreos/go-oidc/v3 v3.12.0 // indirect
|
||||||
github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46 // indirect
|
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f // indirect
|
||||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/distribution/reference v0.5.0 // indirect
|
github.com/distribution/reference v0.6.0 // indirect
|
||||||
github.com/docker/docker v24.0.7+incompatible // indirect
|
github.com/docker/docker v27.5.1+incompatible // indirect
|
||||||
github.com/docker/docker-credential-helpers v0.8.0 // indirect
|
github.com/docker/docker-credential-helpers v0.8.2 // indirect
|
||||||
github.com/docker/go-connections v0.4.0 // indirect
|
github.com/docker/go-connections v0.5.0 // indirect
|
||||||
github.com/docker/go-units v0.5.0 // indirect
|
github.com/docker/go-units v0.5.0 // indirect
|
||||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
|
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
|
||||||
github.com/go-jose/go-jose/v3 v3.0.1 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/go-logr/logr v1.3.0 // indirect
|
github.com/go-jose/go-jose/v3 v3.0.4 // indirect
|
||||||
|
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
||||||
|
github.com/go-logr/logr v1.4.2 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-openapi/analysis v0.21.4 // indirect
|
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||||
github.com/go-openapi/errors v0.20.4 // indirect
|
github.com/go-openapi/errors v0.22.0 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||||
github.com/go-openapi/loads v0.21.2 // indirect
|
github.com/go-openapi/loads v0.22.0 // indirect
|
||||||
github.com/go-openapi/runtime v0.26.0 // indirect
|
github.com/go-openapi/runtime v0.28.0 // indirect
|
||||||
github.com/go-openapi/spec v0.20.9 // indirect
|
github.com/go-openapi/spec v0.21.0 // indirect
|
||||||
github.com/go-openapi/strfmt v0.21.7 // indirect
|
github.com/go-openapi/strfmt v0.23.0 // indirect
|
||||||
github.com/go-openapi/swag v0.22.4 // indirect
|
github.com/go-openapi/swag v0.23.0 // indirect
|
||||||
github.com/go-openapi/validate v0.22.1 // indirect
|
github.com/go-openapi/validate v0.24.0 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||||
github.com/golang/protobuf v1.5.3 // indirect
|
github.com/golang/protobuf v1.5.4 // indirect
|
||||||
github.com/google/go-containerregistry v0.16.1 // indirect
|
github.com/google/go-containerregistry v0.20.2 // indirect
|
||||||
github.com/google/go-intervals v0.0.2 // indirect
|
github.com/google/go-intervals v0.0.2 // indirect
|
||||||
github.com/google/uuid v1.3.1 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.1 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.2-0.20250313123807-1ee6e1a1957a // indirect
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
|
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/compress v1.17.3 // indirect
|
github.com/klauspost/compress v1.18.0 // indirect
|
||||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||||
github.com/letsencrypt/boulder v0.0.0-20230213213521-fdfea0d469b6 // indirect
|
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||||
github.com/mattn/go-shellwords v1.0.12 // indirect
|
github.com/mattn/go-sqlite3 v1.14.24 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.18 // indirect
|
|
||||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||||
github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
|
github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/moby/sys/mountinfo v0.7.1 // indirect
|
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||||
|
github.com/moby/sys/mountinfo v0.7.2 // indirect
|
||||||
|
github.com/moby/sys/user v0.4.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/oklog/ulid v1.3.1 // indirect
|
github.com/oklog/ulid v1.3.1 // indirect
|
||||||
github.com/opencontainers/runc v1.1.10 // indirect
|
github.com/opencontainers/runtime-spec v1.2.1 // indirect
|
||||||
github.com/opencontainers/runtime-spec v1.1.0 // indirect
|
github.com/opencontainers/selinux v1.12.0 // indirect
|
||||||
github.com/opencontainers/selinux v1.11.0 // indirect
|
|
||||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||||
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect
|
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
github.com/proglottis/gpgme v0.1.3 // indirect
|
github.com/proglottis/gpgme v0.1.4 // indirect
|
||||||
github.com/rivo/uniseg v0.4.4 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/russross/blackfriday v2.0.0+incompatible // indirect
|
github.com/russross/blackfriday v2.0.0+incompatible // indirect
|
||||||
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
|
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
|
||||||
|
github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect
|
||||||
github.com/segmentio/ksuid v1.0.4 // indirect
|
github.com/segmentio/ksuid v1.0.4 // indirect
|
||||||
github.com/sigstore/fulcio v1.4.3 // indirect
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||||
github.com/sigstore/rekor v1.2.2 // indirect
|
github.com/sigstore/fulcio v1.6.4 // indirect
|
||||||
github.com/sigstore/sigstore v1.7.5 // indirect
|
github.com/sigstore/rekor v1.3.8 // indirect
|
||||||
|
github.com/sigstore/sigstore v1.8.12 // indirect
|
||||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
|
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
|
||||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect
|
github.com/smallstep/pkcs7 v0.1.1 // indirect
|
||||||
github.com/sylabs/sif/v2 v2.15.0 // indirect
|
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect
|
||||||
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
|
github.com/sylabs/sif/v2 v2.20.2 // indirect
|
||||||
|
github.com/tchap/go-patricia/v2 v2.3.2 // indirect
|
||||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
|
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
|
||||||
github.com/ulikunitz/xz v0.5.11 // indirect
|
github.com/ulikunitz/xz v0.5.12 // indirect
|
||||||
github.com/vbatts/tar-split v0.11.5 // indirect
|
github.com/vbatts/tar-split v0.12.1 // indirect
|
||||||
github.com/vbauerster/mpb/v8 v8.6.2 // indirect
|
github.com/vbauerster/mpb/v8 v8.9.1 // indirect
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
go.mongodb.org/mongo-driver v1.14.0 // indirect
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
|
||||||
go.mongodb.org/mongo-driver v1.11.3 // indirect
|
|
||||||
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
|
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.19.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.19.0 // indirect
|
go.opentelemetry.io/otel v1.31.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.19.0 // indirect
|
go.opentelemetry.io/otel/metric v1.31.0 // indirect
|
||||||
golang.org/x/crypto v0.16.0 // indirect
|
go.opentelemetry.io/otel/trace v1.31.0 // indirect
|
||||||
golang.org/x/mod v0.14.0 // indirect
|
golang.org/x/crypto v0.36.0 // indirect
|
||||||
golang.org/x/net v0.19.0 // indirect
|
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 // indirect
|
||||||
golang.org/x/oauth2 v0.14.0 // indirect
|
golang.org/x/mod v0.22.0 // indirect
|
||||||
golang.org/x/sync v0.5.0 // indirect
|
golang.org/x/net v0.38.0 // indirect
|
||||||
golang.org/x/sys v0.16.0 // indirect
|
golang.org/x/oauth2 v0.25.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/sync v0.13.0 // indirect
|
||||||
golang.org/x/tools v0.16.0 // indirect
|
golang.org/x/sys v0.33.0 // indirect
|
||||||
google.golang.org/appengine v1.6.8 // indirect
|
golang.org/x/text v0.23.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||||
google.golang.org/grpc v1.58.3 // indirect
|
google.golang.org/grpc v1.69.4 // indirect
|
||||||
google.golang.org/protobuf v1.31.0 // indirect
|
google.golang.org/protobuf v1.36.2 // indirect
|
||||||
gopkg.in/go-jose/go-jose.v2 v2.6.1 // indirect
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
653
go.sum
653
go.sum
@ -1,159 +1,135 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||||
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg=
|
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg=
|
||||||
|
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
|
||||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
github.com/Microsoft/hcsshim v0.12.0-rc.1 h1:Hy+xzYujv7urO5wrgcG58SPMOXNLrj4WCJbySs2XX/A=
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
github.com/Microsoft/hcsshim v0.12.0-rc.1/go.mod h1:Y1a1S0QlYp1mBpyvGiuEdOfZqnao+0uX5AWHXQ5NhZU=
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y=
|
||||||
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
||||||
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
|
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
|
||||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
|
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
|
||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
|
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
|
||||||
github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
|
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
|
||||||
github.com/containerd/containerd v1.7.9 h1:KOhK01szQbM80YfW1H6RZKh85PHGqY/9OcEZ35Je8sc=
|
github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
|
||||||
github.com/containerd/containerd v1.7.9/go.mod h1:0/W44LWEYfSHoxBtsHIiNU/duEkgpMokemafHVCpq9Y=
|
github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
|
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
|
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||||
github.com/containers/common v0.57.2 h1:50Zp9VuXt2u5uNTKEc4aU2+PfWzFNAulD9JX43VihyI=
|
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||||
github.com/containers/common v0.57.2/go.mod h1:ZG9ab1bEssX98ZBclWFIyzx4+MyUN8dXj1oSEugp7N0=
|
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||||
github.com/containers/image/v5 v5.29.1 h1:9COTXQpl3FgrW/jw/roLAWlW4TN9ly7/bCAKY76wYl8=
|
github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
|
||||||
github.com/containers/image/v5 v5.29.1/go.mod h1:kQ7qcDsps424ZAz24thD+x7+dJw1vgur3A9tTDsj97E=
|
github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
|
||||||
|
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
|
||||||
|
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
|
||||||
|
github.com/containers/common v0.62.3 h1:aOGryqXfW6aKBbHbqOveH7zB+ihavUN03X/2pUSvWFI=
|
||||||
|
github.com/containers/common v0.62.3/go.mod h1:3R8kDox2prC9uj/a2hmXj/YjZz5sBEUNrcDiw51S0Lo=
|
||||||
|
github.com/containers/image/v5 v5.34.3 h1:/cMgfyA4Y7ILH7nzWP/kqpkE5Df35Ek4bp5ZPvJOVmI=
|
||||||
|
github.com/containers/image/v5 v5.34.3/go.mod h1:MG++slvQSZVq5ejAcLdu4APGsKGMb0YHHnAo7X28fdE=
|
||||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
||||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
|
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
|
||||||
github.com/containers/ocicrypt v1.1.9 h1:2Csfba4jse85Raxk5HIyEk8OwZNjRvfkhEGijOjIdEM=
|
github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM=
|
||||||
github.com/containers/ocicrypt v1.1.9/go.mod h1:dTKx1918d8TDkxXvarscpNVY+lyPakPNFN4jwA9GBys=
|
github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ=
|
||||||
github.com/containers/storage v1.51.0 h1:AowbcpiWXzAjHosKz7MKvPEqpyX+ryZA/ZurytRrFNA=
|
github.com/containers/storage v1.58.0 h1:Q7SyyCCjqgT3wYNgRNIL8o/wUS92heIj2/cc8Sewvcc=
|
||||||
github.com/containers/storage v1.51.0/go.mod h1:ybl8a3j1PPtpyaEi/5A6TOFs+5TrEyObeKJzVtkUlfc=
|
github.com/containers/storage v1.58.0/go.mod h1:w7Jl6oG+OpeLGLzlLyOZPkmUso40kjpzgrHUk5tyBlo=
|
||||||
github.com/coreos/go-oidc/v3 v3.7.0 h1:FTdj0uexT4diYIPlF4yoFVI5MRO1r5+SEcIpEw9vC0o=
|
github.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo=
|
||||||
github.com/coreos/go-oidc/v3 v3.7.0/go.mod h1:yQzSCqBnK3e6Fs5l+f5i0F8Kwf0zpH9bPEsbY00KanM=
|
github.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f h1:eHnXnuK47UlSTOQexbzxAZfekVz6i+LKRdj1CU5DPaM=
|
||||||
github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46 h1:2Dx4IHfC1yHWI12AxQDJM1QbRCDfk6M+blLzlZCXdrc=
|
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
|
||||||
github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
|
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/docker/cli v24.0.7+incompatible h1:wa/nIwYFW7BVTGa7SWPVyyXU9lgORqUb1xfI36MSkFg=
|
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||||
|
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||||
|
github.com/docker/cli v27.5.1+incompatible h1:JB9cieUT9YNiMITtIsguaN55PLOHhBSz3LKVc6cqWaY=
|
||||||
|
github.com/docker/cli v27.5.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM=
|
github.com/docker/docker v27.5.1+incompatible h1:4PYU5dnBYqRQi0294d1FBECqT9ECWeQAIfE8q4YnPY8=
|
||||||
github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v27.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8=
|
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
||||||
github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40=
|
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||||
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
|
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
|
||||||
|
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
|
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 h1:2tV76y6Q9BB+NEBasnqvs7e49aEBFI8ejC89PSnWH+4=
|
||||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
|
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
|
||||||
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw=
|
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||||
github.com/facebookgo/limitgroup v0.0.0-20150612190941-6abd8d71ec01 h1:IeaD1VDVBPlx3viJT9Md8if8IxxJnO+x0JCGb054heg=
|
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||||
github.com/facebookgo/muster v0.0.0-20150708232844-fd3d7953fd52 h1:a4DFiKFJiDRGFD1qIcqGLX/WlUMD9dyLSLDt+9QZgt8=
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA=
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
|
github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
|
||||||
|
github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||||
|
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||||
|
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY=
|
github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
|
||||||
github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc=
|
github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
|
||||||
github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo=
|
github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w=
|
||||||
github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
|
github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE=
|
||||||
github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
|
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||||
github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
|
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||||
github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M=
|
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||||
github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk=
|
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco=
|
||||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs=
|
||||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ=
|
||||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc=
|
||||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
|
||||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
|
||||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
|
||||||
github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g=
|
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||||
github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro=
|
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||||
github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw=
|
github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
|
||||||
github.com/go-openapi/runtime v0.26.0 h1:HYOFtG00FM1UvqrcxbEJg/SwvDRvYLQKGhw2zaQjTcc=
|
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
|
||||||
github.com/go-openapi/runtime v0.26.0/go.mod h1:QgRGeZwrUcSHdeh4Ka9Glvo0ug1LC5WyE+EV88plZrQ=
|
github.com/go-rod/rod v0.116.2 h1:A5t2Ky2A+5eD/ZJQr1EfsQSe5rms5Xof/qj296e+ZqA=
|
||||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
github.com/go-rod/rod v0.116.2/go.mod h1:H+CMO9SCNc2TJ2WfrG+pKhITz57uGNYU43qYHh438Mg=
|
||||||
github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
|
||||||
github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg=
|
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||||
github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
|
|
||||||
github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg=
|
|
||||||
github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k=
|
|
||||||
github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew=
|
|
||||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
|
||||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
|
||||||
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
|
||||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
|
||||||
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
|
||||||
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
|
||||||
github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU=
|
|
||||||
github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
|
|
||||||
github.com/go-rod/rod v0.114.4 h1:FpkNFukjCuZLwnoLs+S9aCL95o/EMec6M+41UmvQay8=
|
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
|
||||||
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
|
||||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
|
||||||
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
|
|
||||||
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
|
|
||||||
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
|
||||||
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
|
||||||
github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
|
|
||||||
github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
|
||||||
github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
|
||||||
github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
|
|
||||||
github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
|
|
||||||
github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
|
|
||||||
github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
|
|
||||||
github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
|
|
||||||
github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
|
|
||||||
github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
|
|
||||||
github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
|
|
||||||
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
|
|
||||||
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
|
||||||
github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
|
||||||
github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
|
|
||||||
github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
|
|
||||||
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
|
|
||||||
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
|
|
||||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
@ -164,275 +140,264 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
|
||||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
|
github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo=
|
||||||
|
github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8=
|
||||||
github.com/google/go-intervals v0.0.2 h1:FGrVEiUnTRKR8yE04qzXYaJMtnIYqobR5QbblK3ixcM=
|
github.com/google/go-intervals v0.0.2 h1:FGrVEiUnTRKR8yE04qzXYaJMtnIYqobR5QbblK3ixcM=
|
||||||
github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y=
|
github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd h1:r8yyd+DJDmsUhGrRBxH5Pj7KeFK5l+Y3FsgT8keqKtk=
|
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
|
||||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||||
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
|
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
github.com/hashicorp/go-multierror v1.1.2-0.20250313123807-1ee6e1a1957a h1:zTI4FFCOXw14aUC78fxMh4tS7jJI7Fm51sH4smjl+Fc=
|
||||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
github.com/hashicorp/go-multierror v1.1.2-0.20250313123807-1ee6e1a1957a/go.mod h1:RYOtqYU2MvOrqUMooJlQoFFuqR6sazGdm1ubZTL++r8=
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M=
|
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
|
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
||||||
github.com/honeycombio/beeline-go v1.10.0 h1:cUDe555oqvw8oD76BQJ8alk7FP0JZ/M/zXpNvOEDLDc=
|
|
||||||
github.com/honeycombio/libhoney-go v1.16.0 h1:kPpqoz6vbOzgp7jC6SR7SkNj7rua7rgxvznI6M3KdHc=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548 h1:dYTbLf4m0a5u0KLmPfB6mgxbcV7588bOCx79hxa5Sr4=
|
github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs=
|
||||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
github.com/jmhodges/clock v1.2.0/go.mod h1:qKjhA7x7u/lQpPB1XAqX1b1lCI/w3/fNuYpI/ZjLynI=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
|
|
||||||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||||
github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA=
|
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||||
github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
|
||||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
|
||||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/letsencrypt/boulder v0.0.0-20230213213521-fdfea0d469b6 h1:unJdfS94Y3k85TKy+mvKzjW5R9rIC+Lv4KGbE7uNu0I=
|
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2TSgRbAhD7yjZzTQmcN25sDRPEeinR51yQ=
|
||||||
github.com/letsencrypt/boulder v0.0.0-20230213213521-fdfea0d469b6/go.mod h1:PUgW5vI9ANEaV6qv9a6EKu8gAySgwf0xrzG9xIB/CK0=
|
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
|
||||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
|
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||||
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI=
|
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||||
github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
|
||||||
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
|
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
|
||||||
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||||
github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
|
github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
|
||||||
github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
|
github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
|
||||||
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
|
||||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
|
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||||
github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||||
|
github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk=
|
||||||
|
github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
|
||||||
|
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
|
||||||
|
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
|
||||||
|
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
|
||||||
|
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
|
||||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||||
|
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
|
||||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/onsi/ginkgo/v2 v2.13.1 h1:LNGfMbR2OVGBfXjvRZIZ2YCTQdGKtPLvuI1rMCCj3OU=
|
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
||||||
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
|
||||||
|
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||||
|
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
|
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||||
github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||||
github.com/opencontainers/image-tools v1.0.0-rc3 h1:ZR837lBIxq6mmwEqfYrbLMuf75eBSHhccVHy6lsBeM4=
|
github.com/opencontainers/image-tools v1.0.0-rc3 h1:ZR837lBIxq6mmwEqfYrbLMuf75eBSHhccVHy6lsBeM4=
|
||||||
github.com/opencontainers/image-tools v1.0.0-rc3/go.mod h1:A9btVpZLzttF4iFaKNychhPyrhfOjJ1OF5KrA8GcLj4=
|
github.com/opencontainers/image-tools v1.0.0-rc3/go.mod h1:A9btVpZLzttF4iFaKNychhPyrhfOjJ1OF5KrA8GcLj4=
|
||||||
github.com/opencontainers/runc v1.1.10 h1:EaL5WeO9lv9wmS6SASjszOeQdSctvpbu0DdBQBizE40=
|
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
|
||||||
github.com/opencontainers/runc v1.1.10/go.mod h1:+/R6+KmDlh+hOO8NkjmgkG9Qzvypzk0yXxAPYYR65+M=
|
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
|
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8=
|
||||||
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U=
|
||||||
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
|
||||||
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
|
||||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||||
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f h1:/UDgs8FGMqwnHagNDPGOlts35QkhAZ8by3DR7nMih7M=
|
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f h1:/UDgs8FGMqwnHagNDPGOlts35QkhAZ8by3DR7nMih7M=
|
||||||
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
|
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
|
||||||
github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU=
|
|
||||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/proglottis/gpgme v0.1.3 h1:Crxx0oz4LKB3QXc5Ea0J19K/3ICfy3ftr5exgUK1AU0=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/proglottis/gpgme v0.1.3/go.mod h1:fPbW/EZ0LvwQtH8Hy7eixhp1eF3G39dtx7GUN+0Gmy0=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
|
github.com/proglottis/gpgme v0.1.4 h1:3nE7YNA70o2aLjcg63tXMOhPD7bplfE5CBdV+hLAm2M=
|
||||||
|
github.com/proglottis/gpgme v0.1.4/go.mod h1:5LoXMgpE4bttgwwdv9bLs/vwqv3qV7F4glEEZ7mRKrM=
|
||||||
|
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||||
|
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI=
|
github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY=
|
||||||
|
github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI=
|
||||||
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
|
||||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
|
||||||
github.com/russross/blackfriday v2.0.0+incompatible h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk=
|
github.com/russross/blackfriday v2.0.0+incompatible h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk=
|
||||||
github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y=
|
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
||||||
github.com/secure-systems-lab/go-securesystemslib v0.7.0 h1:OwvJ5jQf9LnIAS83waAjPbcMsODrTQUpJ02eNLUoxBg=
|
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
||||||
github.com/secure-systems-lab/go-securesystemslib v0.7.0/go.mod h1:/2gYnlnHVQ6xeGtfIqFy7Do03K4cdCY0A/GlJLDKLHI=
|
github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY=
|
||||||
|
github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
|
||||||
|
github.com/secure-systems-lab/go-securesystemslib v0.9.0 h1:rf1HIbL64nUpEIZnjLZ3mcNEL9NBPB0iuVjyxvq3LZc=
|
||||||
|
github.com/secure-systems-lab/go-securesystemslib v0.9.0/go.mod h1:DVHKMcZ+V4/woA/peqr+L0joiRXbPpQ042GgJckkFgw=
|
||||||
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
|
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
|
||||||
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
|
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
|
||||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||||
|
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||||
github.com/sigstore/fulcio v1.4.3 h1:9JcUCZjjVhRF9fmhVuz6i1RyhCc/EGCD7MOl+iqCJLQ=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sigstore/fulcio v1.4.3/go.mod h1:BQPWo7cfxmJwgaHlphUHUpFkp5+YxeJes82oo39m5og=
|
github.com/sigstore/fulcio v1.6.4 h1:d86obfxUAG3Y6CYwOx1pdwCZwKmROB6w6927pKOVIRY=
|
||||||
github.com/sigstore/rekor v1.2.2 h1:5JK/zKZvcQpL/jBmHvmFj3YbpDMBQnJQ6ygp8xdF3bY=
|
github.com/sigstore/fulcio v1.6.4/go.mod h1:Y6bn3i3KGhXpaHsAtYP3Z4Np0+VzCo1fLv8Ci6mbPDs=
|
||||||
github.com/sigstore/rekor v1.2.2/go.mod h1:FGnWBGWzeNceJnp0x9eDFd41mI8aQqCjj+Zp0IEs0Qg=
|
github.com/sigstore/rekor v1.3.8 h1:B8kJI8mpSIXova4Jxa6vXdJyysRxFGsEsLKBDl0rRjA=
|
||||||
github.com/sigstore/sigstore v1.7.5 h1:ij55dBhLwjICmLTBJZm7SqoQLdsu/oowDanACcJNs48=
|
github.com/sigstore/rekor v1.3.8/go.mod h1:/dHFYKSuxEygfDRnEwyJ+ZD6qoVYNXQdi1mJrKvKWsI=
|
||||||
github.com/sigstore/sigstore v1.7.5/go.mod h1:9OCmYWhzuq/G4e1cy9m297tuMRJ1LExyrXY3ZC3Zt/s=
|
github.com/sigstore/sigstore v1.8.12 h1:S8xMVZbE2z9ZBuQUEG737pxdLjnbOIcFi5v9UFfkJFc=
|
||||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sigstore/sigstore v1.8.12/go.mod h1:+PYQAa8rfw0QdPpBcT+Gl3egKD9c+TUgAlF12H3Nmjo=
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
|
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
|
||||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU=
|
||||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
github.com/smallstep/pkcs7 v0.1.1/go.mod h1:dL6j5AIz9GHjVEBTXtW+QliALcgM19RtXaTeyxI+AfA=
|
||||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 h1:lIOOHPEbXzO3vnmx2gok1Tfs31Q8GQqKLc8vVqyQq/I=
|
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw=
|
||||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/sylabs/sif/v2 v2.15.0 h1:Nv0tzksFnoQiQ2eUwpAis9nVqEu4c3RcNSxX8P3Cecw=
|
github.com/sylabs/sif/v2 v2.20.2 h1:HGEPzauCHhIosw5o6xmT3jczuKEuaFzSfdjAsH33vYw=
|
||||||
github.com/sylabs/sif/v2 v2.15.0/go.mod h1:X1H7eaPz6BAxA84POMESXoXfTqgAnLQkujyF/CQFWTc=
|
github.com/sylabs/sif/v2 v2.20.2/go.mod h1:WyYryGRaR4Wp21SAymm5pK0p45qzZCSRiZMFvUZiuhc=
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
github.com/tchap/go-patricia/v2 v2.3.2 h1:xTHFutuitO2zqKAQ5rCROYgUb7Or/+IC3fts9/Yc7nM=
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/tchap/go-patricia/v2 v2.3.2/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
||||||
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
|
|
||||||
github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
|
||||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
|
||||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
|
||||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
||||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
|
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
|
||||||
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||||
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
|
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
||||||
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||||
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
|
github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo=
|
||||||
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
|
github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
|
||||||
github.com/vbauerster/mpb/v8 v8.6.2 h1:9EhnJGQRtvgDVCychJgR96EDCOqgg2NsMuk5JUcX4DA=
|
github.com/vbauerster/mpb/v8 v8.9.1 h1:LH5R3lXPfE2e3lIGxN7WNWv3Hl5nWO6LRi2B0L0ERHw=
|
||||||
github.com/vbauerster/mpb/v8 v8.6.2/go.mod h1:oVJ7T+dib99kZ/VBjoBaC8aPXiSAihnzuKmotuihyFo=
|
github.com/vbauerster/mpb/v8 v8.9.1/go.mod h1:4XMvznPh8nfe2NpnDo1QTPvW9MVkUhbG90mPWvmOzcQ=
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
|
||||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
|
||||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
|
||||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
|
||||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
|
||||||
github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ=
|
github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ=
|
||||||
|
github.com/ysmood/fetchup v0.2.3/go.mod h1:xhibcRKziSvol0H1/pj33dnKrYyI2ebIvz5cOOkYGns=
|
||||||
github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
|
github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
|
||||||
github.com/ysmood/got v0.34.1 h1:IrV2uWLs45VXNvZqhJ6g2nIhY+pgIG1CUoOcqfXFl1s=
|
github.com/ysmood/goob v0.4.0/go.mod h1:u6yx7ZhS4Exf2MwciFr6nIM8knHQIE22lFpWHnfql18=
|
||||||
|
github.com/ysmood/got v0.40.0 h1:ZQk1B55zIvS7zflRrkGfPDrPG3d7+JOza1ZkNxcc74Q=
|
||||||
|
github.com/ysmood/got v0.40.0/go.mod h1:W7DdpuX6skL3NszLmAsC5hT7JAhuLZhByVzHTq874Qg=
|
||||||
github.com/ysmood/gson v0.7.3 h1:QFkWbTH8MxyUTKPkVWAENJhxqdBa4lYTQWqZCiLG6kE=
|
github.com/ysmood/gson v0.7.3 h1:QFkWbTH8MxyUTKPkVWAENJhxqdBa4lYTQWqZCiLG6kE=
|
||||||
github.com/ysmood/leakless v0.8.0 h1:BzLrVoiwxikpgEQR0Lk8NyBN5Cit2b1z+u0mgL4ZJak=
|
github.com/ysmood/gson v0.7.3/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg=
|
||||||
|
github.com/ysmood/leakless v0.9.0 h1:qxCG5VirSBvmi3uynXFkcnLMzkphdh3xx5FtrORwDCU=
|
||||||
|
github.com/ysmood/leakless v0.9.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
|
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
|
||||||
go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
|
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||||
go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
|
|
||||||
go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y=
|
|
||||||
go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
|
||||||
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak=
|
|
||||||
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
|
||||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||||
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
|
||||||
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
|
||||||
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
|
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
|
||||||
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
|
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
|
||||||
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc=
|
||||||
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s=
|
||||||
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU=
|
||||||
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
|
||||||
|
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||||
|
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
|
||||||
|
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
|
||||||
|
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
|
||||||
|
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
|
||||||
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
|
||||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||||
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
|
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
|
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||||
|
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=
|
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 h1:9kj3STMvgqy3YA4VQXBrN7925ICMxD5wzMRcgA30588=
|
||||||
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
|
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
|
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
|
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||||
|
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -443,91 +408,106 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
|
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||||
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
|
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||||
|
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=
|
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
|
||||||
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
|
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
|
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||||
|
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||||
|
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||||
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
|
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||||
|
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
||||||
|
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
|
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||||
|
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||||
|
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
||||||
|
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
|
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
|
||||||
|
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
|
||||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM=
|
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA=
|
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
|
google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A=
|
||||||
google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
@ -537,30 +517,15 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
|
||||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
|
||||||
gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
|
||||||
gopkg.in/go-jose/go-jose.v2 v2.6.1 h1:qEzJlIDmG9q5VO0M/o8tGS65QMHMS1w01TQJB1VPJ4U=
|
|
||||||
gopkg.in/go-jose/go-jose.v2 v2.6.1/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
|
||||||
gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY=
|
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
cc -E - > /dev/null 2> /dev/null << EOF
|
${CPP:-${CC:-cc} -E} ${CPPFLAGS} - > /dev/null 2> /dev/null << EOF
|
||||||
#include <btrfs/ioctl.h>
|
#include <btrfs/ioctl.h>
|
||||||
EOF
|
EOF
|
||||||
if test $? -ne 0 ; then
|
if test $? -ne 0 ; then
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
cc -E - > /dev/null 2> /dev/null << EOF
|
|
||||||
#include <btrfs/version.h>
|
|
||||||
EOF
|
|
||||||
if test $? -ne 0 ; then
|
|
||||||
echo btrfs_noversion
|
|
||||||
fi
|
|
@ -29,6 +29,6 @@ $CONTAINER_RUNTIME run --rm \
|
|||||||
--entrypoint=/usr/share/automation/bin/cirrus-ci_env.py \
|
--entrypoint=/usr/share/automation/bin/cirrus-ci_env.py \
|
||||||
quay.io/libpod/get_ci_vm:latest \
|
quay.io/libpod/get_ci_vm:latest \
|
||||||
--envs="Skopeo Test" /src/.cirrus.yml | \
|
--envs="Skopeo Test" /src/.cirrus.yml | \
|
||||||
egrep -m1 '^SKOPEO_CIDEV_CONTAINER_FQIN' | \
|
grep -E -m1 '^SKOPEO_CIDEV_CONTAINER_FQIN' | \
|
||||||
awk -F "=" -e '{print $2}' | \
|
awk -F "=" -e '{print $2}' | \
|
||||||
tr -d \'\"
|
tr -d \'\"
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
tmpdir="$PWD/tmp.$RANDOM"
|
|
||||||
mkdir -p "$tmpdir"
|
|
||||||
trap 'rm -fr "$tmpdir"' EXIT
|
|
||||||
cc -c -o "$tmpdir"/libdm_tag.o -x c - > /dev/null 2> /dev/null << EOF
|
|
||||||
#include <libdevmapper.h>
|
|
||||||
int main() {
|
|
||||||
struct dm_task *task;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
if test $? -ne 0 ; then
|
|
||||||
echo libdm_no_deferred_remove
|
|
||||||
fi
|
|
@ -5,7 +5,8 @@ fi
|
|||||||
tmpdir="$PWD/tmp.$RANDOM"
|
tmpdir="$PWD/tmp.$RANDOM"
|
||||||
mkdir -p "$tmpdir"
|
mkdir -p "$tmpdir"
|
||||||
trap 'rm -fr "$tmpdir"' EXIT
|
trap 'rm -fr "$tmpdir"' EXIT
|
||||||
cc -o "$tmpdir"/libsubid_tag -x c - -l subid > /dev/null 2> /dev/null << EOF
|
${CC:-cc} ${CPPFLAGS} ${CFLAGS} -o "$tmpdir"/libsubid_tag -x c - -l subid \
|
||||||
|
> /dev/null 2> /dev/null << EOF
|
||||||
#include <shadow/subid.h>
|
#include <shadow/subid.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -29,7 +29,7 @@ rc=0
|
|||||||
# for a given skopeo-foo.1.md, the NAME should be 'skopeo-foo'
|
# for a given skopeo-foo.1.md, the NAME should be 'skopeo-foo'
|
||||||
for md in *.1.md;do
|
for md in *.1.md;do
|
||||||
# Read the first line after '## NAME'
|
# Read the first line after '## NAME'
|
||||||
name=$(egrep -A1 '^## NAME' $md|tail -1|awk '{print $1}' | tr -d \\\\)
|
name=$(grep -E -A1 '^## NAME' $md|tail -1|awk '{print $1}' | tr -d \\\\)
|
||||||
|
|
||||||
expect=$(basename $md .1.md)
|
expect=$(basename $md .1.md)
|
||||||
if [ "$name" != "$expect" ]; then
|
if [ "$name" != "$expect" ]; then
|
||||||
@ -45,7 +45,7 @@ done
|
|||||||
# Make sure the descriptive text in skopeo-foo.1.md matches the one
|
# Make sure the descriptive text in skopeo-foo.1.md matches the one
|
||||||
# in the table in skopeo.1.md.
|
# in the table in skopeo.1.md.
|
||||||
for md in $(ls -1 *-*.1.md);do
|
for md in $(ls -1 *-*.1.md);do
|
||||||
desc=$(egrep -A1 '^## NAME' $md|tail -1|sed -E -e 's/^skopeo[^[:space:]]+ - //')
|
desc=$(grep -E -A1 '^## NAME' $md|tail -1|sed -E -e 's/^skopeo[^[:space:]]+ - //')
|
||||||
|
|
||||||
# Find the descriptive text in the main skopeo man page.
|
# Find the descriptive text in the main skopeo man page.
|
||||||
parent=skopeo.1.md
|
parent=skopeo.1.md
|
||||||
@ -112,7 +112,7 @@ function compare_usage() {
|
|||||||
#
|
#
|
||||||
# Make sure the SYNOPSIS line in skopeo-foo.1.md reads '**skopeo foo** ...'
|
# Make sure the SYNOPSIS line in skopeo-foo.1.md reads '**skopeo foo** ...'
|
||||||
for md in *.1.md;do
|
for md in *.1.md;do
|
||||||
synopsis=$(egrep -A1 '^#* SYNOPSIS' $md|tail -1)
|
synopsis=$(grep -E -A1 '^#* SYNOPSIS' $md|tail -1)
|
||||||
|
|
||||||
# Command name must be bracketed by double asterisks; options and
|
# Command name must be bracketed by double asterisks; options and
|
||||||
# arguments are bracketed by single ones.
|
# arguments are bracketed by single ones.
|
||||||
|
@ -8,7 +8,7 @@ set -e
|
|||||||
#
|
#
|
||||||
# Paradoxically (FIXME: clean this up), SKOPEO_CONTAINER_TESTS is set
|
# Paradoxically (FIXME: clean this up), SKOPEO_CONTAINER_TESTS is set
|
||||||
# both inside a container and without a container (in a CI VM); it actually means
|
# both inside a container and without a container (in a CI VM); it actually means
|
||||||
# "it is safe to desctructively modify the system for tests".
|
# "it is safe to destructively modify the system for tests".
|
||||||
#
|
#
|
||||||
# On a CI VM, we can just use Podman as it is already configured; the changes below,
|
# On a CI VM, we can just use Podman as it is already configured; the changes below,
|
||||||
# to use VFS, are necessary only inside a container, because overlay-inside-overlay
|
# to use VFS, are necessary only inside a container, because overlay-inside-overlay
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
errors=$($GOBIN/golangci-lint run --build-tags "${BUILDTAGS}" 2>&1)
|
|
||||||
|
|
||||||
if [ -z "$errors" ]; then
|
|
||||||
echo 'Congratulations! All Go source files have been linted.'
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo "Errors from golangci-lint:"
|
|
||||||
echo "$errors"
|
|
||||||
echo
|
|
||||||
echo 'Please fix the above errors. You can test via "golangci-lint" and commit the result.'
|
|
||||||
echo
|
|
||||||
} >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
22
install.md
22
install.md
@ -122,7 +122,6 @@ Skopeo has not yet been packaged for Windows. There is an [open feature
|
|||||||
request](https://github.com/containers/skopeo/issues/715) and contributions are
|
request](https://github.com/containers/skopeo/issues/715) and contributions are
|
||||||
always welcome.
|
always welcome.
|
||||||
|
|
||||||
|
|
||||||
## Container Images
|
## Container Images
|
||||||
|
|
||||||
Skopeo container images are available at `quay.io/skopeo/stable:latest`.
|
Skopeo container images are available at `quay.io/skopeo/stable:latest`.
|
||||||
@ -132,14 +131,15 @@ For example,
|
|||||||
podman run docker://quay.io/skopeo/stable:latest copy --help
|
podman run docker://quay.io/skopeo/stable:latest copy --help
|
||||||
```
|
```
|
||||||
|
|
||||||
[Read more](./contrib/skopeoimage/README.md).
|
The skopeo container image build context and automation are
|
||||||
|
located at [https://github.com/containers/image_build/tree/main/skopeo](https://github.com/containers/image_build/tree/main/skopeo)
|
||||||
|
|
||||||
|
|
||||||
## Building from Source
|
## Building from Source
|
||||||
|
|
||||||
Otherwise, read on for building and installing it from source:
|
Otherwise, read on for building and installing it from source:
|
||||||
|
|
||||||
To build the `skopeo` binary you need at least Go 1.19.
|
To build the `skopeo` binary you need at least Go 1.23.
|
||||||
|
|
||||||
There are two ways to build skopeo: in a container, or locally without a
|
There are two ways to build skopeo: in a container, or locally without a
|
||||||
container. Choose the one which better matches your needs and environment.
|
container. Choose the one which better matches your needs and environment.
|
||||||
@ -157,12 +157,12 @@ Install the necessary dependencies:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Fedora:
|
# Fedora:
|
||||||
sudo dnf install gpgme-devel libassuan-devel btrfs-progs-devel device-mapper-devel
|
sudo dnf install gpgme-devel libassuan-devel btrfs-progs-devel
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Ubuntu (`libbtrfs-dev` requires Ubuntu 18.10 and above):
|
# Ubuntu (`libbtrfs-dev` requires Ubuntu 18.10 and above):
|
||||||
sudo apt install libgpgme-dev libassuan-dev libbtrfs-dev libdevmapper-dev pkg-config
|
sudo apt install libgpgme-dev libassuan-dev libbtrfs-dev pkg-config
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -172,12 +172,12 @@ brew install gpgme
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# openSUSE:
|
# openSUSE:
|
||||||
sudo zypper install libgpgme-devel device-mapper-devel libbtrfs-devel glib2-devel
|
sudo zypper install libgpgme-devel libbtrfs-devel glib2-devel
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Arch Linux:
|
# Arch Linux:
|
||||||
sudo pacman -S base-devel gpgme device-mapper btrfs-progs
|
sudo pacman -S base-devel gpgme btrfs-progs
|
||||||
```
|
```
|
||||||
|
|
||||||
Make sure to clone this repository in your `GOPATH` - otherwise compilation fails.
|
Make sure to clone this repository in your `GOPATH` - otherwise compilation fails.
|
||||||
@ -195,6 +195,12 @@ document generation can be skipped by passing `DISABLE_DOCS=1`:
|
|||||||
DISABLE_DOCS=1 make
|
DISABLE_DOCS=1 make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Additional prerequisites
|
||||||
|
|
||||||
|
In order to dynamically link against system libraries and avoid compilation errors the ```CGO_ENABLED='1'``` flag must be enabled. You can easily check by ```go env | grep CGO_ENABLED```.
|
||||||
|
|
||||||
|
An alternative would be to set the `BUILDTAGS=containers_image_openpgp` (this removes the dependency on `libgpgme` and its companion libraries).
|
||||||
|
|
||||||
### Cross-compilation
|
### Cross-compilation
|
||||||
|
|
||||||
For cross-building skopeo, use the command `make bin/skopeo.OS.ARCH`, where OS represents
|
For cross-building skopeo, use the command `make bin/skopeo.OS.ARCH`, where OS represents
|
||||||
@ -261,7 +267,7 @@ sudo make install
|
|||||||
### Building a static binary
|
### Building a static binary
|
||||||
|
|
||||||
There have been efforts in the past to produce and maintain static builds, but the maintainers prefer to run Skopeo using distro packages or within containers. This is because static builds of Skopeo tend to be unreliable and functionally restricted. Specifically:
|
There have been efforts in the past to produce and maintain static builds, but the maintainers prefer to run Skopeo using distro packages or within containers. This is because static builds of Skopeo tend to be unreliable and functionally restricted. Specifically:
|
||||||
- Some features of Skopeo depend on non-Go libraries like `libgpgme` and `libdevmapper`.
|
- Some features of Skopeo depend on non-Go libraries like `libgpgme`.
|
||||||
- Generating static Go binaries uses native Go libraries, which don't support e.g. `.local` or LDAP-based name resolution.
|
- Generating static Go binaries uses native Go libraries, which don't support e.g. `.local` or LDAP-based name resolution.
|
||||||
|
|
||||||
That being said, if you would like to build Skopeo statically, you might be able to do it by combining all the following steps.
|
That being said, if you would like to build Skopeo statically, you might be able to do it by combining all the following steps.
|
||||||
|
@ -30,7 +30,8 @@ const (
|
|||||||
v2DockerRegistryURL = "localhost:5555" // Update also policy.json
|
v2DockerRegistryURL = "localhost:5555" // Update also policy.json
|
||||||
v2s1DockerRegistryURL = "localhost:5556"
|
v2s1DockerRegistryURL = "localhost:5556"
|
||||||
knownWindowsOnlyImage = "docker://mcr.microsoft.com/windows/nanoserver:1909"
|
knownWindowsOnlyImage = "docker://mcr.microsoft.com/windows/nanoserver:1909"
|
||||||
knownListImage = "docker://registry.fedoraproject.org/fedora-minimal" // could have either ":latest" or "@sha256:..." appended
|
knownListImageRepo = "docker://registry.fedoraproject.org/fedora-minimal"
|
||||||
|
knownListImage = knownListImageRepo + ":38"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCopy(t *testing.T) {
|
func TestCopy(t *testing.T) {
|
||||||
@ -187,7 +188,7 @@ func (s *copySuite) TestCopyWithManifestListStorage() {
|
|||||||
assertSkopeoSucceeds(t, "", "copy", knownListImage, "containers-storage:"+storage+"test")
|
assertSkopeoSucceeds(t, "", "copy", knownListImage, "containers-storage:"+storage+"test")
|
||||||
assertSkopeoSucceeds(t, "", "copy", knownListImage, "dir:"+dir1)
|
assertSkopeoSucceeds(t, "", "copy", knownListImage, "dir:"+dir1)
|
||||||
assertSkopeoSucceeds(t, "", "copy", "containers-storage:"+storage+"test", "dir:"+dir2)
|
assertSkopeoSucceeds(t, "", "copy", "containers-storage:"+storage+"test", "dir:"+dir2)
|
||||||
runDecompressDirs(t, dir1, dir2)
|
decompressDirs(t, dir1, dir2)
|
||||||
assertDirImagesAreEqual(t, dir1, dir2)
|
assertDirImagesAreEqual(t, dir1, dir2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +202,7 @@ func (s *copySuite) TestCopyWithManifestListStorageMultiple() {
|
|||||||
assertSkopeoSucceeds(t, "", "--override-arch", "arm64", "copy", knownListImage, "containers-storage:"+storage+"test")
|
assertSkopeoSucceeds(t, "", "--override-arch", "arm64", "copy", knownListImage, "containers-storage:"+storage+"test")
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch", "arm64", "copy", knownListImage, "dir:"+dir1)
|
assertSkopeoSucceeds(t, "", "--override-arch", "arm64", "copy", knownListImage, "dir:"+dir1)
|
||||||
assertSkopeoSucceeds(t, "", "copy", "containers-storage:"+storage+"test", "dir:"+dir2)
|
assertSkopeoSucceeds(t, "", "copy", "containers-storage:"+storage+"test", "dir:"+dir2)
|
||||||
runDecompressDirs(t, dir1, dir2)
|
decompressDirs(t, dir1, dir2)
|
||||||
assertDirImagesAreEqual(t, dir1, dir2)
|
assertDirImagesAreEqual(t, dir1, dir2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,8 +216,8 @@ func (s *copySuite) TestCopyWithManifestListDigest() {
|
|||||||
manifestDigest, err := manifest.Digest([]byte(m))
|
manifestDigest, err := manifest.Digest([]byte(m))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
digest := manifestDigest.String()
|
digest := manifestDigest.String()
|
||||||
assertSkopeoSucceeds(t, "", "copy", knownListImage+"@"+digest, "dir:"+dir1)
|
assertSkopeoSucceeds(t, "", "copy", knownListImageRepo+"@"+digest, "dir:"+dir1)
|
||||||
assertSkopeoSucceeds(t, "", "copy", "--multi-arch=all", knownListImage+"@"+digest, "dir:"+dir2)
|
assertSkopeoSucceeds(t, "", "copy", "--multi-arch=all", knownListImageRepo+"@"+digest, "dir:"+dir2)
|
||||||
assertSkopeoSucceeds(t, "", "copy", "dir:"+dir1, "oci:"+oci1)
|
assertSkopeoSucceeds(t, "", "copy", "dir:"+dir1, "oci:"+oci1)
|
||||||
assertSkopeoSucceeds(t, "", "copy", "dir:"+dir2, "oci:"+oci2)
|
assertSkopeoSucceeds(t, "", "copy", "dir:"+dir2, "oci:"+oci2)
|
||||||
out := combinedOutputOfCommand(t, "diff", "-urN", oci1, oci2)
|
out := combinedOutputOfCommand(t, "diff", "-urN", oci1, oci2)
|
||||||
@ -245,10 +246,10 @@ func (s *copySuite) TestCopyWithManifestListStorageDigest() {
|
|||||||
manifestDigest, err := manifest.Digest([]byte(m))
|
manifestDigest, err := manifest.Digest([]byte(m))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
digest := manifestDigest.String()
|
digest := manifestDigest.String()
|
||||||
assertSkopeoSucceeds(t, "", "copy", knownListImage+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoSucceeds(t, "", "copy", knownListImageRepo+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
||||||
assertSkopeoSucceeds(t, "", "copy", "containers-storage:"+storage+"test@"+digest, "dir:"+dir1)
|
assertSkopeoSucceeds(t, "", "copy", "containers-storage:"+storage+"test@"+digest, "dir:"+dir1)
|
||||||
assertSkopeoSucceeds(t, "", "copy", knownListImage+"@"+digest, "dir:"+dir2)
|
assertSkopeoSucceeds(t, "", "copy", knownListImageRepo+"@"+digest, "dir:"+dir2)
|
||||||
runDecompressDirs(t, dir1, dir2)
|
decompressDirs(t, dir1, dir2)
|
||||||
assertDirImagesAreEqual(t, dir1, dir2)
|
assertDirImagesAreEqual(t, dir1, dir2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,10 +263,10 @@ func (s *copySuite) TestCopyWithManifestListStorageDigestMultipleArches() {
|
|||||||
manifestDigest, err := manifest.Digest([]byte(m))
|
manifestDigest, err := manifest.Digest([]byte(m))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
digest := manifestDigest.String()
|
digest := manifestDigest.String()
|
||||||
assertSkopeoSucceeds(t, "", "copy", knownListImage+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoSucceeds(t, "", "copy", knownListImageRepo+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
||||||
assertSkopeoSucceeds(t, "", "copy", "containers-storage:"+storage+"test@"+digest, "dir:"+dir1)
|
assertSkopeoSucceeds(t, "", "copy", "containers-storage:"+storage+"test@"+digest, "dir:"+dir1)
|
||||||
assertSkopeoSucceeds(t, "", "copy", knownListImage+"@"+digest, "dir:"+dir2)
|
assertSkopeoSucceeds(t, "", "copy", knownListImageRepo+"@"+digest, "dir:"+dir2)
|
||||||
runDecompressDirs(t, dir1, dir2)
|
decompressDirs(t, dir1, dir2)
|
||||||
assertDirImagesAreEqual(t, dir1, dir2)
|
assertDirImagesAreEqual(t, dir1, dir2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,8 +280,8 @@ func (s *copySuite) TestCopyWithManifestListStorageDigestMultipleArchesBothUseLi
|
|||||||
digest := manifestDigest.String()
|
digest := manifestDigest.String()
|
||||||
_, err = manifest.ListFromBlob([]byte(m), manifest.GuessMIMEType([]byte(m)))
|
_, err = manifest.ListFromBlob([]byte(m), manifest.GuessMIMEType([]byte(m)))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImage+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImageRepo+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=arm64", "copy", knownListImage+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoSucceeds(t, "", "--override-arch=arm64", "copy", knownListImageRepo+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
||||||
assertSkopeoFails(t, `.*reading manifest for image instance.*does not exist.*`, "--override-arch=amd64", "inspect", "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoFails(t, `.*reading manifest for image instance.*does not exist.*`, "--override-arch=amd64", "inspect", "containers-storage:"+storage+"test@"+digest)
|
||||||
assertSkopeoFails(t, `.*reading manifest for image instance.*does not exist.*`, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoFails(t, `.*reading manifest for image instance.*does not exist.*`, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+digest)
|
||||||
i2 := combinedOutputOfCommand(t, skopeoBinary, "--override-arch=arm64", "inspect", "--config", "containers-storage:"+storage+"test@"+digest)
|
i2 := combinedOutputOfCommand(t, skopeoBinary, "--override-arch=arm64", "inspect", "--config", "containers-storage:"+storage+"test@"+digest)
|
||||||
@ -304,8 +305,8 @@ func (s *copySuite) TestCopyWithManifestListStorageDigestMultipleArchesFirstUses
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
arm64Instance, err := list.ChooseInstance(&types.SystemContext{ArchitectureChoice: "arm64"})
|
arm64Instance, err := list.ChooseInstance(&types.SystemContext{ArchitectureChoice: "arm64"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImage+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImageRepo+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=arm64", "copy", knownListImage+"@"+arm64Instance.String(), "containers-storage:"+storage+"test@"+arm64Instance.String())
|
assertSkopeoSucceeds(t, "", "--override-arch=arm64", "copy", knownListImageRepo+"@"+arm64Instance.String(), "containers-storage:"+storage+"test@"+arm64Instance.String())
|
||||||
i1 := combinedOutputOfCommand(t, skopeoBinary, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+digest)
|
i1 := combinedOutputOfCommand(t, skopeoBinary, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+digest)
|
||||||
var image1 imgspecv1.Image
|
var image1 imgspecv1.Image
|
||||||
err = json.Unmarshal([]byte(i1), &image1)
|
err = json.Unmarshal([]byte(i1), &image1)
|
||||||
@ -339,8 +340,8 @@ func (s *copySuite) TestCopyWithManifestListStorageDigestMultipleArchesSecondUse
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
arm64Instance, err := list.ChooseInstance(&types.SystemContext{ArchitectureChoice: "arm64"})
|
arm64Instance, err := list.ChooseInstance(&types.SystemContext{ArchitectureChoice: "arm64"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImage+"@"+amd64Instance.String(), "containers-storage:"+storage+"test@"+amd64Instance.String())
|
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImageRepo+"@"+amd64Instance.String(), "containers-storage:"+storage+"test@"+amd64Instance.String())
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=arm64", "copy", knownListImage+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoSucceeds(t, "", "--override-arch=arm64", "copy", knownListImageRepo+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
||||||
i1 := combinedOutputOfCommand(t, skopeoBinary, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+amd64Instance.String())
|
i1 := combinedOutputOfCommand(t, skopeoBinary, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+amd64Instance.String())
|
||||||
var image1 imgspecv1.Image
|
var image1 imgspecv1.Image
|
||||||
err = json.Unmarshal([]byte(i1), &image1)
|
err = json.Unmarshal([]byte(i1), &image1)
|
||||||
@ -374,9 +375,9 @@ func (s *copySuite) TestCopyWithManifestListStorageDigestMultipleArchesThirdUses
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
arm64Instance, err := list.ChooseInstance(&types.SystemContext{ArchitectureChoice: "arm64"})
|
arm64Instance, err := list.ChooseInstance(&types.SystemContext{ArchitectureChoice: "arm64"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImage+"@"+amd64Instance.String(), "containers-storage:"+storage+"test@"+amd64Instance.String())
|
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImageRepo+"@"+amd64Instance.String(), "containers-storage:"+storage+"test@"+amd64Instance.String())
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImage+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImageRepo+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=arm64", "copy", knownListImage+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoSucceeds(t, "", "--override-arch=arm64", "copy", knownListImageRepo+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
||||||
assertSkopeoFails(t, `.*reading manifest for image instance.*does not exist.*`, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoFails(t, `.*reading manifest for image instance.*does not exist.*`, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+digest)
|
||||||
i1 := combinedOutputOfCommand(t, skopeoBinary, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+amd64Instance.String())
|
i1 := combinedOutputOfCommand(t, skopeoBinary, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+amd64Instance.String())
|
||||||
var image1 imgspecv1.Image
|
var image1 imgspecv1.Image
|
||||||
@ -410,7 +411,7 @@ func (s *copySuite) TestCopyWithManifestListStorageDigestMultipleArchesTagAndDig
|
|||||||
arm64Instance, err := list.ChooseInstance(&types.SystemContext{ArchitectureChoice: "arm64"})
|
arm64Instance, err := list.ChooseInstance(&types.SystemContext{ArchitectureChoice: "arm64"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImage, "containers-storage:"+storage+"test:latest")
|
assertSkopeoSucceeds(t, "", "--override-arch=amd64", "copy", knownListImage, "containers-storage:"+storage+"test:latest")
|
||||||
assertSkopeoSucceeds(t, "", "--override-arch=arm64", "copy", knownListImage+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoSucceeds(t, "", "--override-arch=arm64", "copy", knownListImageRepo+"@"+digest, "containers-storage:"+storage+"test@"+digest)
|
||||||
assertSkopeoFails(t, `.*reading manifest for image instance.*does not exist.*`, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+digest)
|
assertSkopeoFails(t, `.*reading manifest for image instance.*does not exist.*`, "--override-arch=amd64", "inspect", "--config", "containers-storage:"+storage+"test@"+digest)
|
||||||
i1 := combinedOutputOfCommand(t, skopeoBinary, "--override-arch=arm64", "inspect", "--config", "containers-storage:"+storage+"test:latest")
|
i1 := combinedOutputOfCommand(t, skopeoBinary, "--override-arch=arm64", "inspect", "--config", "containers-storage:"+storage+"test:latest")
|
||||||
var image1 imgspecv1.Image
|
var image1 imgspecv1.Image
|
||||||
@ -478,7 +479,7 @@ func (s *copySuite) TestCopySimple() {
|
|||||||
|
|
||||||
// FIXME: It would be nice to use one of the local Docker registries instead of needing an Internet connection.
|
// FIXME: It would be nice to use one of the local Docker registries instead of needing an Internet connection.
|
||||||
// "pull": docker: → dir:
|
// "pull": docker: → dir:
|
||||||
assertSkopeoSucceeds(t, "", "copy", "docker://k8s.gcr.io/pause", "dir:"+dir1)
|
assertSkopeoSucceeds(t, "", "copy", "docker://registry.k8s.io/pause", "dir:"+dir1)
|
||||||
// "push": dir: → docker(v2s2):
|
// "push": dir: → docker(v2s2):
|
||||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "dir:"+dir1, ourRegistry+"pause:unsigned")
|
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "dir:"+dir1, ourRegistry+"pause:unsigned")
|
||||||
// The result of pushing and pulling is an unmodified image.
|
// The result of pushing and pulling is an unmodified image.
|
||||||
@ -492,14 +493,14 @@ func (s *copySuite) TestCopySimple() {
|
|||||||
ociDest := "pause-latest-image"
|
ociDest := "pause-latest-image"
|
||||||
ociImgName := "pause"
|
ociImgName := "pause"
|
||||||
defer os.RemoveAll(ociDest)
|
defer os.RemoveAll(ociDest)
|
||||||
assertSkopeoSucceeds(t, "", "copy", "docker://k8s.gcr.io/pause:latest", "oci:"+ociDest+":"+ociImgName)
|
assertSkopeoSucceeds(t, "", "copy", "docker://registry.k8s.io/pause:latest", "oci:"+ociDest+":"+ociImgName)
|
||||||
_, err := os.Stat(ociDest)
|
_, err := os.Stat(ociDest)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// docker v2s2 -> OCI image layout without image name
|
// docker v2s2 -> OCI image layout without image name
|
||||||
ociDest = "pause-latest-noimage"
|
ociDest = "pause-latest-noimage"
|
||||||
defer os.RemoveAll(ociDest)
|
defer os.RemoveAll(ociDest)
|
||||||
assertSkopeoSucceeds(t, "", "copy", "docker://k8s.gcr.io/pause:latest", "oci:"+ociDest)
|
assertSkopeoSucceeds(t, "", "copy", "docker://registry.k8s.io/pause:latest", "oci:"+ociDest)
|
||||||
_, err = os.Stat(ociDest)
|
_, err = os.Stat(ociDest)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -764,7 +765,7 @@ func (s *copySuite) TestCopySignatures() {
|
|||||||
|
|
||||||
// Verify that signed identity is verified.
|
// Verify that signed identity is verified.
|
||||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "atomic:localhost:5006/myns/official:official", "atomic:localhost:5006/myns/naming:test1")
|
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "atomic:localhost:5006/myns/official:official", "atomic:localhost:5006/myns/naming:test1")
|
||||||
assertSkopeoFails(t, ".*Source image rejected: Signature for identity localhost:5006/myns/official:official is not accepted.*",
|
assertSkopeoFails(t, `.*Source image rejected: Signature for identity \\"localhost:5006/myns/official:official\\" is not accepted.*`,
|
||||||
"--tls-verify=false", "--policy", policy, "copy", "atomic:localhost:5006/myns/naming:test1", dirDest)
|
"--tls-verify=false", "--policy", policy, "copy", "atomic:localhost:5006/myns/naming:test1", dirDest)
|
||||||
// signedIdentity works
|
// signedIdentity works
|
||||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "atomic:localhost:5006/myns/official:official", "atomic:localhost:5006/myns/naming:naming")
|
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "atomic:localhost:5006/myns/official:official", "atomic:localhost:5006/myns/naming:naming")
|
||||||
@ -824,7 +825,7 @@ func (s *copySuite) TestCopyDirSignatures() {
|
|||||||
// Verify that the signed identity is verified.
|
// Verify that the signed identity is verified.
|
||||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--policy", policy, "copy", "--sign-by", "official@example.com", topDirDest+"/dir1", "atomic:localhost:5000/myns/personal:dirstaging2")
|
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--policy", policy, "copy", "--sign-by", "official@example.com", topDirDest+"/dir1", "atomic:localhost:5000/myns/personal:dirstaging2")
|
||||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "atomic:localhost:5000/myns/personal:dirstaging2", topDirDest+"/restricted/badidentity")
|
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "atomic:localhost:5000/myns/personal:dirstaging2", topDirDest+"/restricted/badidentity")
|
||||||
assertSkopeoFails(t, ".*Source image rejected: .*Signature for identity localhost:5000/myns/personal:dirstaging2 is not accepted.*",
|
assertSkopeoFails(t, `.*Source image rejected: .*Signature for identity \\"localhost:5000/myns/personal:dirstaging2\\" is not accepted.*`,
|
||||||
"--policy", policy, "copy", topDirDest+"/restricted/badidentity", topDirDest+"/dest")
|
"--policy", policy, "copy", topDirDest+"/restricted/badidentity", topDirDest+"/dest")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1048,7 +1049,7 @@ func (s *copySuite) TestCopyVerifyingMirroredSignatures() {
|
|||||||
// … but verify that while it is accessible using the primary location redirecting to the mirror, …
|
// … but verify that while it is accessible using the primary location redirecting to the mirror, …
|
||||||
assertSkopeoSucceeds(t, "" /* no --policy */, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"primary:mirror-signed", dirDest)
|
assertSkopeoSucceeds(t, "" /* no --policy */, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"primary:mirror-signed", dirDest)
|
||||||
// … verify it is NOT accessible when requiring a signature.
|
// … verify it is NOT accessible when requiring a signature.
|
||||||
assertSkopeoFails(t, ".*Source image rejected: None of the signatures were accepted, reasons: Signature for identity localhost:5006/myns/mirroring-primary:direct is not accepted; Signature for identity localhost:5006/myns/mirroring-mirror:mirror-signed is not accepted.*",
|
assertSkopeoFails(t, `.*Source image rejected: None of the signatures were accepted, reasons: Signature for identity \\"localhost:5006/myns/mirroring-primary:direct\\" is not accepted; Signature for identity \\"localhost:5006/myns/mirroring-mirror:mirror-signed\\" is not accepted.*`,
|
||||||
"--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"primary:mirror-signed", dirDest)
|
"--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"primary:mirror-signed", dirDest)
|
||||||
|
|
||||||
// Fail if we specify an unqualified identity
|
// Fail if we specify an unqualified identity
|
||||||
@ -1062,14 +1063,14 @@ func (s *copySuite) TestCopyVerifyingMirroredSignatures() {
|
|||||||
// … but verify that while it is accessible using the mirror location
|
// … but verify that while it is accessible using the mirror location
|
||||||
assertSkopeoSucceeds(t, "" /* no --policy */, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"mirror:primary-signed", dirDest)
|
assertSkopeoSucceeds(t, "" /* no --policy */, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"mirror:primary-signed", dirDest)
|
||||||
// … verify it is NOT accessible when requiring a signature.
|
// … verify it is NOT accessible when requiring a signature.
|
||||||
assertSkopeoFails(t, ".*Source image rejected: None of the signatures were accepted, reasons: Signature for identity localhost:5006/myns/mirroring-primary:direct is not accepted; Signature for identity localhost:5006/myns/mirroring-mirror:mirror-signed is not accepted; Signature for identity localhost:5006/myns/mirroring-primary:primary-signed is not accepted.*",
|
assertSkopeoFails(t, `.*Source image rejected: None of the signatures were accepted, reasons: Signature for identity \\"localhost:5006/myns/mirroring-primary:direct\\" is not accepted; Signature for identity \\"localhost:5006/myns/mirroring-mirror:mirror-signed\\" is not accepted; Signature for identity \\"localhost:5006/myns/mirroring-primary:primary-signed\\" is not accepted.*`,
|
||||||
"--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"mirror:primary-signed", dirDest)
|
"--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"mirror:primary-signed", dirDest)
|
||||||
|
|
||||||
assertSkopeoSucceeds(t, "", "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", "--dest-tls-verify=false", regPrefix+"primary:unsigned", regPrefix+"remap:remapped")
|
assertSkopeoSucceeds(t, "", "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", "--dest-tls-verify=false", regPrefix+"primary:unsigned", regPrefix+"remap:remapped")
|
||||||
// Verify that while a remapIdentity image is accessible using the remapped (mirror) location
|
// Verify that while a remapIdentity image is accessible using the remapped (mirror) location
|
||||||
assertSkopeoSucceeds(t, "" /* no --policy */, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"remap:remapped", dirDest)
|
assertSkopeoSucceeds(t, "" /* no --policy */, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"remap:remapped", dirDest)
|
||||||
// … it is NOT accessible when requiring a signature …
|
// … it is NOT accessible when requiring a signature …
|
||||||
assertSkopeoFails(t, ".*Source image rejected: None of the signatures were accepted, reasons: Signature for identity localhost:5006/myns/mirroring-primary:direct is not accepted; Signature for identity localhost:5006/myns/mirroring-mirror:mirror-signed is not accepted; Signature for identity localhost:5006/myns/mirroring-primary:primary-signed is not accepted.*", "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"remap:remapped", dirDest)
|
assertSkopeoFails(t, `.*Source image rejected: None of the signatures were accepted, reasons: Signature for identity \\"localhost:5006/myns/mirroring-primary:direct\\" is not accepted; Signature for identity \\"localhost:5006/myns/mirroring-mirror:mirror-signed\\" is not accepted; Signature for identity \\"localhost:5006/myns/mirroring-primary:primary-signed\\" is not accepted.*`, "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"remap:remapped", dirDest)
|
||||||
// … until signed.
|
// … until signed.
|
||||||
assertSkopeoSucceeds(t, "", "--registries.d", registriesDir, "copy", "--src-tls-verify=false", "--dest-tls-verify=false", "--sign-by=personal@example.com", "--sign-identity=localhost:5006/myns/mirroring-primary:remapped", regPrefix+"remap:remapped", regPrefix+"remap:remapped")
|
assertSkopeoSucceeds(t, "", "--registries.d", registriesDir, "copy", "--src-tls-verify=false", "--dest-tls-verify=false", "--sign-by=personal@example.com", "--sign-identity=localhost:5006/myns/mirroring-primary:remapped", regPrefix+"remap:remapped", regPrefix+"remap:remapped")
|
||||||
assertSkopeoSucceeds(t, "", "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"remap:remapped", dirDest)
|
assertSkopeoSucceeds(t, "", "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"remap:remapped", dirDest)
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
#!/bin/bash -e
|
|
||||||
# Account for differences between dir: images that are solely due to one being
|
|
||||||
# compressed (fresh from a registry) and the other not being compressed (read
|
|
||||||
# from storage, which decompressed it and had to reassemble the layer blobs).
|
|
||||||
for dir in "$@" ; do
|
|
||||||
# Updating the manifest's blob digests may change the formatting, so
|
|
||||||
# use jq to get them into similar shape.
|
|
||||||
jq -M . "${dir}"/manifest.json > "${dir}"/manifest.json.tmp && mv "${dir}"/manifest.json.tmp "${dir}"/manifest.json
|
|
||||||
for candidate in "${dir}"/???????????????????????????????????????????????????????????????? ; do
|
|
||||||
# If a digest-identified file looks like it was compressed,
|
|
||||||
# decompress it, and replace its hash and size in the manifest
|
|
||||||
# with the values for their decompressed versions.
|
|
||||||
uncompressed=`zcat "${candidate}" 2> /dev/null | sha256sum | cut -c1-64`
|
|
||||||
if test $? -eq 0 ; then
|
|
||||||
if test "$uncompressed" != e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 ; then
|
|
||||||
zcat "${candidate}" > "${dir}"/${uncompressed}
|
|
||||||
sed -r -i -e "s#sha256:$(basename ${candidate})#sha256:${uncompressed}#g" "${dir}"/manifest.json
|
|
||||||
sed -r -i -e "s#\"size\": $(wc -c < ${candidate}),#\"size\": $(wc -c < ${dir}/${uncompressed}),#g" "${dir}"/manifest.json
|
|
||||||
rm -f "${candidate}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
@ -1,5 +1,4 @@
|
|||||||
//go:build openshift_shell
|
//go:build openshift_shell
|
||||||
// +build openshift_shell
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -153,7 +154,7 @@ func (cluster *openshiftCluster) prepareRegistryConfig(t *testing.T) {
|
|||||||
require.Equal(t, "", string(out))
|
require.Equal(t, "", string(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
// startRegistry starts the OpenShift registry with configPart on port, waits for it to be ready, and returns the process object, or terminates on failure.
|
// startRegistryProcess starts the OpenShift registry with configPart on port, waits for it to be ready, and returns the process object, or terminates on failure.
|
||||||
func (cluster *openshiftCluster) startRegistryProcess(t *testing.T, port uint16, configPath string) *exec.Cmd {
|
func (cluster *openshiftCluster) startRegistryProcess(t *testing.T, port uint16, configPath string) *exec.Cmd {
|
||||||
cmd := cluster.clusterCmd(map[string]string{
|
cmd := cluster.clusterCmd(map[string]string{
|
||||||
"KUBECONFIG": "openshift.local.registry/openshift-registry.kubeconfig",
|
"KUBECONFIG": "openshift.local.registry/openshift-registry.kubeconfig",
|
||||||
@ -253,10 +254,10 @@ func (cluster *openshiftCluster) relaxImageSignerPermissions(t *testing.T) {
|
|||||||
|
|
||||||
// tearDown stops the cluster services and deletes (only some!) of the state.
|
// tearDown stops the cluster services and deletes (only some!) of the state.
|
||||||
func (cluster *openshiftCluster) tearDown(t *testing.T) {
|
func (cluster *openshiftCluster) tearDown(t *testing.T) {
|
||||||
for i := len(cluster.processes) - 1; i >= 0; i-- {
|
for _, process := range slices.Backward(cluster.processes) {
|
||||||
// It’s undocumented what Kill() returns if the process has terminated,
|
// It’s undocumented what Kill() returns if the process has terminated,
|
||||||
// so we couldn’t check just for that. This is running in a container anyway…
|
// so we couldn’t check just for that. This is running in a container anyway…
|
||||||
_ = cluster.processes[i].Process.Kill()
|
_ = process.Process.Kill()
|
||||||
}
|
}
|
||||||
if cluster.dockerDir != "" {
|
if cluster.dockerDir != "" {
|
||||||
err := os.RemoveAll(cluster.dockerDir)
|
err := os.RemoveAll(cluster.dockerDir)
|
@ -5,7 +5,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
// cmdLifecyleToParentIfPossible is a thin wrapper around prctl(PR_SET_PDEATHSIG)
|
// cmdLifecycleToParentIfPossible is a thin wrapper around prctl(PR_SET_PDEATHSIG)
|
||||||
// on Linux.
|
// on Linux.
|
||||||
func cmdLifecycleToParentIfPossible(c *exec.Cmd) {
|
func cmdLifecycleToParentIfPossible(c *exec.Cmd) {
|
||||||
c.SysProcAttr = &syscall.SysProcAttr{
|
c.SysProcAttr = &syscall.SysProcAttr{
|
@ -1,5 +1,4 @@
|
|||||||
//go:build !linux
|
//go:build unix && !linux
|
||||||
// +build !linux
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build unix
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -229,7 +231,8 @@ type byteFetch struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTestGetManifestAndConfig(p *proxy, img string) error {
|
// This exercises all the metadata fetching APIs.
|
||||||
|
func runTestMetadataAPIs(p *proxy, img string) error {
|
||||||
v, err := p.callNoFd("OpenImage", []any{img})
|
v, err := p.callNoFd("OpenImage", []any{img})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -291,6 +294,19 @@ func runTestGetManifestAndConfig(p *proxy, img string) error {
|
|||||||
return fmt.Errorf("No CMD or ENTRYPOINT set")
|
return fmt.Errorf("No CMD or ENTRYPOINT set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, layerInfoBytes, err := p.callReadAllBytes("GetLayerInfoPiped", []any{imgid})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var layerInfoBytesData []interface{}
|
||||||
|
err = json.Unmarshal(layerInfoBytes, &layerInfoBytesData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(layerInfoBytesData) == 0 {
|
||||||
|
return fmt.Errorf("expected layer info data")
|
||||||
|
}
|
||||||
|
|
||||||
// Also test this legacy interface
|
// Also test this legacy interface
|
||||||
_, ctrconfigBytes, err := p.callReadAllBytes("GetConfig", []any{imgid})
|
_, ctrconfigBytes, err := p.callReadAllBytes("GetConfig", []any{imgid})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -337,13 +353,13 @@ func (s *proxySuite) TestProxy() {
|
|||||||
p, err := newProxy()
|
p, err := newProxy()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = runTestGetManifestAndConfig(p, knownNotManifestListedImageX8664)
|
err = runTestMetadataAPIs(p, knownNotManifestListedImageX8664)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Testing image %s: %v", knownNotManifestListedImageX8664, err)
|
err = fmt.Errorf("Testing image %s: %v", knownNotManifestListedImageX8664, err)
|
||||||
}
|
}
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = runTestGetManifestAndConfig(p, knownListImage)
|
err = runTestMetadataAPIs(p, knownListImage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Testing image %s: %v", knownListImage, err)
|
err = fmt.Errorf("Testing image %s: %v", knownListImage, err)
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ func setupRegistryV2At(t *testing.T, url string, auth, schema1 bool) *testRegist
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Wait for registry to be ready to serve requests.
|
// Wait for registry to be ready to serve requests.
|
||||||
for i := 0; i != 50; i++ {
|
for range 50 {
|
||||||
if err = reg.Ping(); err == nil {
|
if err = reg.Ping(); err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
@ -25,15 +25,15 @@ const (
|
|||||||
// A repository with a path with multiple components in it which
|
// A repository with a path with multiple components in it which
|
||||||
// contains multiple tags, preferably with some tags pointing to
|
// contains multiple tags, preferably with some tags pointing to
|
||||||
// manifest lists, and with some tags that don't.
|
// manifest lists, and with some tags that don't.
|
||||||
pullableRepo = "k8s.gcr.io/coredns/coredns"
|
pullableRepo = "registry.k8s.io/coredns/coredns"
|
||||||
// A tagged image in the repository that we can inspect and copy.
|
// A tagged image in the repository that we can inspect and copy.
|
||||||
pullableTaggedImage = "k8s.gcr.io/coredns/coredns:v1.6.6"
|
pullableTaggedImage = "registry.k8s.io/coredns/coredns:v1.6.6"
|
||||||
// A tagged manifest list in the repository that we can inspect and copy.
|
// A tagged manifest list in the repository that we can inspect and copy.
|
||||||
pullableTaggedManifestList = "k8s.gcr.io/coredns/coredns:v1.8.0"
|
pullableTaggedManifestList = "registry.k8s.io/coredns/coredns:v1.8.0"
|
||||||
// A repository containing multiple tags, some of which are for
|
// A repository containing multiple tags, some of which are for
|
||||||
// manifest lists, and which includes a "latest" tag. We specify the
|
// manifest lists, and which includes a "latest" tag. We specify the
|
||||||
// name here without a tag.
|
// name here without a tag.
|
||||||
pullableRepoWithLatestTag = "k8s.gcr.io/pause"
|
pullableRepoWithLatestTag = "registry.k8s.io/pause"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSync(t *testing.T) {
|
func TestSync(t *testing.T) {
|
||||||
@ -323,7 +323,7 @@ func (s *syncSuite) TestYamlRegex2Dir() {
|
|||||||
dir1 := path.Join(tmpDir, "dir1")
|
dir1 := path.Join(tmpDir, "dir1")
|
||||||
|
|
||||||
yamlConfig := `
|
yamlConfig := `
|
||||||
k8s.gcr.io:
|
registry.k8s.io:
|
||||||
images-by-tag-regex:
|
images-by-tag-regex:
|
||||||
pause: ^[12]\.0$ # regex string test
|
pause: ^[12]\.0$ # regex string test
|
||||||
`
|
`
|
||||||
@ -344,7 +344,7 @@ func (s *syncSuite) TestYamlDigest2Dir() {
|
|||||||
dir1 := path.Join(tmpDir, "dir1")
|
dir1 := path.Join(tmpDir, "dir1")
|
||||||
|
|
||||||
yamlConfig := `
|
yamlConfig := `
|
||||||
k8s.gcr.io:
|
registry.k8s.io:
|
||||||
images:
|
images:
|
||||||
pause:
|
pause:
|
||||||
- sha256:59eec8837a4d942cc19a52b8c09ea75121acc38114a2c68b98983ce9356b8610
|
- sha256:59eec8837a4d942cc19a52b8c09ea75121acc38114a2c68b98983ce9356b8610
|
||||||
@ -362,7 +362,7 @@ func (s *syncSuite) TestYaml2Dir() {
|
|||||||
dir1 := path.Join(tmpDir, "dir1")
|
dir1 := path.Join(tmpDir, "dir1")
|
||||||
|
|
||||||
yamlConfig := `
|
yamlConfig := `
|
||||||
k8s.gcr.io:
|
registry.k8s.io:
|
||||||
images:
|
images:
|
||||||
coredns/coredns:
|
coredns/coredns:
|
||||||
- v1.8.0
|
- v1.8.0
|
||||||
|
@ -2,6 +2,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
@ -13,12 +15,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/image/v5/manifest"
|
"github.com/containers/image/v5/manifest"
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
const skopeoBinary = "skopeo"
|
const skopeoBinary = "skopeo"
|
||||||
const decompressDirsBinary = "./decompress-dirs.sh"
|
|
||||||
|
|
||||||
const testFQIN = "docker://quay.io/libpod/busybox" // tag left off on purpose, some tests need to add a special one
|
const testFQIN = "docker://quay.io/libpod/busybox" // tag left off on purpose, some tests need to add a special one
|
||||||
const testFQIN64 = "docker://quay.io/libpod/busybox:amd64"
|
const testFQIN64 = "docker://quay.io/libpod/busybox:amd64"
|
||||||
@ -164,7 +166,7 @@ func modifyEnviron(env []string, name, value string) []string {
|
|||||||
return append(res, prefix+value)
|
return append(res, prefix+value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fileFromFixtureFixture applies edits to inputPath and returns a path to the temporary file.
|
// fileFromFixture applies edits to inputPath and returns a path to the temporary file.
|
||||||
// Callers should defer os.Remove(the_returned_path)
|
// Callers should defer os.Remove(the_returned_path)
|
||||||
func fileFromFixture(t *testing.T, inputPath string, edits map[string]string) string {
|
func fileFromFixture(t *testing.T, inputPath string, edits map[string]string) string {
|
||||||
contents, err := os.ReadFile(inputPath)
|
contents, err := os.ReadFile(inputPath)
|
||||||
@ -186,27 +188,100 @@ func fileFromFixture(t *testing.T, inputPath string, edits map[string]string) st
|
|||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
// runDecompressDirs runs decompress-dirs.sh using exec.Command().CombinedOutput, verifies that the exit status is 0,
|
// decompressDirs decompresses specified dir:-formatted directories
|
||||||
// and optionally that the output matches a multi-line regexp if it is nonempty; or terminates c on failure
|
func decompressDirs(t *testing.T, dirs ...string) {
|
||||||
func runDecompressDirs(t *testing.T, args ...string) {
|
t.Logf("Decompressing %s", strings.Join(dirs, " "))
|
||||||
t.Logf("Running %s %s", decompressDirsBinary, strings.Join(args, " "))
|
for i, dir := range dirs {
|
||||||
for i, dir := range args {
|
|
||||||
m, err := os.ReadFile(filepath.Join(dir, "manifest.json"))
|
m, err := os.ReadFile(filepath.Join(dir, "manifest.json"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
t.Logf("manifest %d before: %s", i+1, string(m))
|
t.Logf("manifest %d before: %s", i+1, string(m))
|
||||||
}
|
|
||||||
out, err := exec.Command(decompressDirsBinary, args...).CombinedOutput()
|
decompressDir(t, dir)
|
||||||
assert.NoError(t, err, "%s", out)
|
|
||||||
for i, dir := range args {
|
m, err = os.ReadFile(filepath.Join(dir, "manifest.json"))
|
||||||
if len(out) > 0 {
|
|
||||||
t.Logf("output: %s", out)
|
|
||||||
}
|
|
||||||
m, err := os.ReadFile(filepath.Join(dir, "manifest.json"))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
t.Logf("manifest %d after: %s", i+1, string(m))
|
t.Logf("manifest %d after: %s", i+1, string(m))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getRawMapField assigns a value of rawMap[key] to dest,
|
||||||
|
// failing if it does not exist or if it doesn’t have the expected type
|
||||||
|
func getRawMapField[T any](t *testing.T, rawMap map[string]any, key string, dest *T) {
|
||||||
|
rawValue, ok := rawMap[key]
|
||||||
|
require.True(t, ok, key)
|
||||||
|
value, ok := rawValue.(T)
|
||||||
|
require.True(t, ok, key, "%#v", value)
|
||||||
|
*dest = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// decompressDir modifies a dir:-formatted directory to replace gzip-compressed layers with uncompressed variants,
|
||||||
|
// and to use a ~canonical formatting of manifest.json.
|
||||||
|
func decompressDir(t *testing.T, dir string) {
|
||||||
|
// This is, overall, very dumb; the “obvious” way would be to invoke skopeo to decompress,
|
||||||
|
// or at least to use c/image to parse/format the manifest.
|
||||||
|
//
|
||||||
|
// But this is used to test (aspects of) those code paths… so, it’s acceptable for this to be
|
||||||
|
// dumb and to make assumptions about the data, but it should not share code.
|
||||||
|
|
||||||
|
manifestBlob, err := os.ReadFile(filepath.Join(dir, "manifest.json"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
var rawManifest map[string]any
|
||||||
|
err = json.Unmarshal(manifestBlob, &rawManifest)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var rawLayers []any
|
||||||
|
getRawMapField(t, rawManifest, "layers", &rawLayers)
|
||||||
|
for i, rawLayerValue := range rawLayers {
|
||||||
|
rawLayer, ok := rawLayerValue.(map[string]any)
|
||||||
|
require.True(t, ok)
|
||||||
|
var digestString string
|
||||||
|
getRawMapField(t, rawLayer, "digest", &digestString)
|
||||||
|
compressedDigest, err := digest.Parse(digestString)
|
||||||
|
require.NoError(t, err)
|
||||||
|
if compressedDigest.String() == "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" { // An empty file
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
compressedPath := filepath.Join(dir, compressedDigest.Encoded())
|
||||||
|
compressedStream, err := os.Open(compressedPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer compressedStream.Close()
|
||||||
|
|
||||||
|
uncompressedStream, err := gzip.NewReader(compressedStream)
|
||||||
|
if err != nil {
|
||||||
|
continue // Silently assume the layer is not gzip-compressed
|
||||||
|
}
|
||||||
|
tempDest, err := os.CreateTemp(dir, "decompressing")
|
||||||
|
require.NoError(t, err)
|
||||||
|
digester := digest.Canonical.Digester()
|
||||||
|
uncompressedSize, err := io.Copy(tempDest, io.TeeReader(uncompressedStream, digester.Hash()))
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = uncompressedStream.Close()
|
||||||
|
require.NoError(t, err)
|
||||||
|
uncompressedDigest := digester.Digest()
|
||||||
|
uncompressedPath := filepath.Join(dir, uncompressedDigest.Encoded())
|
||||||
|
err = os.Rename(tempDest.Name(), uncompressedPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = os.Remove(compressedPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
rawLayer["digest"] = uncompressedDigest.String()
|
||||||
|
rawLayer["size"] = uncompressedSize
|
||||||
|
var mimeType string
|
||||||
|
getRawMapField(t, rawLayer, "mediaType", &mimeType)
|
||||||
|
if uncompressedMIMEType, ok := strings.CutSuffix(mimeType, ".gzip"); ok {
|
||||||
|
rawLayer["mediaType"] = uncompressedMIMEType
|
||||||
|
}
|
||||||
|
|
||||||
|
rawLayers[i] = rawLayer
|
||||||
|
}
|
||||||
|
rawManifest["layers"] = rawLayers
|
||||||
|
|
||||||
|
manifestBlob, err = json.Marshal(rawManifest)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = os.WriteFile(filepath.Join(dir, "manifest.json"), manifestBlob, 0o600)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
// Verify manifest in a dir: image at dir is expectedMIMEType.
|
// Verify manifest in a dir: image at dir is expectedMIMEType.
|
||||||
func verifyManifestMIMEType(t *testing.T, dir string, expectedMIMEType string) {
|
func verifyManifestMIMEType(t *testing.T, dir string, expectedMIMEType string) {
|
||||||
manifestBlob, err := os.ReadFile(filepath.Join(dir, "manifest.json"))
|
manifestBlob, err := os.ReadFile(filepath.Join(dir, "manifest.json"))
|
20
plans/main.fmf
Normal file
20
plans/main.fmf
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
discover:
|
||||||
|
how: fmf
|
||||||
|
execute:
|
||||||
|
how: tmt
|
||||||
|
prepare:
|
||||||
|
- when: distro == centos-stream or distro == rhel
|
||||||
|
how: shell
|
||||||
|
script: |
|
||||||
|
dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm --eval '%{?rhel}').noarch.rpm
|
||||||
|
dnf -y config-manager --set-enabled epel
|
||||||
|
order: 10
|
||||||
|
- when: initiator == packit
|
||||||
|
how: shell
|
||||||
|
script: |
|
||||||
|
COPR_REPO_FILE="/etc/yum.repos.d/*podman-next*.repo"
|
||||||
|
if compgen -G $COPR_REPO_FILE > /dev/null; then
|
||||||
|
sed -i -n '/^priority=/!p;$apriority=1' $COPR_REPO_FILE
|
||||||
|
fi
|
||||||
|
dnf -y upgrade --allowerasing
|
||||||
|
order: 20
|
16
rpm/gating.yaml
Normal file
16
rpm/gating.yaml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
--- !Policy
|
||||||
|
product_versions:
|
||||||
|
- fedora-*
|
||||||
|
decision_context:
|
||||||
|
- bodhi_update_push_stable
|
||||||
|
- bodhi_update_push_testing
|
||||||
|
subject_type: koji_build
|
||||||
|
rules:
|
||||||
|
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional}
|
||||||
|
|
||||||
|
--- !Policy
|
||||||
|
product_versions:
|
||||||
|
- rhel-*
|
||||||
|
decision_context: osci_compose_gate
|
||||||
|
rules:
|
||||||
|
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
@ -7,15 +7,6 @@
|
|||||||
%global debug_package %{nil}
|
%global debug_package %{nil}
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
# RHEL's default %%gobuild macro doesn't account for the BUILDTAGS variable, so we
|
|
||||||
# set it separately here and do not depend on RHEL's go-[s]rpm-macros package
|
|
||||||
# until that's fixed.
|
|
||||||
# c9s bz: https://bugzilla.redhat.com/show_bug.cgi?id=2227328
|
|
||||||
# c8s bz: https://bugzilla.redhat.com/show_bug.cgi?id=2227331
|
|
||||||
%if %{defined rhel}
|
|
||||||
%define gobuild(o:) go build -buildmode pie -compiler gc -tags="rpm_crashtraceback libtrust_openssl ${BUILDTAGS:-}" -ldflags "-linkmode=external -compressdwarf=false ${LDFLAGS:-} -B 0x$(head -c20 /dev/urandom|od -An -tx1|tr -d ' \\n') -extldflags '%__global_ldflags'" -a -v -x %{?**};
|
|
||||||
%endif
|
|
||||||
|
|
||||||
%global gomodulesmode GO111MODULE=on
|
%global gomodulesmode GO111MODULE=on
|
||||||
|
|
||||||
# No btrfs on RHEL
|
# No btrfs on RHEL
|
||||||
@ -23,10 +14,15 @@
|
|||||||
%define build_with_btrfs 1
|
%define build_with_btrfs 1
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
%if %{defined rhel}
|
||||||
|
%define fips 1
|
||||||
|
%endif
|
||||||
|
|
||||||
# Only used in official koji builds
|
# Only used in official koji builds
|
||||||
# Copr builds set a separate epoch for all environments
|
# Copr builds set a separate epoch for all environments
|
||||||
%if %{defined fedora}
|
%if %{defined fedora}
|
||||||
%define conditional_epoch 1
|
%define conditional_epoch 1
|
||||||
|
%define fakeroot 1
|
||||||
%else
|
%else
|
||||||
%define conditional_epoch 2
|
%define conditional_epoch 2
|
||||||
%endif
|
%endif
|
||||||
@ -67,7 +63,6 @@ BuildRequires: go-rpm-macros
|
|||||||
%endif
|
%endif
|
||||||
BuildRequires: gpgme-devel
|
BuildRequires: gpgme-devel
|
||||||
BuildRequires: libassuan-devel
|
BuildRequires: libassuan-devel
|
||||||
BuildRequires: pkgconfig(devmapper)
|
|
||||||
BuildRequires: ostree-devel
|
BuildRequires: ostree-devel
|
||||||
BuildRequires: glib2-devel
|
BuildRequires: glib2-devel
|
||||||
BuildRequires: make
|
BuildRequires: make
|
||||||
@ -78,11 +73,16 @@ Requires: containers-common >= 4:1-21
|
|||||||
Command line utility to inspect images and repositories directly on Docker
|
Command line utility to inspect images and repositories directly on Docker
|
||||||
registries without the need to pull them
|
registries without the need to pull them
|
||||||
|
|
||||||
|
# NOTE: The tests subpackage is only intended for testing and will not be supported
|
||||||
|
# for end-users and/or customers.
|
||||||
%package tests
|
%package tests
|
||||||
Summary: Tests for %{name}
|
Summary: Tests for %{name}
|
||||||
|
|
||||||
Requires: %{name} = %{epoch}:%{version}-%{release}
|
Requires: %{name} = %{epoch}:%{version}-%{release}
|
||||||
Requires: bats
|
Requires: bats
|
||||||
|
%if %{defined fakeroot}
|
||||||
|
Requires: fakeroot
|
||||||
|
%endif
|
||||||
Requires: gnupg
|
Requires: gnupg
|
||||||
Requires: jq
|
Requires: jq
|
||||||
Requires: golang
|
Requires: golang
|
||||||
@ -90,7 +90,6 @@ Requires: podman
|
|||||||
Requires: crun
|
Requires: crun
|
||||||
Requires: httpd-tools
|
Requires: httpd-tools
|
||||||
Requires: openssl
|
Requires: openssl
|
||||||
Requires: fakeroot
|
|
||||||
Requires: squashfs-tools
|
Requires: squashfs-tools
|
||||||
|
|
||||||
%description tests
|
%description tests
|
||||||
@ -119,11 +118,15 @@ CGO_CFLAGS=$(echo $CGO_CFLAGS | sed 's/-specs=\/usr\/lib\/rpm\/redhat\/redhat-an
|
|||||||
export CGO_CFLAGS="$CGO_CFLAGS -m64 -mtune=generic -fcf-protection=full"
|
export CGO_CFLAGS="$CGO_CFLAGS -m64 -mtune=generic -fcf-protection=full"
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
BASEBUILDTAGS="$(hack/libdm_tag.sh) $(hack/libsubid_tag.sh)"
|
BASEBUILDTAGS="$(hack/libsubid_tag.sh)"
|
||||||
%if %{defined build_with_btrfs}
|
%if %{defined build_with_btrfs}
|
||||||
export BUILDTAGS="$BASEBUILDTAGS $(hack/btrfs_tag.sh) $(hack/btrfs_installed_tag.sh)"
|
export BUILDTAGS="$BASEBUILDTAGS $(hack/btrfs_installed_tag.sh)"
|
||||||
%else
|
%else
|
||||||
export BUILDTAGS="$BASEBUILDTAGS btrfs_noversion exclude_graphdriver_btrfs"
|
export BUILDTAGS="$BASEBUILDTAGS exclude_graphdriver_btrfs"
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%if %{defined fips}
|
||||||
|
export BUILDTAGS="$BUILDTAGS libtrust_openssl"
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
# unset LDFLAGS earlier set from set_build_flags
|
# unset LDFLAGS earlier set from set_build_flags
|
||||||
@ -145,6 +148,10 @@ cp -pav systemtest/* %{buildroot}/%{_datadir}/%{name}/test/system/
|
|||||||
#define license tag if not already defined
|
#define license tag if not already defined
|
||||||
%{!?_licensedir:%global license %doc}
|
%{!?_licensedir:%global license %doc}
|
||||||
|
|
||||||
|
# Include this to silence rpmlint.
|
||||||
|
# Especially annoying if you use syntastic vim plugin.
|
||||||
|
%check
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%license LICENSE
|
%license LICENSE
|
||||||
%doc README.md
|
%doc README.md
|
||||||
@ -159,16 +166,8 @@ cp -pav systemtest/* %{buildroot}/%{_datadir}/%{name}/test/system/
|
|||||||
%{_datadir}/zsh/site-functions/_%{name}
|
%{_datadir}/zsh/site-functions/_%{name}
|
||||||
|
|
||||||
%files tests
|
%files tests
|
||||||
%license LICENSE
|
%license LICENSE vendor/modules.txt
|
||||||
%{_datadir}/%{name}/test
|
%{_datadir}/%{name}/test
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
%if %{defined autochangelog}
|
|
||||||
%autochangelog
|
%autochangelog
|
||||||
%else
|
|
||||||
# NOTE: This changelog will be visible on CentOS 8 Stream builds
|
|
||||||
# Other envs are capable of handling autochangelog
|
|
||||||
* Tue Jun 13 2023 RH Container Bot <rhcontainerbot@fedoraproject.org>
|
|
||||||
- Placeholder changelog for envs that are not autochangelog-ready.
|
|
||||||
- Contact upstream if you need to report an issue with the build.
|
|
||||||
%endif
|
|
||||||
|
@ -36,7 +36,7 @@ load helpers
|
|||||||
# the output of 'inspect' lists layer digests,
|
# the output of 'inspect' lists layer digests,
|
||||||
# but not the digest of the config blob ($config_digest), if any.
|
# but not the digest of the config blob ($config_digest), if any.
|
||||||
layers=$(jq -r '.Layers' <<<"$inspect_local")
|
layers=$(jq -r '.Layers' <<<"$inspect_local")
|
||||||
for sha in $(find $workdir -type f | xargs -l1 basename | egrep '^[0-9a-f]{64}$'); do
|
for sha in $(find $workdir -type f | xargs -l1 basename | grep -E '^[0-9a-f]{64}$'); do
|
||||||
if [ "sha256:$sha" != "$config_digest" ]; then
|
if [ "sha256:$sha" != "$config_digest" ]; then
|
||||||
expect_output --from="$layers" --substring "sha256:$sha" \
|
expect_output --from="$layers" --substring "sha256:$sha" \
|
||||||
"Locally-extracted SHA file is present in 'inspect'"
|
"Locally-extracted SHA file is present in 'inspect'"
|
||||||
@ -103,7 +103,7 @@ END_EXPECT
|
|||||||
|
|
||||||
# By default, 'inspect' tries to match our host os+arch. This should fail.
|
# By default, 'inspect' tries to match our host os+arch. This should fail.
|
||||||
run_skopeo 1 inspect $img
|
run_skopeo 1 inspect $img
|
||||||
expect_output --substring "parsing manifest for image: choosing image instance: no image found in manifest list for architecture $arch, variant " \
|
expect_output --substring "parsing manifest for image: choosing image instance: no image found in manifest list for architecture \\\\\"$arch\\\\\", variant " \
|
||||||
"skopeo inspect, without --raw, fails"
|
"skopeo inspect, without --raw, fails"
|
||||||
|
|
||||||
# With --raw, we can inspect
|
# With --raw, we can inspect
|
||||||
@ -129,4 +129,11 @@ END_EXPECT
|
|||||||
expect_output --from="$repo_tags" "" "inspect --no-tags was expected to return empty RepoTags[]"
|
expect_output --from="$repo_tags" "" "inspect --no-tags was expected to return empty RepoTags[]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "inspect: image unknown" {
|
||||||
|
# non existing image
|
||||||
|
run_skopeo 2 inspect containers-storage:non-existing-tag
|
||||||
|
expect_output --substring "does not resolve to an image ID" \
|
||||||
|
"skopeo inspect containers-storage:010101010101"
|
||||||
|
}
|
||||||
|
|
||||||
# vim: filetype=sh
|
# vim: filetype=sh
|
||||||
|
@ -40,7 +40,7 @@ function setup() {
|
|||||||
expect_output --substring "authentication required"
|
expect_output --substring "authentication required"
|
||||||
|
|
||||||
# Correct creds, but no such image
|
# Correct creds, but no such image
|
||||||
run_skopeo 1 inspect --tls-verify=false --creds=$testuser:$testpassword \
|
run_skopeo 2 inspect --tls-verify=false --creds=$testuser:$testpassword \
|
||||||
docker://localhost:5000/nonesuch
|
docker://localhost:5000/nonesuch
|
||||||
expect_output --substring "manifest unknown"
|
expect_output --substring "manifest unknown"
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ END_PUSH
|
|||||||
done <<END_TESTS
|
done <<END_TESTS
|
||||||
/myns/alice:signed
|
/myns/alice:signed
|
||||||
/myns/bob:signedbyalice Invalid GPG signature
|
/myns/bob:signedbyalice Invalid GPG signature
|
||||||
/myns/alice:unsigned Signature for identity localhost:5000/myns/alice:signed is not accepted
|
/myns/alice:unsigned Signature for identity \\\\\\\\"localhost:5000/myns/alice:signed\\\\\\\\" is not accepted
|
||||||
/myns/carol:latest Running image docker://localhost:5000/myns/carol:latest is rejected by policy.
|
/myns/carol:latest Running image docker://localhost:5000/myns/carol:latest is rejected by policy.
|
||||||
/open/forall:latest
|
/open/forall:latest
|
||||||
END_TESTS
|
END_TESTS
|
||||||
|
@ -24,7 +24,7 @@ function setup() {
|
|||||||
run_skopeo delete --tls-verify=false $localimg
|
run_skopeo delete --tls-verify=false $localimg
|
||||||
|
|
||||||
# make sure image is removed from registry
|
# make sure image is removed from registry
|
||||||
expected_rc=1
|
expected_rc=2
|
||||||
run_skopeo $expected_rc inspect --tls-verify=false $localimg
|
run_skopeo $expected_rc inspect --tls-verify=false $localimg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ SKOPEO_BINARY=${SKOPEO_BINARY:-${TEST_SOURCE_DIR}/../bin/skopeo}
|
|||||||
SKOPEO_TIMEOUT=${SKOPEO_TIMEOUT:-300}
|
SKOPEO_TIMEOUT=${SKOPEO_TIMEOUT:-300}
|
||||||
|
|
||||||
# Default image to run as a local registry
|
# Default image to run as a local registry
|
||||||
REGISTRY_FQIN=${SKOPEO_TEST_REGISTRY_FQIN:-quay.io/libpod/registry:2}
|
REGISTRY_FQIN=${SKOPEO_TEST_REGISTRY_FQIN:-quay.io/libpod/registry:2.8.2}
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# BEGIN setup/teardown
|
# BEGIN setup/teardown
|
||||||
@ -317,7 +317,7 @@ start_registry() {
|
|||||||
die "start_registry() invoked with testuser but no testpassword"
|
die "start_registry() invoked with testuser but no testpassword"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! egrep -q "^$testuser:" $AUTHDIR/htpasswd; then
|
if ! grep -E -q "^$testuser:" $AUTHDIR/htpasswd; then
|
||||||
htpasswd -Bbn $testuser $testpassword >> $AUTHDIR/htpasswd
|
htpasswd -Bbn $testuser $testpassword >> $AUTHDIR/htpasswd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
10
systemtest/tmt/main.fmf
Normal file
10
systemtest/tmt/main.fmf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
require:
|
||||||
|
- bats
|
||||||
|
- skopeo-tests
|
||||||
|
|
||||||
|
environment:
|
||||||
|
SKOPEO_BINARY: /usr/bin/skopeo
|
||||||
|
|
||||||
|
summary: System test
|
||||||
|
test: bash ./test.sh
|
||||||
|
duration: 60m
|
13
systemtest/tmt/test.sh
Normal file
13
systemtest/tmt/test.sh
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -exo pipefail
|
||||||
|
|
||||||
|
uname -r
|
||||||
|
|
||||||
|
rpm -q \
|
||||||
|
bats \
|
||||||
|
containers-common \
|
||||||
|
skopeo \
|
||||||
|
skopeo-tests \
|
||||||
|
|
||||||
|
bats /usr/share/skopeo/test/system
|
3
vendor/dario.cat/mergo/.gitignore
vendored
3
vendor/dario.cat/mergo/.gitignore
vendored
@ -13,6 +13,9 @@
|
|||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
*.out
|
*.out
|
||||||
|
|
||||||
|
# Golang/Intellij
|
||||||
|
.idea
|
||||||
|
|
||||||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||||
.glide/
|
.glide/
|
||||||
|
|
||||||
|
102
vendor/dario.cat/mergo/README.md
vendored
102
vendor/dario.cat/mergo/README.md
vendored
@ -44,13 +44,21 @@ Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, Microsoft, etc](https://github.com/imdario/mergo#mergo-in-the-wild).
|
Mergo is stable and frozen, ready for production. Check a short list of the projects using at large scale it [here](https://github.com/imdario/mergo#mergo-in-the-wild).
|
||||||
|
|
||||||
|
No new features are accepted. They will be considered for a future v2 that improves the implementation and fixes bugs for corner cases.
|
||||||
|
|
||||||
### Important notes
|
### Important notes
|
||||||
|
|
||||||
#### 1.0.0
|
#### 1.0.0
|
||||||
|
|
||||||
In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`.
|
In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`. No more v1 versions will be released.
|
||||||
|
|
||||||
|
If the vanity URL is causing issues in your project due to a dependency pulling Mergo - it isn't a direct dependency in your project - it is recommended to use [replace](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive) to pin the version to the last one with the old import URL:
|
||||||
|
|
||||||
|
```
|
||||||
|
replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16
|
||||||
|
```
|
||||||
|
|
||||||
#### 0.3.9
|
#### 0.3.9
|
||||||
|
|
||||||
@ -64,55 +72,24 @@ If you were using Mergo before April 6th, 2015, please check your project works
|
|||||||
|
|
||||||
If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes:
|
If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes:
|
||||||
|
|
||||||
<a href='https://ko-fi.com/B0B58839' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
|
|
||||||
<a href="https://liberapay.com/dario/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a>
|
<a href="https://liberapay.com/dario/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a>
|
||||||
<a href='https://github.com/sponsors/imdario' target='_blank'><img alt="Become my sponsor" src="https://img.shields.io/github/sponsors/imdario?style=for-the-badge" /></a>
|
<a href='https://github.com/sponsors/imdario' target='_blank'><img alt="Become my sponsor" src="https://img.shields.io/github/sponsors/imdario?style=for-the-badge" /></a>
|
||||||
|
|
||||||
### Mergo in the wild
|
### Mergo in the wild
|
||||||
|
|
||||||
- [moby/moby](https://github.com/moby/moby)
|
Mergo is used by [thousands](https://deps.dev/go/dario.cat%2Fmergo/v1.0.0/dependents) [of](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.16/dependents) [projects](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.12), including:
|
||||||
- [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
|
|
||||||
- [vmware/dispatch](https://github.com/vmware/dispatch)
|
* [containerd/containerd](https://github.com/containerd/containerd)
|
||||||
- [Shopify/themekit](https://github.com/Shopify/themekit)
|
* [datadog/datadog-agent](https://github.com/datadog/datadog-agent)
|
||||||
- [imdario/zas](https://github.com/imdario/zas)
|
* [docker/cli/](https://github.com/docker/cli/)
|
||||||
- [matcornic/hermes](https://github.com/matcornic/hermes)
|
* [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
|
||||||
- [OpenBazaar/openbazaar-go](https://github.com/OpenBazaar/openbazaar-go)
|
* [go-micro/go-micro](https://github.com/go-micro/go-micro)
|
||||||
- [kataras/iris](https://github.com/kataras/iris)
|
* [grafana/loki](https://github.com/grafana/loki)
|
||||||
- [michaelsauter/crane](https://github.com/michaelsauter/crane)
|
* [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
|
||||||
- [go-task/task](https://github.com/go-task/task)
|
* [masterminds/sprig](github.com/Masterminds/sprig)
|
||||||
- [sensu/uchiwa](https://github.com/sensu/uchiwa)
|
* [moby/moby](https://github.com/moby/moby)
|
||||||
- [ory/hydra](https://github.com/ory/hydra)
|
* [slackhq/nebula](https://github.com/slackhq/nebula)
|
||||||
- [sisatech/vcli](https://github.com/sisatech/vcli)
|
* [volcano-sh/volcano](https://github.com/volcano-sh/volcano)
|
||||||
- [dairycart/dairycart](https://github.com/dairycart/dairycart)
|
|
||||||
- [projectcalico/felix](https://github.com/projectcalico/felix)
|
|
||||||
- [resin-os/balena](https://github.com/resin-os/balena)
|
|
||||||
- [go-kivik/kivik](https://github.com/go-kivik/kivik)
|
|
||||||
- [Telefonica/govice](https://github.com/Telefonica/govice)
|
|
||||||
- [supergiant/supergiant](supergiant/supergiant)
|
|
||||||
- [SergeyTsalkov/brooce](https://github.com/SergeyTsalkov/brooce)
|
|
||||||
- [soniah/dnsmadeeasy](https://github.com/soniah/dnsmadeeasy)
|
|
||||||
- [ohsu-comp-bio/funnel](https://github.com/ohsu-comp-bio/funnel)
|
|
||||||
- [EagerIO/Stout](https://github.com/EagerIO/Stout)
|
|
||||||
- [lynndylanhurley/defsynth-api](https://github.com/lynndylanhurley/defsynth-api)
|
|
||||||
- [russross/canvasassignments](https://github.com/russross/canvasassignments)
|
|
||||||
- [rdegges/cryptly-api](https://github.com/rdegges/cryptly-api)
|
|
||||||
- [casualjim/exeggutor](https://github.com/casualjim/exeggutor)
|
|
||||||
- [divshot/gitling](https://github.com/divshot/gitling)
|
|
||||||
- [RWJMurphy/gorl](https://github.com/RWJMurphy/gorl)
|
|
||||||
- [andrerocker/deploy42](https://github.com/andrerocker/deploy42)
|
|
||||||
- [elwinar/rambler](https://github.com/elwinar/rambler)
|
|
||||||
- [tmaiaroto/gopartman](https://github.com/tmaiaroto/gopartman)
|
|
||||||
- [jfbus/impressionist](https://github.com/jfbus/impressionist)
|
|
||||||
- [Jmeyering/zealot](https://github.com/Jmeyering/zealot)
|
|
||||||
- [godep-migrator/rigger-host](https://github.com/godep-migrator/rigger-host)
|
|
||||||
- [Dronevery/MultiwaySwitch-Go](https://github.com/Dronevery/MultiwaySwitch-Go)
|
|
||||||
- [thoas/picfit](https://github.com/thoas/picfit)
|
|
||||||
- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)
|
|
||||||
- [jnuthong/item_search](https://github.com/jnuthong/item_search)
|
|
||||||
- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)
|
|
||||||
- [containerssh/containerssh](https://github.com/containerssh/containerssh)
|
|
||||||
- [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
|
|
||||||
- [tjpnz/structbot](https://github.com/tjpnz/structbot)
|
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
@ -141,6 +118,39 @@ if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you need to override pointers, so the source pointer's value is assigned to the destination's pointer, you must use `WithoutDereference`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"dario.cat/mergo"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Foo struct {
|
||||||
|
A *string
|
||||||
|
B int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
first := "first"
|
||||||
|
second := "second"
|
||||||
|
src := Foo{
|
||||||
|
A: &first,
|
||||||
|
B: 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
dest := Foo{
|
||||||
|
A: &second,
|
||||||
|
B: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
mergo.Merge(&dest, src, mergo.WithOverride, mergo.WithoutDereference)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.
|
Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
2
vendor/dario.cat/mergo/map.go
vendored
2
vendor/dario.cat/mergo/map.go
vendored
@ -58,7 +58,7 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, conf
|
|||||||
}
|
}
|
||||||
fieldName := field.Name
|
fieldName := field.Name
|
||||||
fieldName = changeInitialCase(fieldName, unicode.ToLower)
|
fieldName = changeInitialCase(fieldName, unicode.ToLower)
|
||||||
if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v), !config.ShouldNotDereference) || overwrite) {
|
if _, ok := dstMap[fieldName]; !ok || (!isEmptyValue(reflect.ValueOf(src.Field(i).Interface()), !config.ShouldNotDereference) && overwrite) || config.overwriteWithEmptyValue {
|
||||||
dstMap[fieldName] = src.Field(i).Interface()
|
dstMap[fieldName] = src.Field(i).Interface()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
vendor/dario.cat/mergo/merge.go
vendored
2
vendor/dario.cat/mergo/merge.go
vendored
@ -269,7 +269,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
|
|||||||
if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
|
if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else if src.Elem().Kind() != reflect.Struct {
|
||||||
if overwriteWithEmptySrc || (overwrite && !src.IsNil()) || dst.IsNil() {
|
if overwriteWithEmptySrc || (overwrite && !src.IsNil()) || dst.IsNil() {
|
||||||
dst.Set(src)
|
dst.Set(src)
|
||||||
}
|
}
|
||||||
|
4
vendor/github.com/BurntSushi/toml/README.md
generated
vendored
4
vendor/github.com/BurntSushi/toml/README.md
generated
vendored
@ -3,13 +3,13 @@ reflection interface similar to Go's standard library `json` and `xml` packages.
|
|||||||
|
|
||||||
Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0).
|
Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0).
|
||||||
|
|
||||||
Documentation: https://godocs.io/github.com/BurntSushi/toml
|
Documentation: https://pkg.go.dev/github.com/BurntSushi/toml
|
||||||
|
|
||||||
See the [releases page](https://github.com/BurntSushi/toml/releases) for a
|
See the [releases page](https://github.com/BurntSushi/toml/releases) for a
|
||||||
changelog; this information is also in the git tag annotations (e.g. `git show
|
changelog; this information is also in the git tag annotations (e.g. `git show
|
||||||
v0.4.0`).
|
v0.4.0`).
|
||||||
|
|
||||||
This library requires Go 1.13 or newer; add it to your go.mod with:
|
This library requires Go 1.18 or newer; add it to your go.mod with:
|
||||||
|
|
||||||
% go get github.com/BurntSushi/toml@latest
|
% go get github.com/BurntSushi/toml@latest
|
||||||
|
|
||||||
|
126
vendor/github.com/BurntSushi/toml/decode.go
generated
vendored
126
vendor/github.com/BurntSushi/toml/decode.go
generated
vendored
@ -6,7 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/fs"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -18,13 +18,13 @@ import (
|
|||||||
// Unmarshaler is the interface implemented by objects that can unmarshal a
|
// Unmarshaler is the interface implemented by objects that can unmarshal a
|
||||||
// TOML description of themselves.
|
// TOML description of themselves.
|
||||||
type Unmarshaler interface {
|
type Unmarshaler interface {
|
||||||
UnmarshalTOML(interface{}) error
|
UnmarshalTOML(any) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal decodes the contents of data in TOML format into a pointer v.
|
// Unmarshal decodes the contents of data in TOML format into a pointer v.
|
||||||
//
|
//
|
||||||
// See [Decoder] for a description of the decoding process.
|
// See [Decoder] for a description of the decoding process.
|
||||||
func Unmarshal(data []byte, v interface{}) error {
|
func Unmarshal(data []byte, v any) error {
|
||||||
_, err := NewDecoder(bytes.NewReader(data)).Decode(v)
|
_, err := NewDecoder(bytes.NewReader(data)).Decode(v)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -32,12 +32,12 @@ func Unmarshal(data []byte, v interface{}) error {
|
|||||||
// Decode the TOML data in to the pointer v.
|
// Decode the TOML data in to the pointer v.
|
||||||
//
|
//
|
||||||
// See [Decoder] for a description of the decoding process.
|
// See [Decoder] for a description of the decoding process.
|
||||||
func Decode(data string, v interface{}) (MetaData, error) {
|
func Decode(data string, v any) (MetaData, error) {
|
||||||
return NewDecoder(strings.NewReader(data)).Decode(v)
|
return NewDecoder(strings.NewReader(data)).Decode(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeFile reads the contents of a file and decodes it with [Decode].
|
// DecodeFile reads the contents of a file and decodes it with [Decode].
|
||||||
func DecodeFile(path string, v interface{}) (MetaData, error) {
|
func DecodeFile(path string, v any) (MetaData, error) {
|
||||||
fp, err := os.Open(path)
|
fp, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return MetaData{}, err
|
return MetaData{}, err
|
||||||
@ -46,6 +46,17 @@ func DecodeFile(path string, v interface{}) (MetaData, error) {
|
|||||||
return NewDecoder(fp).Decode(v)
|
return NewDecoder(fp).Decode(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeFS reads the contents of a file from [fs.FS] and decodes it with
|
||||||
|
// [Decode].
|
||||||
|
func DecodeFS(fsys fs.FS, path string, v any) (MetaData, error) {
|
||||||
|
fp, err := fsys.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return MetaData{}, err
|
||||||
|
}
|
||||||
|
defer fp.Close()
|
||||||
|
return NewDecoder(fp).Decode(v)
|
||||||
|
}
|
||||||
|
|
||||||
// Primitive is a TOML value that hasn't been decoded into a Go value.
|
// Primitive is a TOML value that hasn't been decoded into a Go value.
|
||||||
//
|
//
|
||||||
// This type can be used for any value, which will cause decoding to be delayed.
|
// This type can be used for any value, which will cause decoding to be delayed.
|
||||||
@ -58,7 +69,7 @@ func DecodeFile(path string, v interface{}) (MetaData, error) {
|
|||||||
// overhead of reflection. They can be useful when you don't know the exact type
|
// overhead of reflection. They can be useful when you don't know the exact type
|
||||||
// of TOML data until runtime.
|
// of TOML data until runtime.
|
||||||
type Primitive struct {
|
type Primitive struct {
|
||||||
undecoded interface{}
|
undecoded any
|
||||||
context Key
|
context Key
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +133,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Decode TOML data in to the pointer `v`.
|
// Decode TOML data in to the pointer `v`.
|
||||||
func (dec *Decoder) Decode(v interface{}) (MetaData, error) {
|
func (dec *Decoder) Decode(v any) (MetaData, error) {
|
||||||
rv := reflect.ValueOf(v)
|
rv := reflect.ValueOf(v)
|
||||||
if rv.Kind() != reflect.Ptr {
|
if rv.Kind() != reflect.Ptr {
|
||||||
s := "%q"
|
s := "%q"
|
||||||
@ -136,8 +147,8 @@ func (dec *Decoder) Decode(v interface{}) (MetaData, error) {
|
|||||||
return MetaData{}, fmt.Errorf("toml: cannot decode to nil value of %q", reflect.TypeOf(v))
|
return MetaData{}, fmt.Errorf("toml: cannot decode to nil value of %q", reflect.TypeOf(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this is a supported type: struct, map, interface{}, or something
|
// Check if this is a supported type: struct, map, any, or something that
|
||||||
// that implements UnmarshalTOML or UnmarshalText.
|
// implements UnmarshalTOML or UnmarshalText.
|
||||||
rv = indirect(rv)
|
rv = indirect(rv)
|
||||||
rt := rv.Type()
|
rt := rv.Type()
|
||||||
if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map &&
|
if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map &&
|
||||||
@ -148,7 +159,7 @@ func (dec *Decoder) Decode(v interface{}) (MetaData, error) {
|
|||||||
|
|
||||||
// TODO: parser should read from io.Reader? Or at the very least, make it
|
// TODO: parser should read from io.Reader? Or at the very least, make it
|
||||||
// read from []byte rather than string
|
// read from []byte rather than string
|
||||||
data, err := ioutil.ReadAll(dec.r)
|
data, err := io.ReadAll(dec.r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return MetaData{}, err
|
return MetaData{}, err
|
||||||
}
|
}
|
||||||
@ -179,18 +190,31 @@ func (dec *Decoder) Decode(v interface{}) (MetaData, error) {
|
|||||||
// will only reflect keys that were decoded. Namely, any keys hidden behind a
|
// will only reflect keys that were decoded. Namely, any keys hidden behind a
|
||||||
// Primitive will be considered undecoded. Executing this method will update the
|
// Primitive will be considered undecoded. Executing this method will update the
|
||||||
// undecoded keys in the meta data. (See the example.)
|
// undecoded keys in the meta data. (See the example.)
|
||||||
func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error {
|
func (md *MetaData) PrimitiveDecode(primValue Primitive, v any) error {
|
||||||
md.context = primValue.context
|
md.context = primValue.context
|
||||||
defer func() { md.context = nil }()
|
defer func() { md.context = nil }()
|
||||||
return md.unify(primValue.undecoded, rvalue(v))
|
return md.unify(primValue.undecoded, rvalue(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// markDecodedRecursive is a helper to mark any key under the given tmap as
|
||||||
|
// decoded, recursing as needed
|
||||||
|
func markDecodedRecursive(md *MetaData, tmap map[string]any) {
|
||||||
|
for key := range tmap {
|
||||||
|
md.decoded[md.context.add(key).String()] = struct{}{}
|
||||||
|
if tmap, ok := tmap[key].(map[string]any); ok {
|
||||||
|
md.context = append(md.context, key)
|
||||||
|
markDecodedRecursive(md, tmap)
|
||||||
|
md.context = md.context[0 : len(md.context)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// unify performs a sort of type unification based on the structure of `rv`,
|
// unify performs a sort of type unification based on the structure of `rv`,
|
||||||
// which is the client representation.
|
// which is the client representation.
|
||||||
//
|
//
|
||||||
// Any type mismatch produces an error. Finding a type that we don't know
|
// Any type mismatch produces an error. Finding a type that we don't know
|
||||||
// how to handle produces an unsupported type error.
|
// how to handle produces an unsupported type error.
|
||||||
func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unify(data any, rv reflect.Value) error {
|
||||||
// Special case. Look for a `Primitive` value.
|
// Special case. Look for a `Primitive` value.
|
||||||
// TODO: #76 would make this superfluous after implemented.
|
// TODO: #76 would make this superfluous after implemented.
|
||||||
if rv.Type() == primitiveType {
|
if rv.Type() == primitiveType {
|
||||||
@ -207,7 +231,21 @@ func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
|
|||||||
|
|
||||||
rvi := rv.Interface()
|
rvi := rv.Interface()
|
||||||
if v, ok := rvi.(Unmarshaler); ok {
|
if v, ok := rvi.(Unmarshaler); ok {
|
||||||
return v.UnmarshalTOML(data)
|
err := v.UnmarshalTOML(data)
|
||||||
|
if err != nil {
|
||||||
|
return md.parseErr(err)
|
||||||
|
}
|
||||||
|
// Assume the Unmarshaler decoded everything, so mark all keys under
|
||||||
|
// this table as decoded.
|
||||||
|
if tmap, ok := data.(map[string]any); ok {
|
||||||
|
markDecodedRecursive(md, tmap)
|
||||||
|
}
|
||||||
|
if aot, ok := data.([]map[string]any); ok {
|
||||||
|
for _, tmap := range aot {
|
||||||
|
markDecodedRecursive(md, tmap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
if v, ok := rvi.(encoding.TextUnmarshaler); ok {
|
if v, ok := rvi.(encoding.TextUnmarshaler); ok {
|
||||||
return md.unifyText(data, v)
|
return md.unifyText(data, v)
|
||||||
@ -227,14 +265,6 @@ func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
|
|||||||
return md.unifyInt(data, rv)
|
return md.unifyInt(data, rv)
|
||||||
}
|
}
|
||||||
switch k {
|
switch k {
|
||||||
case reflect.Ptr:
|
|
||||||
elem := reflect.New(rv.Type().Elem())
|
|
||||||
err := md.unify(data, reflect.Indirect(elem))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
rv.Set(elem)
|
|
||||||
return nil
|
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
return md.unifyStruct(data, rv)
|
return md.unifyStruct(data, rv)
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
@ -258,14 +288,13 @@ func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
|
|||||||
return md.e("unsupported type %s", rv.Kind())
|
return md.e("unsupported type %s", rv.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyStruct(mapping any, rv reflect.Value) error {
|
||||||
tmap, ok := mapping.(map[string]interface{})
|
tmap, ok := mapping.(map[string]any)
|
||||||
if !ok {
|
if !ok {
|
||||||
if mapping == nil {
|
if mapping == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return md.e("type mismatch for %s: expected table but found %T",
|
return md.e("type mismatch for %s: expected table but found %s", rv.Type().String(), fmtType(mapping))
|
||||||
rv.Type().String(), mapping)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, datum := range tmap {
|
for key, datum := range tmap {
|
||||||
@ -304,14 +333,14 @@ func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyMap(mapping any, rv reflect.Value) error {
|
||||||
keyType := rv.Type().Key().Kind()
|
keyType := rv.Type().Key().Kind()
|
||||||
if keyType != reflect.String && keyType != reflect.Interface {
|
if keyType != reflect.String && keyType != reflect.Interface {
|
||||||
return fmt.Errorf("toml: cannot decode to a map with non-string key type (%s in %q)",
|
return fmt.Errorf("toml: cannot decode to a map with non-string key type (%s in %q)",
|
||||||
keyType, rv.Type())
|
keyType, rv.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
tmap, ok := mapping.(map[string]interface{})
|
tmap, ok := mapping.(map[string]any)
|
||||||
if !ok {
|
if !ok {
|
||||||
if tmap == nil {
|
if tmap == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -347,7 +376,7 @@ func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyArray(data any, rv reflect.Value) error {
|
||||||
datav := reflect.ValueOf(data)
|
datav := reflect.ValueOf(data)
|
||||||
if datav.Kind() != reflect.Slice {
|
if datav.Kind() != reflect.Slice {
|
||||||
if !datav.IsValid() {
|
if !datav.IsValid() {
|
||||||
@ -361,7 +390,7 @@ func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error {
|
|||||||
return md.unifySliceArray(datav, rv)
|
return md.unifySliceArray(datav, rv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifySlice(data any, rv reflect.Value) error {
|
||||||
datav := reflect.ValueOf(data)
|
datav := reflect.ValueOf(data)
|
||||||
if datav.Kind() != reflect.Slice {
|
if datav.Kind() != reflect.Slice {
|
||||||
if !datav.IsValid() {
|
if !datav.IsValid() {
|
||||||
@ -388,7 +417,7 @@ func (md *MetaData) unifySliceArray(data, rv reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyString(data any, rv reflect.Value) error {
|
||||||
_, ok := rv.Interface().(json.Number)
|
_, ok := rv.Interface().(json.Number)
|
||||||
if ok {
|
if ok {
|
||||||
if i, ok := data.(int64); ok {
|
if i, ok := data.(int64); ok {
|
||||||
@ -408,7 +437,7 @@ func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error {
|
|||||||
return md.badtype("string", data)
|
return md.badtype("string", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyFloat64(data any, rv reflect.Value) error {
|
||||||
rvk := rv.Kind()
|
rvk := rv.Kind()
|
||||||
|
|
||||||
if num, ok := data.(float64); ok {
|
if num, ok := data.(float64); ok {
|
||||||
@ -429,7 +458,7 @@ func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
|
|||||||
if num, ok := data.(int64); ok {
|
if num, ok := data.(int64); ok {
|
||||||
if (rvk == reflect.Float32 && (num < -maxSafeFloat32Int || num > maxSafeFloat32Int)) ||
|
if (rvk == reflect.Float32 && (num < -maxSafeFloat32Int || num > maxSafeFloat32Int)) ||
|
||||||
(rvk == reflect.Float64 && (num < -maxSafeFloat64Int || num > maxSafeFloat64Int)) {
|
(rvk == reflect.Float64 && (num < -maxSafeFloat64Int || num > maxSafeFloat64Int)) {
|
||||||
return md.parseErr(errParseRange{i: num, size: rvk.String()})
|
return md.parseErr(errUnsafeFloat{i: num, size: rvk.String()})
|
||||||
}
|
}
|
||||||
rv.SetFloat(float64(num))
|
rv.SetFloat(float64(num))
|
||||||
return nil
|
return nil
|
||||||
@ -438,7 +467,7 @@ func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
|
|||||||
return md.badtype("float", data)
|
return md.badtype("float", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyInt(data any, rv reflect.Value) error {
|
||||||
_, ok := rv.Interface().(time.Duration)
|
_, ok := rv.Interface().(time.Duration)
|
||||||
if ok {
|
if ok {
|
||||||
// Parse as string duration, and fall back to regular integer parsing
|
// Parse as string duration, and fall back to regular integer parsing
|
||||||
@ -481,7 +510,7 @@ func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyBool(data any, rv reflect.Value) error {
|
||||||
if b, ok := data.(bool); ok {
|
if b, ok := data.(bool); ok {
|
||||||
rv.SetBool(b)
|
rv.SetBool(b)
|
||||||
return nil
|
return nil
|
||||||
@ -489,12 +518,12 @@ func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error {
|
|||||||
return md.badtype("boolean", data)
|
return md.badtype("boolean", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyAnything(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyAnything(data any, rv reflect.Value) error {
|
||||||
rv.Set(reflect.ValueOf(data))
|
rv.Set(reflect.ValueOf(data))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) error {
|
func (md *MetaData) unifyText(data any, v encoding.TextUnmarshaler) error {
|
||||||
var s string
|
var s string
|
||||||
switch sdata := data.(type) {
|
switch sdata := data.(type) {
|
||||||
case Marshaler:
|
case Marshaler:
|
||||||
@ -523,27 +552,29 @@ func (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) erro
|
|||||||
return md.badtype("primitive (string-like)", data)
|
return md.badtype("primitive (string-like)", data)
|
||||||
}
|
}
|
||||||
if err := v.UnmarshalText([]byte(s)); err != nil {
|
if err := v.UnmarshalText([]byte(s)); err != nil {
|
||||||
return err
|
return md.parseErr(err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) badtype(dst string, data interface{}) error {
|
func (md *MetaData) badtype(dst string, data any) error {
|
||||||
return md.e("incompatible types: TOML value has type %T; destination has type %s", data, dst)
|
return md.e("incompatible types: TOML value has type %s; destination has type %s", fmtType(data), dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) parseErr(err error) error {
|
func (md *MetaData) parseErr(err error) error {
|
||||||
k := md.context.String()
|
k := md.context.String()
|
||||||
|
d := string(md.data)
|
||||||
return ParseError{
|
return ParseError{
|
||||||
LastKey: k,
|
Message: err.Error(),
|
||||||
Position: md.keyInfo[k].pos,
|
|
||||||
Line: md.keyInfo[k].pos.Line,
|
|
||||||
err: err,
|
err: err,
|
||||||
input: string(md.data),
|
LastKey: k,
|
||||||
|
Position: md.keyInfo[k].pos.withCol(d),
|
||||||
|
Line: md.keyInfo[k].pos.Line,
|
||||||
|
input: d,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) e(format string, args ...interface{}) error {
|
func (md *MetaData) e(format string, args ...any) error {
|
||||||
f := "toml: "
|
f := "toml: "
|
||||||
if len(md.context) > 0 {
|
if len(md.context) > 0 {
|
||||||
f = fmt.Sprintf("toml: (last key %q): ", md.context)
|
f = fmt.Sprintf("toml: (last key %q): ", md.context)
|
||||||
@ -556,7 +587,7 @@ func (md *MetaData) e(format string, args ...interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rvalue returns a reflect.Value of `v`. All pointers are resolved.
|
// rvalue returns a reflect.Value of `v`. All pointers are resolved.
|
||||||
func rvalue(v interface{}) reflect.Value {
|
func rvalue(v any) reflect.Value {
|
||||||
return indirect(reflect.ValueOf(v))
|
return indirect(reflect.ValueOf(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,3 +631,8 @@ func isUnifiable(rv reflect.Value) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fmt %T with "interface {}" replaced with "any", which is far more readable.
|
||||||
|
func fmtType(t any) string {
|
||||||
|
return strings.ReplaceAll(fmt.Sprintf("%T", t), "interface {}", "any")
|
||||||
|
}
|
||||||
|
19
vendor/github.com/BurntSushi/toml/decode_go116.go
generated
vendored
19
vendor/github.com/BurntSushi/toml/decode_go116.go
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
//go:build go1.16
|
|
||||||
// +build go1.16
|
|
||||||
|
|
||||||
package toml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/fs"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DecodeFS reads the contents of a file from [fs.FS] and decodes it with
|
|
||||||
// [Decode].
|
|
||||||
func DecodeFS(fsys fs.FS, path string, v interface{}) (MetaData, error) {
|
|
||||||
fp, err := fsys.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return MetaData{}, err
|
|
||||||
}
|
|
||||||
defer fp.Close()
|
|
||||||
return NewDecoder(fp).Decode(v)
|
|
||||||
}
|
|
18
vendor/github.com/BurntSushi/toml/deprecated.go
generated
vendored
18
vendor/github.com/BurntSushi/toml/deprecated.go
generated
vendored
@ -15,15 +15,15 @@ type TextMarshaler encoding.TextMarshaler
|
|||||||
// Deprecated: use encoding.TextUnmarshaler
|
// Deprecated: use encoding.TextUnmarshaler
|
||||||
type TextUnmarshaler encoding.TextUnmarshaler
|
type TextUnmarshaler encoding.TextUnmarshaler
|
||||||
|
|
||||||
// PrimitiveDecode is an alias for MetaData.PrimitiveDecode().
|
|
||||||
//
|
|
||||||
// Deprecated: use MetaData.PrimitiveDecode.
|
|
||||||
func PrimitiveDecode(primValue Primitive, v interface{}) error {
|
|
||||||
md := MetaData{decoded: make(map[string]struct{})}
|
|
||||||
return md.unify(primValue.undecoded, rvalue(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeReader is an alias for NewDecoder(r).Decode(v).
|
// DecodeReader is an alias for NewDecoder(r).Decode(v).
|
||||||
//
|
//
|
||||||
// Deprecated: use NewDecoder(reader).Decode(&value).
|
// Deprecated: use NewDecoder(reader).Decode(&value).
|
||||||
func DecodeReader(r io.Reader, v interface{}) (MetaData, error) { return NewDecoder(r).Decode(v) }
|
func DecodeReader(r io.Reader, v any) (MetaData, error) { return NewDecoder(r).Decode(v) }
|
||||||
|
|
||||||
|
// PrimitiveDecode is an alias for MetaData.PrimitiveDecode().
|
||||||
|
//
|
||||||
|
// Deprecated: use MetaData.PrimitiveDecode.
|
||||||
|
func PrimitiveDecode(primValue Primitive, v any) error {
|
||||||
|
md := MetaData{decoded: make(map[string]struct{})}
|
||||||
|
return md.unify(primValue.undecoded, rvalue(v))
|
||||||
|
}
|
||||||
|
3
vendor/github.com/BurntSushi/toml/doc.go
generated
vendored
3
vendor/github.com/BurntSushi/toml/doc.go
generated
vendored
@ -2,9 +2,6 @@
|
|||||||
//
|
//
|
||||||
// This package supports TOML v1.0.0, as specified at https://toml.io
|
// This package supports TOML v1.0.0, as specified at https://toml.io
|
||||||
//
|
//
|
||||||
// There is also support for delaying decoding with the Primitive type, and
|
|
||||||
// querying the set of keys in a TOML document with the MetaData type.
|
|
||||||
//
|
|
||||||
// The github.com/BurntSushi/toml/cmd/tomlv package implements a TOML validator,
|
// The github.com/BurntSushi/toml/cmd/tomlv package implements a TOML validator,
|
||||||
// and can be used to verify if TOML document is valid. It can also be used to
|
// and can be used to verify if TOML document is valid. It can also be used to
|
||||||
// print the type of each key.
|
// print the type of each key.
|
||||||
|
91
vendor/github.com/BurntSushi/toml/encode.go
generated
vendored
91
vendor/github.com/BurntSushi/toml/encode.go
generated
vendored
@ -2,6 +2,7 @@ package toml
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"encoding"
|
"encoding"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
@ -76,6 +77,17 @@ type Marshaler interface {
|
|||||||
MarshalTOML() ([]byte, error)
|
MarshalTOML() ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal returns a TOML representation of the Go value.
|
||||||
|
//
|
||||||
|
// See [Encoder] for a description of the encoding process.
|
||||||
|
func Marshal(v any) ([]byte, error) {
|
||||||
|
buff := new(bytes.Buffer)
|
||||||
|
if err := NewEncoder(buff).Encode(v); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buff.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Encoder encodes a Go to a TOML document.
|
// Encoder encodes a Go to a TOML document.
|
||||||
//
|
//
|
||||||
// The mapping between Go values and TOML values should be precisely the same as
|
// The mapping between Go values and TOML values should be precisely the same as
|
||||||
@ -115,26 +127,21 @@ type Marshaler interface {
|
|||||||
// NOTE: only exported keys are encoded due to the use of reflection. Unexported
|
// NOTE: only exported keys are encoded due to the use of reflection. Unexported
|
||||||
// keys are silently discarded.
|
// keys are silently discarded.
|
||||||
type Encoder struct {
|
type Encoder struct {
|
||||||
// String to use for a single indentation level; default is two spaces.
|
Indent string // string for a single indentation level; default is two spaces.
|
||||||
Indent string
|
hasWritten bool // written any output to w yet?
|
||||||
|
|
||||||
w *bufio.Writer
|
w *bufio.Writer
|
||||||
hasWritten bool // written any output to w yet?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEncoder create a new Encoder.
|
// NewEncoder create a new Encoder.
|
||||||
func NewEncoder(w io.Writer) *Encoder {
|
func NewEncoder(w io.Writer) *Encoder {
|
||||||
return &Encoder{
|
return &Encoder{w: bufio.NewWriter(w), Indent: " "}
|
||||||
w: bufio.NewWriter(w),
|
|
||||||
Indent: " ",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode writes a TOML representation of the Go value to the [Encoder]'s writer.
|
// Encode writes a TOML representation of the Go value to the [Encoder]'s writer.
|
||||||
//
|
//
|
||||||
// An error is returned if the value given cannot be encoded to a valid TOML
|
// An error is returned if the value given cannot be encoded to a valid TOML
|
||||||
// document.
|
// document.
|
||||||
func (enc *Encoder) Encode(v interface{}) error {
|
func (enc *Encoder) Encode(v any) error {
|
||||||
rv := eindirect(reflect.ValueOf(v))
|
rv := eindirect(reflect.ValueOf(v))
|
||||||
err := enc.safeEncode(Key([]string{}), rv)
|
err := enc.safeEncode(Key([]string{}), rv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -280,18 +287,30 @@ func (enc *Encoder) eElement(rv reflect.Value) {
|
|||||||
case reflect.Float32:
|
case reflect.Float32:
|
||||||
f := rv.Float()
|
f := rv.Float()
|
||||||
if math.IsNaN(f) {
|
if math.IsNaN(f) {
|
||||||
|
if math.Signbit(f) {
|
||||||
|
enc.wf("-")
|
||||||
|
}
|
||||||
enc.wf("nan")
|
enc.wf("nan")
|
||||||
} else if math.IsInf(f, 0) {
|
} else if math.IsInf(f, 0) {
|
||||||
enc.wf("%cinf", map[bool]byte{true: '-', false: '+'}[math.Signbit(f)])
|
if math.Signbit(f) {
|
||||||
|
enc.wf("-")
|
||||||
|
}
|
||||||
|
enc.wf("inf")
|
||||||
} else {
|
} else {
|
||||||
enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 32)))
|
enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 32)))
|
||||||
}
|
}
|
||||||
case reflect.Float64:
|
case reflect.Float64:
|
||||||
f := rv.Float()
|
f := rv.Float()
|
||||||
if math.IsNaN(f) {
|
if math.IsNaN(f) {
|
||||||
|
if math.Signbit(f) {
|
||||||
|
enc.wf("-")
|
||||||
|
}
|
||||||
enc.wf("nan")
|
enc.wf("nan")
|
||||||
} else if math.IsInf(f, 0) {
|
} else if math.IsInf(f, 0) {
|
||||||
enc.wf("%cinf", map[bool]byte{true: '-', false: '+'}[math.Signbit(f)])
|
if math.Signbit(f) {
|
||||||
|
enc.wf("-")
|
||||||
|
}
|
||||||
|
enc.wf("inf")
|
||||||
} else {
|
} else {
|
||||||
enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 64)))
|
enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 64)))
|
||||||
}
|
}
|
||||||
@ -304,7 +323,7 @@ func (enc *Encoder) eElement(rv reflect.Value) {
|
|||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
enc.eElement(rv.Elem())
|
enc.eElement(rv.Elem())
|
||||||
default:
|
default:
|
||||||
encPanic(fmt.Errorf("unexpected type: %T", rv.Interface()))
|
encPanic(fmt.Errorf("unexpected type: %s", fmtType(rv.Interface())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,31 +402,30 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {
|
|||||||
|
|
||||||
// Sort keys so that we have deterministic output. And write keys directly
|
// Sort keys so that we have deterministic output. And write keys directly
|
||||||
// underneath this key first, before writing sub-structs or sub-maps.
|
// underneath this key first, before writing sub-structs or sub-maps.
|
||||||
var mapKeysDirect, mapKeysSub []string
|
var mapKeysDirect, mapKeysSub []reflect.Value
|
||||||
for _, mapKey := range rv.MapKeys() {
|
for _, mapKey := range rv.MapKeys() {
|
||||||
k := mapKey.String()
|
|
||||||
if typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) {
|
if typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) {
|
||||||
mapKeysSub = append(mapKeysSub, k)
|
mapKeysSub = append(mapKeysSub, mapKey)
|
||||||
} else {
|
} else {
|
||||||
mapKeysDirect = append(mapKeysDirect, k)
|
mapKeysDirect = append(mapKeysDirect, mapKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var writeMapKeys = func(mapKeys []string, trailC bool) {
|
writeMapKeys := func(mapKeys []reflect.Value, trailC bool) {
|
||||||
sort.Strings(mapKeys)
|
sort.Slice(mapKeys, func(i, j int) bool { return mapKeys[i].String() < mapKeys[j].String() })
|
||||||
for i, mapKey := range mapKeys {
|
for i, mapKey := range mapKeys {
|
||||||
val := eindirect(rv.MapIndex(reflect.ValueOf(mapKey)))
|
val := eindirect(rv.MapIndex(mapKey))
|
||||||
if isNil(val) {
|
if isNil(val) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if inline {
|
if inline {
|
||||||
enc.writeKeyValue(Key{mapKey}, val, true)
|
enc.writeKeyValue(Key{mapKey.String()}, val, true)
|
||||||
if trailC || i != len(mapKeys)-1 {
|
if trailC || i != len(mapKeys)-1 {
|
||||||
enc.wf(", ")
|
enc.wf(", ")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
enc.encode(key.add(mapKey), val)
|
enc.encode(key.add(mapKey.String()), val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -422,8 +440,6 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const is32Bit = (32 << (^uint(0) >> 63)) == 32
|
|
||||||
|
|
||||||
func pointerTo(t reflect.Type) reflect.Type {
|
func pointerTo(t reflect.Type) reflect.Type {
|
||||||
if t.Kind() == reflect.Ptr {
|
if t.Kind() == reflect.Ptr {
|
||||||
return pointerTo(t.Elem())
|
return pointerTo(t.Elem())
|
||||||
@ -458,15 +474,14 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
|||||||
|
|
||||||
frv := eindirect(rv.Field(i))
|
frv := eindirect(rv.Field(i))
|
||||||
|
|
||||||
if is32Bit {
|
// Need to make a copy because ... ehm, I don't know why... I guess
|
||||||
// Copy so it works correct on 32bit archs; not clear why this
|
// allocating a new array can cause it to fail(?)
|
||||||
// is needed. See #314, and https://www.reddit.com/r/golang/comments/pnx8v4
|
//
|
||||||
// This also works fine on 64bit, but 32bit archs are somewhat
|
// Done for: https://github.com/BurntSushi/toml/issues/430
|
||||||
// rare and this is a wee bit faster.
|
// Previously only on 32bit for: https://github.com/BurntSushi/toml/issues/314
|
||||||
copyStart := make([]int, len(start))
|
copyStart := make([]int, len(start))
|
||||||
copy(copyStart, start)
|
copy(copyStart, start)
|
||||||
start = copyStart
|
start = copyStart
|
||||||
}
|
|
||||||
|
|
||||||
// Treat anonymous struct fields with tag names as though they are
|
// Treat anonymous struct fields with tag names as though they are
|
||||||
// not anonymous, like encoding/json does.
|
// not anonymous, like encoding/json does.
|
||||||
@ -488,7 +503,7 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
|||||||
}
|
}
|
||||||
addFields(rt, rv, nil)
|
addFields(rt, rv, nil)
|
||||||
|
|
||||||
writeFields := func(fields [][]int) {
|
writeFields := func(fields [][]int, totalFields int) {
|
||||||
for _, fieldIndex := range fields {
|
for _, fieldIndex := range fields {
|
||||||
fieldType := rt.FieldByIndex(fieldIndex)
|
fieldType := rt.FieldByIndex(fieldIndex)
|
||||||
fieldVal := rv.FieldByIndex(fieldIndex)
|
fieldVal := rv.FieldByIndex(fieldIndex)
|
||||||
@ -518,7 +533,7 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
|||||||
|
|
||||||
if inline {
|
if inline {
|
||||||
enc.writeKeyValue(Key{keyName}, fieldVal, true)
|
enc.writeKeyValue(Key{keyName}, fieldVal, true)
|
||||||
if fieldIndex[0] != len(fields)-1 {
|
if fieldIndex[0] != totalFields-1 {
|
||||||
enc.wf(", ")
|
enc.wf(", ")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -530,8 +545,10 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
|||||||
if inline {
|
if inline {
|
||||||
enc.wf("{")
|
enc.wf("{")
|
||||||
}
|
}
|
||||||
writeFields(fieldsDirect)
|
|
||||||
writeFields(fieldsSub)
|
l := len(fieldsDirect) + len(fieldsSub)
|
||||||
|
writeFields(fieldsDirect, l)
|
||||||
|
writeFields(fieldsSub, l)
|
||||||
if inline {
|
if inline {
|
||||||
enc.wf("}")
|
enc.wf("}")
|
||||||
}
|
}
|
||||||
@ -712,7 +729,7 @@ func (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (enc *Encoder) wf(format string, v ...interface{}) {
|
func (enc *Encoder) wf(format string, v ...any) {
|
||||||
_, err := fmt.Fprintf(enc.w, format, v...)
|
_, err := fmt.Fprintf(enc.w, format, v...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
encPanic(err)
|
encPanic(err)
|
||||||
|
168
vendor/github.com/BurntSushi/toml/error.go
generated
vendored
168
vendor/github.com/BurntSushi/toml/error.go
generated
vendored
@ -67,21 +67,36 @@ type ParseError struct {
|
|||||||
// Position of an error.
|
// Position of an error.
|
||||||
type Position struct {
|
type Position struct {
|
||||||
Line int // Line number, starting at 1.
|
Line int // Line number, starting at 1.
|
||||||
|
Col int // Error column, starting at 1.
|
||||||
Start int // Start of error, as byte offset starting at 0.
|
Start int // Start of error, as byte offset starting at 0.
|
||||||
Len int // Lenght in bytes.
|
Len int // Length of the error in bytes.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Position) withCol(tomlFile string) Position {
|
||||||
|
var (
|
||||||
|
pos int
|
||||||
|
lines = strings.Split(tomlFile, "\n")
|
||||||
|
)
|
||||||
|
for i := range lines {
|
||||||
|
ll := len(lines[i]) + 1 // +1 for the removed newline
|
||||||
|
if pos+ll >= p.Start {
|
||||||
|
p.Col = p.Start - pos + 1
|
||||||
|
if p.Col < 1 { // Should never happen, but just in case.
|
||||||
|
p.Col = 1
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
pos += ll
|
||||||
|
}
|
||||||
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pe ParseError) Error() string {
|
func (pe ParseError) Error() string {
|
||||||
msg := pe.Message
|
|
||||||
if msg == "" { // Error from errorf()
|
|
||||||
msg = pe.err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
if pe.LastKey == "" {
|
if pe.LastKey == "" {
|
||||||
return fmt.Sprintf("toml: line %d: %s", pe.Position.Line, msg)
|
return fmt.Sprintf("toml: line %d: %s", pe.Position.Line, pe.Message)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("toml: line %d (last key %q): %s",
|
return fmt.Sprintf("toml: line %d (last key %q): %s",
|
||||||
pe.Position.Line, pe.LastKey, msg)
|
pe.Position.Line, pe.LastKey, pe.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrorWithPosition returns the error with detailed location context.
|
// ErrorWithPosition returns the error with detailed location context.
|
||||||
@ -92,35 +107,37 @@ func (pe ParseError) ErrorWithPosition() string {
|
|||||||
return pe.Error()
|
return pe.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
lines = strings.Split(pe.input, "\n")
|
|
||||||
col = pe.column(lines)
|
|
||||||
b = new(strings.Builder)
|
|
||||||
)
|
|
||||||
|
|
||||||
msg := pe.Message
|
|
||||||
if msg == "" {
|
|
||||||
msg = pe.err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: don't show control characters as literals? This may not show up
|
// TODO: don't show control characters as literals? This may not show up
|
||||||
// well everywhere.
|
// well everywhere.
|
||||||
|
|
||||||
|
var (
|
||||||
|
lines = strings.Split(pe.input, "\n")
|
||||||
|
b = new(strings.Builder)
|
||||||
|
)
|
||||||
if pe.Position.Len == 1 {
|
if pe.Position.Len == 1 {
|
||||||
fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d:\n\n",
|
fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d:\n\n",
|
||||||
msg, pe.Position.Line, col+1)
|
pe.Message, pe.Position.Line, pe.Position.Col)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d-%d:\n\n",
|
fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d-%d:\n\n",
|
||||||
msg, pe.Position.Line, col, col+pe.Position.Len)
|
pe.Message, pe.Position.Line, pe.Position.Col, pe.Position.Col+pe.Position.Len-1)
|
||||||
}
|
}
|
||||||
if pe.Position.Line > 2 {
|
if pe.Position.Line > 2 {
|
||||||
fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-2, lines[pe.Position.Line-3])
|
fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-2, expandTab(lines[pe.Position.Line-3]))
|
||||||
}
|
}
|
||||||
if pe.Position.Line > 1 {
|
if pe.Position.Line > 1 {
|
||||||
fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-1, lines[pe.Position.Line-2])
|
fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-1, expandTab(lines[pe.Position.Line-2]))
|
||||||
}
|
}
|
||||||
fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line, lines[pe.Position.Line-1])
|
|
||||||
fmt.Fprintf(b, "% 10s%s%s\n", "", strings.Repeat(" ", col), strings.Repeat("^", pe.Position.Len))
|
/// Expand tabs, so that the ^^^s are at the correct position, but leave
|
||||||
|
/// "column 10-13" intact. Adjusting this to the visual column would be
|
||||||
|
/// better, but we don't know the tabsize of the user in their editor, which
|
||||||
|
/// can be 8, 4, 2, or something else. We can't know. So leaving it as the
|
||||||
|
/// character index is probably the "most correct".
|
||||||
|
expanded := expandTab(lines[pe.Position.Line-1])
|
||||||
|
diff := len(expanded) - len(lines[pe.Position.Line-1])
|
||||||
|
|
||||||
|
fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line, expanded)
|
||||||
|
fmt.Fprintf(b, "% 10s%s%s\n", "", strings.Repeat(" ", pe.Position.Col-1+diff), strings.Repeat("^", pe.Position.Len))
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,34 +159,47 @@ func (pe ParseError) ErrorWithUsage() string {
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pe ParseError) column(lines []string) int {
|
func expandTab(s string) string {
|
||||||
var pos, col int
|
var (
|
||||||
for i := range lines {
|
b strings.Builder
|
||||||
ll := len(lines[i]) + 1 // +1 for the removed newline
|
l int
|
||||||
if pos+ll >= pe.Position.Start {
|
fill = func(n int) string {
|
||||||
col = pe.Position.Start - pos
|
b := make([]byte, n)
|
||||||
if col < 0 { // Should never happen, but just in case.
|
for i := range b {
|
||||||
col = 0
|
b[i] = ' '
|
||||||
}
|
}
|
||||||
break
|
return string(b)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
b.Grow(len(s))
|
||||||
|
for _, r := range s {
|
||||||
|
switch r {
|
||||||
|
case '\t':
|
||||||
|
tw := 8 - l%8
|
||||||
|
b.WriteString(fill(tw))
|
||||||
|
l += tw
|
||||||
|
default:
|
||||||
|
b.WriteRune(r)
|
||||||
|
l += 1
|
||||||
}
|
}
|
||||||
pos += ll
|
|
||||||
}
|
}
|
||||||
|
return b.String()
|
||||||
return col
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
errLexControl struct{ r rune }
|
errLexControl struct{ r rune }
|
||||||
errLexEscape struct{ r rune }
|
errLexEscape struct{ r rune }
|
||||||
errLexUTF8 struct{ b byte }
|
errLexUTF8 struct{ b byte }
|
||||||
errLexInvalidNum struct{ v string }
|
errParseDate struct{ v string }
|
||||||
errLexInvalidDate struct{ v string }
|
|
||||||
errLexInlineTableNL struct{}
|
errLexInlineTableNL struct{}
|
||||||
errLexStringNL struct{}
|
errLexStringNL struct{}
|
||||||
errParseRange struct {
|
errParseRange struct {
|
||||||
i interface{} // int or float
|
i any // int or float
|
||||||
size string // "int64", "uint16", etc.
|
size string // "int64", "uint16", etc.
|
||||||
|
}
|
||||||
|
errUnsafeFloat struct {
|
||||||
|
i interface{} // float32 or float64
|
||||||
|
size string // "float32" or "float64"
|
||||||
}
|
}
|
||||||
errParseDuration struct{ d string }
|
errParseDuration struct{ d string }
|
||||||
)
|
)
|
||||||
@ -183,18 +213,20 @@ func (e errLexEscape) Error() string { return fmt.Sprintf(`invalid escape
|
|||||||
func (e errLexEscape) Usage() string { return usageEscape }
|
func (e errLexEscape) Usage() string { return usageEscape }
|
||||||
func (e errLexUTF8) Error() string { return fmt.Sprintf("invalid UTF-8 byte: 0x%02x", e.b) }
|
func (e errLexUTF8) Error() string { return fmt.Sprintf("invalid UTF-8 byte: 0x%02x", e.b) }
|
||||||
func (e errLexUTF8) Usage() string { return "" }
|
func (e errLexUTF8) Usage() string { return "" }
|
||||||
func (e errLexInvalidNum) Error() string { return fmt.Sprintf("invalid number: %q", e.v) }
|
func (e errParseDate) Error() string { return fmt.Sprintf("invalid datetime: %q", e.v) }
|
||||||
func (e errLexInvalidNum) Usage() string { return "" }
|
func (e errParseDate) Usage() string { return usageDate }
|
||||||
func (e errLexInvalidDate) Error() string { return fmt.Sprintf("invalid date: %q", e.v) }
|
|
||||||
func (e errLexInvalidDate) Usage() string { return "" }
|
|
||||||
func (e errLexInlineTableNL) Error() string { return "newlines not allowed within inline tables" }
|
func (e errLexInlineTableNL) Error() string { return "newlines not allowed within inline tables" }
|
||||||
func (e errLexInlineTableNL) Usage() string { return usageInlineNewline }
|
func (e errLexInlineTableNL) Usage() string { return usageInlineNewline }
|
||||||
func (e errLexStringNL) Error() string { return "strings cannot contain newlines" }
|
func (e errLexStringNL) Error() string { return "strings cannot contain newlines" }
|
||||||
func (e errLexStringNL) Usage() string { return usageStringNewline }
|
func (e errLexStringNL) Usage() string { return usageStringNewline }
|
||||||
func (e errParseRange) Error() string { return fmt.Sprintf("%v is out of range for %s", e.i, e.size) }
|
func (e errParseRange) Error() string { return fmt.Sprintf("%v is out of range for %s", e.i, e.size) }
|
||||||
func (e errParseRange) Usage() string { return usageIntOverflow }
|
func (e errParseRange) Usage() string { return usageIntOverflow }
|
||||||
func (e errParseDuration) Error() string { return fmt.Sprintf("invalid duration: %q", e.d) }
|
func (e errUnsafeFloat) Error() string {
|
||||||
func (e errParseDuration) Usage() string { return usageDuration }
|
return fmt.Sprintf("%v is out of the safe %s range", e.i, e.size)
|
||||||
|
}
|
||||||
|
func (e errUnsafeFloat) Usage() string { return usageUnsafeFloat }
|
||||||
|
func (e errParseDuration) Error() string { return fmt.Sprintf("invalid duration: %q", e.d) }
|
||||||
|
func (e errParseDuration) Usage() string { return usageDuration }
|
||||||
|
|
||||||
const usageEscape = `
|
const usageEscape = `
|
||||||
A '\' inside a "-delimited string is interpreted as an escape character.
|
A '\' inside a "-delimited string is interpreted as an escape character.
|
||||||
@ -251,19 +283,35 @@ bug in the program that uses too small of an integer.
|
|||||||
The maximum and minimum values are:
|
The maximum and minimum values are:
|
||||||
|
|
||||||
size │ lowest │ highest
|
size │ lowest │ highest
|
||||||
───────┼────────────────┼──────────
|
───────┼────────────────┼──────────────
|
||||||
int8 │ -128 │ 127
|
int8 │ -128 │ 127
|
||||||
int16 │ -32,768 │ 32,767
|
int16 │ -32,768 │ 32,767
|
||||||
int32 │ -2,147,483,648 │ 2,147,483,647
|
int32 │ -2,147,483,648 │ 2,147,483,647
|
||||||
int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷
|
int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷
|
||||||
uint8 │ 0 │ 255
|
uint8 │ 0 │ 255
|
||||||
uint16 │ 0 │ 65535
|
uint16 │ 0 │ 65,535
|
||||||
uint32 │ 0 │ 4294967295
|
uint32 │ 0 │ 4,294,967,295
|
||||||
uint64 │ 0 │ 1.8 × 10¹⁸
|
uint64 │ 0 │ 1.8 × 10¹⁸
|
||||||
|
|
||||||
int refers to int32 on 32-bit systems and int64 on 64-bit systems.
|
int refers to int32 on 32-bit systems and int64 on 64-bit systems.
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const usageUnsafeFloat = `
|
||||||
|
This number is outside of the "safe" range for floating point numbers; whole
|
||||||
|
(non-fractional) numbers outside the below range can not always be represented
|
||||||
|
accurately in a float, leading to some loss of accuracy.
|
||||||
|
|
||||||
|
Explicitly mark a number as a fractional unit by adding ".0", which will incur
|
||||||
|
some loss of accuracy; for example:
|
||||||
|
|
||||||
|
f = 2_000_000_000.0
|
||||||
|
|
||||||
|
Accuracy ranges:
|
||||||
|
|
||||||
|
float32 = 16,777,215
|
||||||
|
float64 = 9,007,199,254,740,991
|
||||||
|
`
|
||||||
|
|
||||||
const usageDuration = `
|
const usageDuration = `
|
||||||
A duration must be as "number<unit>", without any spaces. Valid units are:
|
A duration must be as "number<unit>", without any spaces. Valid units are:
|
||||||
|
|
||||||
@ -277,3 +325,23 @@ A duration must be as "number<unit>", without any spaces. Valid units are:
|
|||||||
You can combine multiple units; for example "5m10s" for 5 minutes and 10
|
You can combine multiple units; for example "5m10s" for 5 minutes and 10
|
||||||
seconds.
|
seconds.
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const usageDate = `
|
||||||
|
A TOML datetime must be in one of the following formats:
|
||||||
|
|
||||||
|
2006-01-02T15:04:05Z07:00 Date and time, with timezone.
|
||||||
|
2006-01-02T15:04:05 Date and time, but without timezone.
|
||||||
|
2006-01-02 Date without a time or timezone.
|
||||||
|
15:04:05 Just a time, without any timezone.
|
||||||
|
|
||||||
|
Seconds may optionally have a fraction, up to nanosecond precision:
|
||||||
|
|
||||||
|
15:04:05.123
|
||||||
|
15:04:05.856018510
|
||||||
|
`
|
||||||
|
|
||||||
|
// TOML 1.1:
|
||||||
|
// The seconds part in times is optional, and may be omitted:
|
||||||
|
// 2006-01-02T15:04Z07:00
|
||||||
|
// 2006-01-02T15:04
|
||||||
|
// 15:04
|
||||||
|
83
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
83
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
@ -17,6 +17,7 @@ const (
|
|||||||
itemEOF
|
itemEOF
|
||||||
itemText
|
itemText
|
||||||
itemString
|
itemString
|
||||||
|
itemStringEsc
|
||||||
itemRawString
|
itemRawString
|
||||||
itemMultilineString
|
itemMultilineString
|
||||||
itemRawMultilineString
|
itemRawMultilineString
|
||||||
@ -53,6 +54,7 @@ type lexer struct {
|
|||||||
state stateFn
|
state stateFn
|
||||||
items chan item
|
items chan item
|
||||||
tomlNext bool
|
tomlNext bool
|
||||||
|
esc bool
|
||||||
|
|
||||||
// Allow for backing up up to 4 runes. This is necessary because TOML
|
// Allow for backing up up to 4 runes. This is necessary because TOML
|
||||||
// contains 3-rune tokens (""" and ''').
|
// contains 3-rune tokens (""" and ''').
|
||||||
@ -164,7 +166,7 @@ func (lx *lexer) next() (r rune) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
r, w := utf8.DecodeRuneInString(lx.input[lx.pos:])
|
r, w := utf8.DecodeRuneInString(lx.input[lx.pos:])
|
||||||
if r == utf8.RuneError {
|
if r == utf8.RuneError && w == 1 {
|
||||||
lx.error(errLexUTF8{lx.input[lx.pos]})
|
lx.error(errLexUTF8{lx.input[lx.pos]})
|
||||||
return utf8.RuneError
|
return utf8.RuneError
|
||||||
}
|
}
|
||||||
@ -270,10 +272,12 @@ func (lx *lexer) errorPos(start, length int, err error) stateFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// errorf is like error, and creates a new error.
|
// errorf is like error, and creates a new error.
|
||||||
func (lx *lexer) errorf(format string, values ...interface{}) stateFn {
|
func (lx *lexer) errorf(format string, values ...any) stateFn {
|
||||||
if lx.atEOF {
|
if lx.atEOF {
|
||||||
pos := lx.getPos()
|
pos := lx.getPos()
|
||||||
pos.Line--
|
if lx.pos >= 1 && lx.input[lx.pos-1] == '\n' {
|
||||||
|
pos.Line--
|
||||||
|
}
|
||||||
pos.Len = 1
|
pos.Len = 1
|
||||||
pos.Start = lx.pos - 1
|
pos.Start = lx.pos - 1
|
||||||
lx.items <- item{typ: itemError, pos: pos, err: fmt.Errorf(format, values...)}
|
lx.items <- item{typ: itemError, pos: pos, err: fmt.Errorf(format, values...)}
|
||||||
@ -333,9 +337,7 @@ func lexTopEnd(lx *lexer) stateFn {
|
|||||||
lx.emit(itemEOF)
|
lx.emit(itemEOF)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return lx.errorf(
|
return lx.errorf("expected a top-level item to end with a newline, comment, or EOF, but got %q instead", r)
|
||||||
"expected a top-level item to end with a newline, comment, or EOF, but got %q instead",
|
|
||||||
r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// lexTable lexes the beginning of a table. Namely, it makes sure that
|
// lexTable lexes the beginning of a table. Namely, it makes sure that
|
||||||
@ -492,6 +494,9 @@ func lexKeyEnd(lx *lexer) stateFn {
|
|||||||
lx.emit(itemKeyEnd)
|
lx.emit(itemKeyEnd)
|
||||||
return lexSkip(lx, lexValue)
|
return lexSkip(lx, lexValue)
|
||||||
default:
|
default:
|
||||||
|
if r == '\n' {
|
||||||
|
return lx.errorPrevLine(fmt.Errorf("expected '.' or '=', but got %q instead", r))
|
||||||
|
}
|
||||||
return lx.errorf("expected '.' or '=', but got %q instead", r)
|
return lx.errorf("expected '.' or '=', but got %q instead", r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -560,6 +565,9 @@ func lexValue(lx *lexer) stateFn {
|
|||||||
if r == eof {
|
if r == eof {
|
||||||
return lx.errorf("unexpected EOF; expected value")
|
return lx.errorf("unexpected EOF; expected value")
|
||||||
}
|
}
|
||||||
|
if r == '\n' {
|
||||||
|
return lx.errorPrevLine(fmt.Errorf("expected value but found %q instead", r))
|
||||||
|
}
|
||||||
return lx.errorf("expected value but found %q instead", r)
|
return lx.errorf("expected value but found %q instead", r)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,7 +706,12 @@ func lexString(lx *lexer) stateFn {
|
|||||||
return lexStringEscape
|
return lexStringEscape
|
||||||
case r == '"':
|
case r == '"':
|
||||||
lx.backup()
|
lx.backup()
|
||||||
lx.emit(itemString)
|
if lx.esc {
|
||||||
|
lx.esc = false
|
||||||
|
lx.emit(itemStringEsc)
|
||||||
|
} else {
|
||||||
|
lx.emit(itemString)
|
||||||
|
}
|
||||||
lx.next()
|
lx.next()
|
||||||
lx.ignore()
|
lx.ignore()
|
||||||
return lx.pop()
|
return lx.pop()
|
||||||
@ -748,6 +761,7 @@ func lexMultilineString(lx *lexer) stateFn {
|
|||||||
lx.backup() /// backup: don't include the """ in the item.
|
lx.backup() /// backup: don't include the """ in the item.
|
||||||
lx.backup()
|
lx.backup()
|
||||||
lx.backup()
|
lx.backup()
|
||||||
|
lx.esc = false
|
||||||
lx.emit(itemMultilineString)
|
lx.emit(itemMultilineString)
|
||||||
lx.next() /// Read over ''' again and discard it.
|
lx.next() /// Read over ''' again and discard it.
|
||||||
lx.next()
|
lx.next()
|
||||||
@ -837,6 +851,7 @@ func lexMultilineStringEscape(lx *lexer) stateFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func lexStringEscape(lx *lexer) stateFn {
|
func lexStringEscape(lx *lexer) stateFn {
|
||||||
|
lx.esc = true
|
||||||
r := lx.next()
|
r := lx.next()
|
||||||
switch r {
|
switch r {
|
||||||
case 'e':
|
case 'e':
|
||||||
@ -879,10 +894,8 @@ func lexHexEscape(lx *lexer) stateFn {
|
|||||||
var r rune
|
var r rune
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
r = lx.next()
|
r = lx.next()
|
||||||
if !isHexadecimal(r) {
|
if !isHex(r) {
|
||||||
return lx.errorf(
|
return lx.errorf(`expected two hexadecimal digits after '\x', but got %q instead`, lx.current())
|
||||||
`expected two hexadecimal digits after '\x', but got %q instead`,
|
|
||||||
lx.current())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lx.pop()
|
return lx.pop()
|
||||||
@ -892,10 +905,8 @@ func lexShortUnicodeEscape(lx *lexer) stateFn {
|
|||||||
var r rune
|
var r rune
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
r = lx.next()
|
r = lx.next()
|
||||||
if !isHexadecimal(r) {
|
if !isHex(r) {
|
||||||
return lx.errorf(
|
return lx.errorf(`expected four hexadecimal digits after '\u', but got %q instead`, lx.current())
|
||||||
`expected four hexadecimal digits after '\u', but got %q instead`,
|
|
||||||
lx.current())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lx.pop()
|
return lx.pop()
|
||||||
@ -905,10 +916,8 @@ func lexLongUnicodeEscape(lx *lexer) stateFn {
|
|||||||
var r rune
|
var r rune
|
||||||
for i := 0; i < 8; i++ {
|
for i := 0; i < 8; i++ {
|
||||||
r = lx.next()
|
r = lx.next()
|
||||||
if !isHexadecimal(r) {
|
if !isHex(r) {
|
||||||
return lx.errorf(
|
return lx.errorf(`expected eight hexadecimal digits after '\U', but got %q instead`, lx.current())
|
||||||
`expected eight hexadecimal digits after '\U', but got %q instead`,
|
|
||||||
lx.current())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lx.pop()
|
return lx.pop()
|
||||||
@ -975,7 +984,7 @@ func lexDatetime(lx *lexer) stateFn {
|
|||||||
// lexHexInteger consumes a hexadecimal integer after seeing the '0x' prefix.
|
// lexHexInteger consumes a hexadecimal integer after seeing the '0x' prefix.
|
||||||
func lexHexInteger(lx *lexer) stateFn {
|
func lexHexInteger(lx *lexer) stateFn {
|
||||||
r := lx.next()
|
r := lx.next()
|
||||||
if isHexadecimal(r) {
|
if isHex(r) {
|
||||||
return lexHexInteger
|
return lexHexInteger
|
||||||
}
|
}
|
||||||
switch r {
|
switch r {
|
||||||
@ -1109,8 +1118,8 @@ func lexBaseNumberOrDate(lx *lexer) stateFn {
|
|||||||
return lexOctalInteger
|
return lexOctalInteger
|
||||||
case 'x':
|
case 'x':
|
||||||
r = lx.peek()
|
r = lx.peek()
|
||||||
if !isHexadecimal(r) {
|
if !isHex(r) {
|
||||||
lx.errorf("not a hexidecimal number: '%s%c'", lx.current(), r)
|
lx.errorf("not a hexadecimal number: '%s%c'", lx.current(), r)
|
||||||
}
|
}
|
||||||
return lexHexInteger
|
return lexHexInteger
|
||||||
}
|
}
|
||||||
@ -1207,7 +1216,7 @@ func (itype itemType) String() string {
|
|||||||
return "EOF"
|
return "EOF"
|
||||||
case itemText:
|
case itemText:
|
||||||
return "Text"
|
return "Text"
|
||||||
case itemString, itemRawString, itemMultilineString, itemRawMultilineString:
|
case itemString, itemStringEsc, itemRawString, itemMultilineString, itemRawMultilineString:
|
||||||
return "String"
|
return "String"
|
||||||
case itemBool:
|
case itemBool:
|
||||||
return "Bool"
|
return "Bool"
|
||||||
@ -1240,7 +1249,7 @@ func (itype itemType) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (item item) String() string {
|
func (item item) String() string {
|
||||||
return fmt.Sprintf("(%s, %s)", item.typ.String(), item.val)
|
return fmt.Sprintf("(%s, %s)", item.typ, item.val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isWhitespace(r rune) bool { return r == '\t' || r == ' ' }
|
func isWhitespace(r rune) bool { return r == '\t' || r == ' ' }
|
||||||
@ -1256,28 +1265,8 @@ func isControl(r rune) bool { // Control characters except \t, \r, \n
|
|||||||
func isDigit(r rune) bool { return r >= '0' && r <= '9' }
|
func isDigit(r rune) bool { return r >= '0' && r <= '9' }
|
||||||
func isBinary(r rune) bool { return r == '0' || r == '1' }
|
func isBinary(r rune) bool { return r == '0' || r == '1' }
|
||||||
func isOctal(r rune) bool { return r >= '0' && r <= '7' }
|
func isOctal(r rune) bool { return r >= '0' && r <= '7' }
|
||||||
func isHexadecimal(r rune) bool {
|
func isHex(r rune) bool { return (r >= '0' && r <= '9') || (r|0x20 >= 'a' && r|0x20 <= 'f') }
|
||||||
return (r >= '0' && r <= '9') || (r >= 'a' && r <= 'f') || (r >= 'A' && r <= 'F')
|
|
||||||
}
|
|
||||||
|
|
||||||
func isBareKeyChar(r rune, tomlNext bool) bool {
|
func isBareKeyChar(r rune, tomlNext bool) bool {
|
||||||
if tomlNext {
|
return (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') ||
|
||||||
return (r >= 'A' && r <= 'Z') ||
|
(r >= '0' && r <= '9') || r == '_' || r == '-'
|
||||||
(r >= 'a' && r <= 'z') ||
|
|
||||||
(r >= '0' && r <= '9') ||
|
|
||||||
r == '_' || r == '-' ||
|
|
||||||
r == 0xb2 || r == 0xb3 || r == 0xb9 || (r >= 0xbc && r <= 0xbe) ||
|
|
||||||
(r >= 0xc0 && r <= 0xd6) || (r >= 0xd8 && r <= 0xf6) || (r >= 0xf8 && r <= 0x037d) ||
|
|
||||||
(r >= 0x037f && r <= 0x1fff) ||
|
|
||||||
(r >= 0x200c && r <= 0x200d) || (r >= 0x203f && r <= 0x2040) ||
|
|
||||||
(r >= 0x2070 && r <= 0x218f) || (r >= 0x2460 && r <= 0x24ff) ||
|
|
||||||
(r >= 0x2c00 && r <= 0x2fef) || (r >= 0x3001 && r <= 0xd7ff) ||
|
|
||||||
(r >= 0xf900 && r <= 0xfdcf) || (r >= 0xfdf0 && r <= 0xfffd) ||
|
|
||||||
(r >= 0x10000 && r <= 0xeffff)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (r >= 'A' && r <= 'Z') ||
|
|
||||||
(r >= 'a' && r <= 'z') ||
|
|
||||||
(r >= '0' && r <= '9') ||
|
|
||||||
r == '_' || r == '-'
|
|
||||||
}
|
}
|
||||||
|
46
vendor/github.com/BurntSushi/toml/meta.go
generated
vendored
46
vendor/github.com/BurntSushi/toml/meta.go
generated
vendored
@ -13,7 +13,7 @@ type MetaData struct {
|
|||||||
context Key // Used only during decoding.
|
context Key // Used only during decoding.
|
||||||
|
|
||||||
keyInfo map[string]keyInfo
|
keyInfo map[string]keyInfo
|
||||||
mapping map[string]interface{}
|
mapping map[string]any
|
||||||
keys []Key
|
keys []Key
|
||||||
decoded map[string]struct{}
|
decoded map[string]struct{}
|
||||||
data []byte // Input file; for errors.
|
data []byte // Input file; for errors.
|
||||||
@ -31,12 +31,12 @@ func (md *MetaData) IsDefined(key ...string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
hash map[string]interface{}
|
hash map[string]any
|
||||||
ok bool
|
ok bool
|
||||||
hashOrVal interface{} = md.mapping
|
hashOrVal any = md.mapping
|
||||||
)
|
)
|
||||||
for _, k := range key {
|
for _, k := range key {
|
||||||
if hash, ok = hashOrVal.(map[string]interface{}); !ok {
|
if hash, ok = hashOrVal.(map[string]any); !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if hashOrVal, ok = hash[k]; !ok {
|
if hashOrVal, ok = hash[k]; !ok {
|
||||||
@ -94,28 +94,52 @@ func (md *MetaData) Undecoded() []Key {
|
|||||||
type Key []string
|
type Key []string
|
||||||
|
|
||||||
func (k Key) String() string {
|
func (k Key) String() string {
|
||||||
ss := make([]string, len(k))
|
// This is called quite often, so it's a bit funky to make it faster.
|
||||||
for i := range k {
|
var b strings.Builder
|
||||||
ss[i] = k.maybeQuoted(i)
|
b.Grow(len(k) * 25)
|
||||||
|
outer:
|
||||||
|
for i, kk := range k {
|
||||||
|
if i > 0 {
|
||||||
|
b.WriteByte('.')
|
||||||
|
}
|
||||||
|
if kk == "" {
|
||||||
|
b.WriteString(`""`)
|
||||||
|
} else {
|
||||||
|
for _, r := range kk {
|
||||||
|
// "Inline" isBareKeyChar
|
||||||
|
if !((r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || r == '-') {
|
||||||
|
b.WriteByte('"')
|
||||||
|
b.WriteString(dblQuotedReplacer.Replace(kk))
|
||||||
|
b.WriteByte('"')
|
||||||
|
continue outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.WriteString(kk)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(ss, ".")
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k Key) maybeQuoted(i int) string {
|
func (k Key) maybeQuoted(i int) string {
|
||||||
if k[i] == "" {
|
if k[i] == "" {
|
||||||
return `""`
|
return `""`
|
||||||
}
|
}
|
||||||
for _, c := range k[i] {
|
for _, r := range k[i] {
|
||||||
if !isBareKeyChar(c, false) {
|
if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || r == '-' {
|
||||||
return `"` + dblQuotedReplacer.Replace(k[i]) + `"`
|
continue
|
||||||
}
|
}
|
||||||
|
return `"` + dblQuotedReplacer.Replace(k[i]) + `"`
|
||||||
}
|
}
|
||||||
return k[i]
|
return k[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Like append(), but only increase the cap by 1.
|
||||||
func (k Key) add(piece string) Key {
|
func (k Key) add(piece string) Key {
|
||||||
newKey := make(Key, len(k)+1)
|
newKey := make(Key, len(k)+1)
|
||||||
copy(newKey, k)
|
copy(newKey, k)
|
||||||
newKey[len(k)] = piece
|
newKey[len(k)] = piece
|
||||||
return newKey
|
return newKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k Key) parent() Key { return k[:len(k)-1] } // all except the last piece.
|
||||||
|
func (k Key) last() string { return k[len(k)-1] } // last piece of this key.
|
||||||
|
282
vendor/github.com/BurntSushi/toml/parse.go
generated
vendored
282
vendor/github.com/BurntSushi/toml/parse.go
generated
vendored
@ -2,6 +2,7 @@ package toml
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -20,9 +21,9 @@ type parser struct {
|
|||||||
|
|
||||||
ordered []Key // List of keys in the order that they appear in the TOML data.
|
ordered []Key // List of keys in the order that they appear in the TOML data.
|
||||||
|
|
||||||
keyInfo map[string]keyInfo // Map keyname → info about the TOML key.
|
keyInfo map[string]keyInfo // Map keyname → info about the TOML key.
|
||||||
mapping map[string]interface{} // Map keyname → key value.
|
mapping map[string]any // Map keyname → key value.
|
||||||
implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names").
|
implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names").
|
||||||
}
|
}
|
||||||
|
|
||||||
type keyInfo struct {
|
type keyInfo struct {
|
||||||
@ -63,7 +64,7 @@ func parse(data string) (p *parser, err error) {
|
|||||||
if i := strings.IndexRune(data[:ex], 0); i > -1 {
|
if i := strings.IndexRune(data[:ex], 0); i > -1 {
|
||||||
return nil, ParseError{
|
return nil, ParseError{
|
||||||
Message: "files cannot contain NULL bytes; probably using UTF-16; TOML files must be UTF-8",
|
Message: "files cannot contain NULL bytes; probably using UTF-16; TOML files must be UTF-8",
|
||||||
Position: Position{Line: 1, Start: i, Len: 1},
|
Position: Position{Line: 1, Col: 1, Start: i, Len: 1},
|
||||||
Line: 1,
|
Line: 1,
|
||||||
input: data,
|
input: data,
|
||||||
}
|
}
|
||||||
@ -71,7 +72,7 @@ func parse(data string) (p *parser, err error) {
|
|||||||
|
|
||||||
p = &parser{
|
p = &parser{
|
||||||
keyInfo: make(map[string]keyInfo),
|
keyInfo: make(map[string]keyInfo),
|
||||||
mapping: make(map[string]interface{}),
|
mapping: make(map[string]any),
|
||||||
lx: lex(data, tomlNext),
|
lx: lex(data, tomlNext),
|
||||||
ordered: make([]Key, 0),
|
ordered: make([]Key, 0),
|
||||||
implicits: make(map[string]struct{}),
|
implicits: make(map[string]struct{}),
|
||||||
@ -90,26 +91,27 @@ func parse(data string) (p *parser, err error) {
|
|||||||
|
|
||||||
func (p *parser) panicErr(it item, err error) {
|
func (p *parser) panicErr(it item, err error) {
|
||||||
panic(ParseError{
|
panic(ParseError{
|
||||||
|
Message: err.Error(),
|
||||||
err: err,
|
err: err,
|
||||||
Position: it.pos,
|
Position: it.pos.withCol(p.lx.input),
|
||||||
Line: it.pos.Len,
|
Line: it.pos.Len,
|
||||||
LastKey: p.current(),
|
LastKey: p.current(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) panicItemf(it item, format string, v ...interface{}) {
|
func (p *parser) panicItemf(it item, format string, v ...any) {
|
||||||
panic(ParseError{
|
panic(ParseError{
|
||||||
Message: fmt.Sprintf(format, v...),
|
Message: fmt.Sprintf(format, v...),
|
||||||
Position: it.pos,
|
Position: it.pos.withCol(p.lx.input),
|
||||||
Line: it.pos.Len,
|
Line: it.pos.Len,
|
||||||
LastKey: p.current(),
|
LastKey: p.current(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) panicf(format string, v ...interface{}) {
|
func (p *parser) panicf(format string, v ...any) {
|
||||||
panic(ParseError{
|
panic(ParseError{
|
||||||
Message: fmt.Sprintf(format, v...),
|
Message: fmt.Sprintf(format, v...),
|
||||||
Position: p.pos,
|
Position: p.pos.withCol(p.lx.input),
|
||||||
Line: p.pos.Line,
|
Line: p.pos.Line,
|
||||||
LastKey: p.current(),
|
LastKey: p.current(),
|
||||||
})
|
})
|
||||||
@ -121,10 +123,11 @@ func (p *parser) next() item {
|
|||||||
if it.typ == itemError {
|
if it.typ == itemError {
|
||||||
if it.err != nil {
|
if it.err != nil {
|
||||||
panic(ParseError{
|
panic(ParseError{
|
||||||
Position: it.pos,
|
Message: it.err.Error(),
|
||||||
|
err: it.err,
|
||||||
|
Position: it.pos.withCol(p.lx.input),
|
||||||
Line: it.pos.Line,
|
Line: it.pos.Line,
|
||||||
LastKey: p.current(),
|
LastKey: p.current(),
|
||||||
err: it.err,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +142,7 @@ func (p *parser) nextPos() item {
|
|||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) bug(format string, v ...interface{}) {
|
func (p *parser) bug(format string, v ...any) {
|
||||||
panic(fmt.Sprintf("BUG: "+format+"\n\n", v...))
|
panic(fmt.Sprintf("BUG: "+format+"\n\n", v...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,11 +197,11 @@ func (p *parser) topLevel(item item) {
|
|||||||
p.assertEqual(itemKeyEnd, k.typ)
|
p.assertEqual(itemKeyEnd, k.typ)
|
||||||
|
|
||||||
/// The current key is the last part.
|
/// The current key is the last part.
|
||||||
p.currentKey = key[len(key)-1]
|
p.currentKey = key.last()
|
||||||
|
|
||||||
/// All the other parts (if any) are the context; need to set each part
|
/// All the other parts (if any) are the context; need to set each part
|
||||||
/// as implicit.
|
/// as implicit.
|
||||||
context := key[:len(key)-1]
|
context := key.parent()
|
||||||
for i := range context {
|
for i := range context {
|
||||||
p.addImplicitContext(append(p.context, context[i:i+1]...))
|
p.addImplicitContext(append(p.context, context[i:i+1]...))
|
||||||
}
|
}
|
||||||
@ -207,7 +210,8 @@ func (p *parser) topLevel(item item) {
|
|||||||
/// Set value.
|
/// Set value.
|
||||||
vItem := p.next()
|
vItem := p.next()
|
||||||
val, typ := p.value(vItem, false)
|
val, typ := p.value(vItem, false)
|
||||||
p.set(p.currentKey, val, typ, vItem.pos)
|
p.setValue(p.currentKey, val)
|
||||||
|
p.setType(p.currentKey, typ, vItem.pos)
|
||||||
|
|
||||||
/// Remove the context we added (preserving any context from [tbl] lines).
|
/// Remove the context we added (preserving any context from [tbl] lines).
|
||||||
p.context = outerContext
|
p.context = outerContext
|
||||||
@ -222,7 +226,7 @@ func (p *parser) keyString(it item) string {
|
|||||||
switch it.typ {
|
switch it.typ {
|
||||||
case itemText:
|
case itemText:
|
||||||
return it.val
|
return it.val
|
||||||
case itemString, itemMultilineString,
|
case itemString, itemStringEsc, itemMultilineString,
|
||||||
itemRawString, itemRawMultilineString:
|
itemRawString, itemRawMultilineString:
|
||||||
s, _ := p.value(it, false)
|
s, _ := p.value(it, false)
|
||||||
return s.(string)
|
return s.(string)
|
||||||
@ -239,9 +243,11 @@ var datetimeRepl = strings.NewReplacer(
|
|||||||
|
|
||||||
// value translates an expected value from the lexer into a Go value wrapped
|
// value translates an expected value from the lexer into a Go value wrapped
|
||||||
// as an empty interface.
|
// as an empty interface.
|
||||||
func (p *parser) value(it item, parentIsArray bool) (interface{}, tomlType) {
|
func (p *parser) value(it item, parentIsArray bool) (any, tomlType) {
|
||||||
switch it.typ {
|
switch it.typ {
|
||||||
case itemString:
|
case itemString:
|
||||||
|
return it.val, p.typeOfPrimitive(it)
|
||||||
|
case itemStringEsc:
|
||||||
return p.replaceEscapes(it, it.val), p.typeOfPrimitive(it)
|
return p.replaceEscapes(it, it.val), p.typeOfPrimitive(it)
|
||||||
case itemMultilineString:
|
case itemMultilineString:
|
||||||
return p.replaceEscapes(it, p.stripEscapedNewlines(stripFirstNewline(it.val))), p.typeOfPrimitive(it)
|
return p.replaceEscapes(it, p.stripEscapedNewlines(stripFirstNewline(it.val))), p.typeOfPrimitive(it)
|
||||||
@ -274,7 +280,7 @@ func (p *parser) value(it item, parentIsArray bool) (interface{}, tomlType) {
|
|||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) valueInteger(it item) (interface{}, tomlType) {
|
func (p *parser) valueInteger(it item) (any, tomlType) {
|
||||||
if !numUnderscoresOK(it.val) {
|
if !numUnderscoresOK(it.val) {
|
||||||
p.panicItemf(it, "Invalid integer %q: underscores must be surrounded by digits", it.val)
|
p.panicItemf(it, "Invalid integer %q: underscores must be surrounded by digits", it.val)
|
||||||
}
|
}
|
||||||
@ -298,7 +304,7 @@ func (p *parser) valueInteger(it item) (interface{}, tomlType) {
|
|||||||
return num, p.typeOfPrimitive(it)
|
return num, p.typeOfPrimitive(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) valueFloat(it item) (interface{}, tomlType) {
|
func (p *parser) valueFloat(it item) (any, tomlType) {
|
||||||
parts := strings.FieldsFunc(it.val, func(r rune) bool {
|
parts := strings.FieldsFunc(it.val, func(r rune) bool {
|
||||||
switch r {
|
switch r {
|
||||||
case '.', 'e', 'E':
|
case '.', 'e', 'E':
|
||||||
@ -322,7 +328,9 @@ func (p *parser) valueFloat(it item) (interface{}, tomlType) {
|
|||||||
p.panicItemf(it, "Invalid float %q: '.' must be followed by one or more digits", it.val)
|
p.panicItemf(it, "Invalid float %q: '.' must be followed by one or more digits", it.val)
|
||||||
}
|
}
|
||||||
val := strings.Replace(it.val, "_", "", -1)
|
val := strings.Replace(it.val, "_", "", -1)
|
||||||
if val == "+nan" || val == "-nan" { // Go doesn't support this, but TOML spec does.
|
signbit := false
|
||||||
|
if val == "+nan" || val == "-nan" {
|
||||||
|
signbit = val == "-nan"
|
||||||
val = "nan"
|
val = "nan"
|
||||||
}
|
}
|
||||||
num, err := strconv.ParseFloat(val, 64)
|
num, err := strconv.ParseFloat(val, 64)
|
||||||
@ -333,6 +341,9 @@ func (p *parser) valueFloat(it item) (interface{}, tomlType) {
|
|||||||
p.panicItemf(it, "Invalid float value: %q", it.val)
|
p.panicItemf(it, "Invalid float value: %q", it.val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if signbit {
|
||||||
|
num = math.Copysign(num, -1)
|
||||||
|
}
|
||||||
return num, p.typeOfPrimitive(it)
|
return num, p.typeOfPrimitive(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +363,7 @@ var dtTypes = []struct {
|
|||||||
{"15:04", internal.LocalTime, true},
|
{"15:04", internal.LocalTime, true},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) valueDatetime(it item) (interface{}, tomlType) {
|
func (p *parser) valueDatetime(it item) (any, tomlType) {
|
||||||
it.val = datetimeRepl.Replace(it.val)
|
it.val = datetimeRepl.Replace(it.val)
|
||||||
var (
|
var (
|
||||||
t time.Time
|
t time.Time
|
||||||
@ -365,26 +376,44 @@ func (p *parser) valueDatetime(it item) (interface{}, tomlType) {
|
|||||||
}
|
}
|
||||||
t, err = time.ParseInLocation(dt.fmt, it.val, dt.zone)
|
t, err = time.ParseInLocation(dt.fmt, it.val, dt.zone)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
if missingLeadingZero(it.val, dt.fmt) {
|
||||||
|
p.panicErr(it, errParseDate{it.val})
|
||||||
|
}
|
||||||
ok = true
|
ok = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
p.panicItemf(it, "Invalid TOML Datetime: %q.", it.val)
|
p.panicErr(it, errParseDate{it.val})
|
||||||
}
|
}
|
||||||
return t, p.typeOfPrimitive(it)
|
return t, p.typeOfPrimitive(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) valueArray(it item) (interface{}, tomlType) {
|
// Go's time.Parse() will accept numbers without a leading zero; there isn't any
|
||||||
|
// way to require it. https://github.com/golang/go/issues/29911
|
||||||
|
//
|
||||||
|
// Depend on the fact that the separators (- and :) should always be at the same
|
||||||
|
// location.
|
||||||
|
func missingLeadingZero(d, l string) bool {
|
||||||
|
for i, c := range []byte(l) {
|
||||||
|
if c == '.' || c == 'Z' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (c < '0' || c > '9') && d[i] != c {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) valueArray(it item) (any, tomlType) {
|
||||||
p.setType(p.currentKey, tomlArray, it.pos)
|
p.setType(p.currentKey, tomlArray, it.pos)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
types []tomlType
|
// Initialize to a non-nil slice to make it consistent with how S = []
|
||||||
|
// decodes into a non-nil slice inside something like struct { S
|
||||||
// Initialize to a non-nil empty slice. This makes it consistent with
|
// []string }. See #338
|
||||||
// how S = [] decodes into a non-nil slice inside something like struct
|
array = make([]any, 0, 2)
|
||||||
// { S []string }. See #338
|
|
||||||
array = []interface{}{}
|
|
||||||
)
|
)
|
||||||
for it = p.next(); it.typ != itemArrayEnd; it = p.next() {
|
for it = p.next(); it.typ != itemArrayEnd; it = p.next() {
|
||||||
if it.typ == itemCommentStart {
|
if it.typ == itemCommentStart {
|
||||||
@ -394,21 +423,20 @@ func (p *parser) valueArray(it item) (interface{}, tomlType) {
|
|||||||
|
|
||||||
val, typ := p.value(it, true)
|
val, typ := p.value(it, true)
|
||||||
array = append(array, val)
|
array = append(array, val)
|
||||||
types = append(types, typ)
|
|
||||||
|
|
||||||
// XXX: types isn't used here, we need it to record the accurate type
|
// XXX: type isn't used here, we need it to record the accurate type
|
||||||
// information.
|
// information.
|
||||||
//
|
//
|
||||||
// Not entirely sure how to best store this; could use "key[0]",
|
// Not entirely sure how to best store this; could use "key[0]",
|
||||||
// "key[1]" notation, or maybe store it on the Array type?
|
// "key[1]" notation, or maybe store it on the Array type?
|
||||||
_ = types
|
_ = typ
|
||||||
}
|
}
|
||||||
return array, tomlArray
|
return array, tomlArray
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) valueInlineTable(it item, parentIsArray bool) (interface{}, tomlType) {
|
func (p *parser) valueInlineTable(it item, parentIsArray bool) (any, tomlType) {
|
||||||
var (
|
var (
|
||||||
hash = make(map[string]interface{})
|
topHash = make(map[string]any)
|
||||||
outerContext = p.context
|
outerContext = p.context
|
||||||
outerKey = p.currentKey
|
outerKey = p.currentKey
|
||||||
)
|
)
|
||||||
@ -436,11 +464,11 @@ func (p *parser) valueInlineTable(it item, parentIsArray bool) (interface{}, tom
|
|||||||
p.assertEqual(itemKeyEnd, k.typ)
|
p.assertEqual(itemKeyEnd, k.typ)
|
||||||
|
|
||||||
/// The current key is the last part.
|
/// The current key is the last part.
|
||||||
p.currentKey = key[len(key)-1]
|
p.currentKey = key.last()
|
||||||
|
|
||||||
/// All the other parts (if any) are the context; need to set each part
|
/// All the other parts (if any) are the context; need to set each part
|
||||||
/// as implicit.
|
/// as implicit.
|
||||||
context := key[:len(key)-1]
|
context := key.parent()
|
||||||
for i := range context {
|
for i := range context {
|
||||||
p.addImplicitContext(append(p.context, context[i:i+1]...))
|
p.addImplicitContext(append(p.context, context[i:i+1]...))
|
||||||
}
|
}
|
||||||
@ -448,7 +476,21 @@ func (p *parser) valueInlineTable(it item, parentIsArray bool) (interface{}, tom
|
|||||||
|
|
||||||
/// Set the value.
|
/// Set the value.
|
||||||
val, typ := p.value(p.next(), false)
|
val, typ := p.value(p.next(), false)
|
||||||
p.set(p.currentKey, val, typ, it.pos)
|
p.setValue(p.currentKey, val)
|
||||||
|
p.setType(p.currentKey, typ, it.pos)
|
||||||
|
|
||||||
|
hash := topHash
|
||||||
|
for _, c := range context {
|
||||||
|
h, ok := hash[c]
|
||||||
|
if !ok {
|
||||||
|
h = make(map[string]any)
|
||||||
|
hash[c] = h
|
||||||
|
}
|
||||||
|
hash, ok = h.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
p.panicf("%q is not a table", p.context)
|
||||||
|
}
|
||||||
|
}
|
||||||
hash[p.currentKey] = val
|
hash[p.currentKey] = val
|
||||||
|
|
||||||
/// Restore context.
|
/// Restore context.
|
||||||
@ -456,7 +498,7 @@ func (p *parser) valueInlineTable(it item, parentIsArray bool) (interface{}, tom
|
|||||||
}
|
}
|
||||||
p.context = outerContext
|
p.context = outerContext
|
||||||
p.currentKey = outerKey
|
p.currentKey = outerKey
|
||||||
return hash, tomlHash
|
return topHash, tomlHash
|
||||||
}
|
}
|
||||||
|
|
||||||
// numHasLeadingZero checks if this number has leading zeroes, allowing for '0',
|
// numHasLeadingZero checks if this number has leading zeroes, allowing for '0',
|
||||||
@ -486,9 +528,9 @@ func numUnderscoresOK(s string) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// isHexadecimal is a superset of all the permissable characters
|
// isHex is a superset of all the permissible characters surrounding an
|
||||||
// surrounding an underscore.
|
// underscore.
|
||||||
accept = isHexadecimal(r)
|
accept = isHex(r)
|
||||||
}
|
}
|
||||||
return accept
|
return accept
|
||||||
}
|
}
|
||||||
@ -511,21 +553,19 @@ func numPeriodsOK(s string) bool {
|
|||||||
// Establishing the context also makes sure that the key isn't a duplicate, and
|
// Establishing the context also makes sure that the key isn't a duplicate, and
|
||||||
// will create implicit hashes automatically.
|
// will create implicit hashes automatically.
|
||||||
func (p *parser) addContext(key Key, array bool) {
|
func (p *parser) addContext(key Key, array bool) {
|
||||||
var ok bool
|
/// Always start at the top level and drill down for our context.
|
||||||
|
|
||||||
// Always start at the top level and drill down for our context.
|
|
||||||
hashContext := p.mapping
|
hashContext := p.mapping
|
||||||
keyContext := make(Key, 0)
|
keyContext := make(Key, 0, len(key)-1)
|
||||||
|
|
||||||
// We only need implicit hashes for key[0:-1]
|
/// We only need implicit hashes for the parents.
|
||||||
for _, k := range key[0 : len(key)-1] {
|
for _, k := range key.parent() {
|
||||||
_, ok = hashContext[k]
|
_, ok := hashContext[k]
|
||||||
keyContext = append(keyContext, k)
|
keyContext = append(keyContext, k)
|
||||||
|
|
||||||
// No key? Make an implicit hash and move on.
|
// No key? Make an implicit hash and move on.
|
||||||
if !ok {
|
if !ok {
|
||||||
p.addImplicit(keyContext)
|
p.addImplicit(keyContext)
|
||||||
hashContext[k] = make(map[string]interface{})
|
hashContext[k] = make(map[string]any)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the hash context is actually an array of tables, then set
|
// If the hash context is actually an array of tables, then set
|
||||||
@ -534,9 +574,9 @@ func (p *parser) addContext(key Key, array bool) {
|
|||||||
// Otherwise, it better be a table, since this MUST be a key group (by
|
// Otherwise, it better be a table, since this MUST be a key group (by
|
||||||
// virtue of it not being the last element in a key).
|
// virtue of it not being the last element in a key).
|
||||||
switch t := hashContext[k].(type) {
|
switch t := hashContext[k].(type) {
|
||||||
case []map[string]interface{}:
|
case []map[string]any:
|
||||||
hashContext = t[len(t)-1]
|
hashContext = t[len(t)-1]
|
||||||
case map[string]interface{}:
|
case map[string]any:
|
||||||
hashContext = t
|
hashContext = t
|
||||||
default:
|
default:
|
||||||
p.panicf("Key '%s' was already created as a hash.", keyContext)
|
p.panicf("Key '%s' was already created as a hash.", keyContext)
|
||||||
@ -547,39 +587,33 @@ func (p *parser) addContext(key Key, array bool) {
|
|||||||
if array {
|
if array {
|
||||||
// If this is the first element for this array, then allocate a new
|
// If this is the first element for this array, then allocate a new
|
||||||
// list of tables for it.
|
// list of tables for it.
|
||||||
k := key[len(key)-1]
|
k := key.last()
|
||||||
if _, ok := hashContext[k]; !ok {
|
if _, ok := hashContext[k]; !ok {
|
||||||
hashContext[k] = make([]map[string]interface{}, 0, 4)
|
hashContext[k] = make([]map[string]any, 0, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new table. But make sure the key hasn't already been used
|
// Add a new table. But make sure the key hasn't already been used
|
||||||
// for something else.
|
// for something else.
|
||||||
if hash, ok := hashContext[k].([]map[string]interface{}); ok {
|
if hash, ok := hashContext[k].([]map[string]any); ok {
|
||||||
hashContext[k] = append(hash, make(map[string]interface{}))
|
hashContext[k] = append(hash, make(map[string]any))
|
||||||
} else {
|
} else {
|
||||||
p.panicf("Key '%s' was already created and cannot be used as an array.", key)
|
p.panicf("Key '%s' was already created and cannot be used as an array.", key)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.setValue(key[len(key)-1], make(map[string]interface{}))
|
p.setValue(key.last(), make(map[string]any))
|
||||||
}
|
}
|
||||||
p.context = append(p.context, key[len(key)-1])
|
p.context = append(p.context, key.last())
|
||||||
}
|
|
||||||
|
|
||||||
// set calls setValue and setType.
|
|
||||||
func (p *parser) set(key string, val interface{}, typ tomlType, pos Position) {
|
|
||||||
p.setValue(key, val)
|
|
||||||
p.setType(key, typ, pos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setValue sets the given key to the given value in the current context.
|
// setValue sets the given key to the given value in the current context.
|
||||||
// It will make sure that the key hasn't already been defined, account for
|
// It will make sure that the key hasn't already been defined, account for
|
||||||
// implicit key groups.
|
// implicit key groups.
|
||||||
func (p *parser) setValue(key string, value interface{}) {
|
func (p *parser) setValue(key string, value any) {
|
||||||
var (
|
var (
|
||||||
tmpHash interface{}
|
tmpHash any
|
||||||
ok bool
|
ok bool
|
||||||
hash = p.mapping
|
hash = p.mapping
|
||||||
keyContext Key
|
keyContext = make(Key, 0, len(p.context)+1)
|
||||||
)
|
)
|
||||||
for _, k := range p.context {
|
for _, k := range p.context {
|
||||||
keyContext = append(keyContext, k)
|
keyContext = append(keyContext, k)
|
||||||
@ -587,11 +621,11 @@ func (p *parser) setValue(key string, value interface{}) {
|
|||||||
p.bug("Context for key '%s' has not been established.", keyContext)
|
p.bug("Context for key '%s' has not been established.", keyContext)
|
||||||
}
|
}
|
||||||
switch t := tmpHash.(type) {
|
switch t := tmpHash.(type) {
|
||||||
case []map[string]interface{}:
|
case []map[string]any:
|
||||||
// The context is a table of hashes. Pick the most recent table
|
// The context is a table of hashes. Pick the most recent table
|
||||||
// defined as the current hash.
|
// defined as the current hash.
|
||||||
hash = t[len(t)-1]
|
hash = t[len(t)-1]
|
||||||
case map[string]interface{}:
|
case map[string]any:
|
||||||
hash = t
|
hash = t
|
||||||
default:
|
default:
|
||||||
p.panicf("Key '%s' has already been defined.", keyContext)
|
p.panicf("Key '%s' has already been defined.", keyContext)
|
||||||
@ -618,9 +652,8 @@ func (p *parser) setValue(key string, value interface{}) {
|
|||||||
p.removeImplicit(keyContext)
|
p.removeImplicit(keyContext)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Otherwise, we have a concrete key trying to override a previous key,
|
||||||
// Otherwise, we have a concrete key trying to override a previous
|
// which is *always* wrong.
|
||||||
// key, which is *always* wrong.
|
|
||||||
p.panicf("Key '%s' has already been defined.", keyContext)
|
p.panicf("Key '%s' has already been defined.", keyContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,8 +716,11 @@ func stripFirstNewline(s string) string {
|
|||||||
// the next newline. After a line-ending backslash, all whitespace is removed
|
// the next newline. After a line-ending backslash, all whitespace is removed
|
||||||
// until the next non-whitespace character.
|
// until the next non-whitespace character.
|
||||||
func (p *parser) stripEscapedNewlines(s string) string {
|
func (p *parser) stripEscapedNewlines(s string) string {
|
||||||
var b strings.Builder
|
var (
|
||||||
var i int
|
b strings.Builder
|
||||||
|
i int
|
||||||
|
)
|
||||||
|
b.Grow(len(s))
|
||||||
for {
|
for {
|
||||||
ix := strings.Index(s[i:], `\`)
|
ix := strings.Index(s[i:], `\`)
|
||||||
if ix < 0 {
|
if ix < 0 {
|
||||||
@ -714,9 +750,8 @@ func (p *parser) stripEscapedNewlines(s string) string {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !strings.Contains(s[i:j], "\n") {
|
if !strings.Contains(s[i:j], "\n") {
|
||||||
// This is not a line-ending backslash.
|
// This is not a line-ending backslash. (It's a bad escape sequence,
|
||||||
// (It's a bad escape sequence, but we can let
|
// but we can let replaceEscapes catch it.)
|
||||||
// replaceEscapes catch it.)
|
|
||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -727,79 +762,78 @@ func (p *parser) stripEscapedNewlines(s string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) replaceEscapes(it item, str string) string {
|
func (p *parser) replaceEscapes(it item, str string) string {
|
||||||
replaced := make([]rune, 0, len(str))
|
var (
|
||||||
s := []byte(str)
|
b strings.Builder
|
||||||
r := 0
|
skip = 0
|
||||||
for r < len(s) {
|
)
|
||||||
if s[r] != '\\' {
|
b.Grow(len(str))
|
||||||
c, size := utf8.DecodeRune(s[r:])
|
for i, c := range str {
|
||||||
r += size
|
if skip > 0 {
|
||||||
replaced = append(replaced, c)
|
skip--
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
r += 1
|
if c != '\\' {
|
||||||
if r >= len(s) {
|
b.WriteRune(c)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if i >= len(str) {
|
||||||
p.bug("Escape sequence at end of string.")
|
p.bug("Escape sequence at end of string.")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
switch s[r] {
|
switch str[i+1] {
|
||||||
default:
|
default:
|
||||||
p.bug("Expected valid escape code after \\, but got %q.", s[r])
|
p.bug("Expected valid escape code after \\, but got %q.", str[i+1])
|
||||||
case ' ', '\t':
|
case ' ', '\t':
|
||||||
p.panicItemf(it, "invalid escape: '\\%c'", s[r])
|
p.panicItemf(it, "invalid escape: '\\%c'", str[i+1])
|
||||||
case 'b':
|
case 'b':
|
||||||
replaced = append(replaced, rune(0x0008))
|
b.WriteByte(0x08)
|
||||||
r += 1
|
skip = 1
|
||||||
case 't':
|
case 't':
|
||||||
replaced = append(replaced, rune(0x0009))
|
b.WriteByte(0x09)
|
||||||
r += 1
|
skip = 1
|
||||||
case 'n':
|
case 'n':
|
||||||
replaced = append(replaced, rune(0x000A))
|
b.WriteByte(0x0a)
|
||||||
r += 1
|
skip = 1
|
||||||
case 'f':
|
case 'f':
|
||||||
replaced = append(replaced, rune(0x000C))
|
b.WriteByte(0x0c)
|
||||||
r += 1
|
skip = 1
|
||||||
case 'r':
|
case 'r':
|
||||||
replaced = append(replaced, rune(0x000D))
|
b.WriteByte(0x0d)
|
||||||
r += 1
|
skip = 1
|
||||||
case 'e':
|
case 'e':
|
||||||
if p.tomlNext {
|
if p.tomlNext {
|
||||||
replaced = append(replaced, rune(0x001B))
|
b.WriteByte(0x1b)
|
||||||
r += 1
|
skip = 1
|
||||||
}
|
}
|
||||||
case '"':
|
case '"':
|
||||||
replaced = append(replaced, rune(0x0022))
|
b.WriteByte(0x22)
|
||||||
r += 1
|
skip = 1
|
||||||
case '\\':
|
case '\\':
|
||||||
replaced = append(replaced, rune(0x005C))
|
b.WriteByte(0x5c)
|
||||||
r += 1
|
skip = 1
|
||||||
|
// The lexer guarantees the correct number of characters are present;
|
||||||
|
// don't need to check here.
|
||||||
case 'x':
|
case 'x':
|
||||||
if p.tomlNext {
|
if p.tomlNext {
|
||||||
escaped := p.asciiEscapeToUnicode(it, s[r+1:r+3])
|
escaped := p.asciiEscapeToUnicode(it, str[i+2:i+4])
|
||||||
replaced = append(replaced, escaped)
|
b.WriteRune(escaped)
|
||||||
r += 3
|
skip = 3
|
||||||
}
|
}
|
||||||
case 'u':
|
case 'u':
|
||||||
// At this point, we know we have a Unicode escape of the form
|
escaped := p.asciiEscapeToUnicode(it, str[i+2:i+6])
|
||||||
// `uXXXX` at [r, r+5). (Because the lexer guarantees this
|
b.WriteRune(escaped)
|
||||||
// for us.)
|
skip = 5
|
||||||
escaped := p.asciiEscapeToUnicode(it, s[r+1:r+5])
|
|
||||||
replaced = append(replaced, escaped)
|
|
||||||
r += 5
|
|
||||||
case 'U':
|
case 'U':
|
||||||
// At this point, we know we have a Unicode escape of the form
|
escaped := p.asciiEscapeToUnicode(it, str[i+2:i+10])
|
||||||
// `uXXXX` at [r, r+9). (Because the lexer guarantees this
|
b.WriteRune(escaped)
|
||||||
// for us.)
|
skip = 9
|
||||||
escaped := p.asciiEscapeToUnicode(it, s[r+1:r+9])
|
|
||||||
replaced = append(replaced, escaped)
|
|
||||||
r += 9
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return string(replaced)
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) asciiEscapeToUnicode(it item, bs []byte) rune {
|
func (p *parser) asciiEscapeToUnicode(it item, s string) rune {
|
||||||
s := string(bs)
|
|
||||||
hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32)
|
hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.bug("Could not parse '%s' as a hexadecimal number, but the lexer claims it's OK: %s", s, err)
|
p.bug("Could not parse '%s' as a hexadecimal number, but the lexer claims it's OK: %s", s, err)
|
||||||
|
8
vendor/github.com/BurntSushi/toml/type_fields.go
generated
vendored
8
vendor/github.com/BurntSushi/toml/type_fields.go
generated
vendored
@ -25,10 +25,8 @@ type field struct {
|
|||||||
// breaking ties with index sequence.
|
// breaking ties with index sequence.
|
||||||
type byName []field
|
type byName []field
|
||||||
|
|
||||||
func (x byName) Len() int { return len(x) }
|
func (x byName) Len() int { return len(x) }
|
||||||
|
|
||||||
func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
func (x byName) Less(i, j int) bool {
|
func (x byName) Less(i, j int) bool {
|
||||||
if x[i].name != x[j].name {
|
if x[i].name != x[j].name {
|
||||||
return x[i].name < x[j].name
|
return x[i].name < x[j].name
|
||||||
@ -45,10 +43,8 @@ func (x byName) Less(i, j int) bool {
|
|||||||
// byIndex sorts field by index sequence.
|
// byIndex sorts field by index sequence.
|
||||||
type byIndex []field
|
type byIndex []field
|
||||||
|
|
||||||
func (x byIndex) Len() int { return len(x) }
|
func (x byIndex) Len() int { return len(x) }
|
||||||
|
|
||||||
func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
func (x byIndex) Less(i, j int) bool {
|
func (x byIndex) Less(i, j int) bool {
|
||||||
for k, xik := range x[i].index {
|
for k, xik := range x[i].index {
|
||||||
if k >= len(x[j].index) {
|
if k >= len(x[j].index) {
|
||||||
|
11
vendor/github.com/BurntSushi/toml/type_toml.go
generated
vendored
11
vendor/github.com/BurntSushi/toml/type_toml.go
generated
vendored
@ -22,13 +22,8 @@ func typeIsTable(t tomlType) bool {
|
|||||||
|
|
||||||
type tomlBaseType string
|
type tomlBaseType string
|
||||||
|
|
||||||
func (btype tomlBaseType) typeString() string {
|
func (btype tomlBaseType) typeString() string { return string(btype) }
|
||||||
return string(btype)
|
func (btype tomlBaseType) String() string { return btype.typeString() }
|
||||||
}
|
|
||||||
|
|
||||||
func (btype tomlBaseType) String() string {
|
|
||||||
return btype.typeString()
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tomlInteger tomlBaseType = "Integer"
|
tomlInteger tomlBaseType = "Integer"
|
||||||
@ -54,7 +49,7 @@ func (p *parser) typeOfPrimitive(lexItem item) tomlType {
|
|||||||
return tomlFloat
|
return tomlFloat
|
||||||
case itemDatetime:
|
case itemDatetime:
|
||||||
return tomlDatetime
|
return tomlDatetime
|
||||||
case itemString:
|
case itemString, itemStringEsc:
|
||||||
return tomlString
|
return tomlString
|
||||||
case itemMultilineString:
|
case itemMultilineString:
|
||||||
return tomlString
|
return tomlString
|
||||||
|
1
vendor/github.com/Masterminds/semver/v3/.gitignore
generated
vendored
Normal file
1
vendor/github.com/Masterminds/semver/v3/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
_fuzz/
|
27
vendor/github.com/Masterminds/semver/v3/.golangci.yml
generated
vendored
Normal file
27
vendor/github.com/Masterminds/semver/v3/.golangci.yml
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
run:
|
||||||
|
deadline: 2m
|
||||||
|
|
||||||
|
linters:
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- misspell
|
||||||
|
- govet
|
||||||
|
- staticcheck
|
||||||
|
- errcheck
|
||||||
|
- unparam
|
||||||
|
- ineffassign
|
||||||
|
- nakedret
|
||||||
|
- gocyclo
|
||||||
|
- dupl
|
||||||
|
- goimports
|
||||||
|
- revive
|
||||||
|
- gosec
|
||||||
|
- gosimple
|
||||||
|
- typecheck
|
||||||
|
- unused
|
||||||
|
|
||||||
|
linters-settings:
|
||||||
|
gofmt:
|
||||||
|
simplify: true
|
||||||
|
dupl:
|
||||||
|
threshold: 600
|
242
vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
generated
vendored
Normal file
242
vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 3.3.0 (2024-08-27)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #238: Add LessThanEqual and GreaterThanEqual functions (thanks @grosser)
|
||||||
|
- #213: nil version equality checking (thanks @KnutZuidema)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #241: Simplify StrictNewVersion parsing (thanks @grosser)
|
||||||
|
- Testing support up through Go 1.23
|
||||||
|
- Minimum version set to 1.21 as this is what's tested now
|
||||||
|
- Fuzz testing now supports caching
|
||||||
|
|
||||||
|
## 3.2.1 (2023-04-10)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #198: Improved testing around pre-release names
|
||||||
|
- #200: Improved code scanning with addition of CodeQL
|
||||||
|
- #201: Testing now includes Go 1.20. Go 1.17 has been dropped
|
||||||
|
- #202: Migrated Fuzz testing to Go built-in Fuzzing. CI runs daily
|
||||||
|
- #203: Docs updated for security details
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #199: Fixed issue with range transformations
|
||||||
|
|
||||||
|
## 3.2.0 (2022-11-28)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #190: Added text marshaling and unmarshaling
|
||||||
|
- #167: Added JSON marshalling for constraints (thanks @SimonTheLeg)
|
||||||
|
- #173: Implement encoding.TextMarshaler and encoding.TextUnmarshaler on Version (thanks @MarkRosemaker)
|
||||||
|
- #179: Added New() version constructor (thanks @kazhuravlev)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #182/#183: Updated CI testing setup
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #186: Fixing issue where validation of constraint section gave false positives
|
||||||
|
- #176: Fix constraints check with *-0 (thanks @mtt0)
|
||||||
|
- #181: Fixed Caret operator (^) gives unexpected results when the minor version in constraint is 0 (thanks @arshchimni)
|
||||||
|
- #161: Fixed godoc (thanks @afirth)
|
||||||
|
|
||||||
|
## 3.1.1 (2020-11-23)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #158: Fixed issue with generated regex operation order that could cause problem
|
||||||
|
|
||||||
|
## 3.1.0 (2020-04-15)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #131: Add support for serializing/deserializing SQL (thanks @ryancurrah)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #148: More accurate validation messages on constraints
|
||||||
|
|
||||||
|
## 3.0.3 (2019-12-13)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #141: Fixed issue with <= comparison
|
||||||
|
|
||||||
|
## 3.0.2 (2019-11-14)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #134: Fixed broken constraint checking with ^0.0 (thanks @krmichelos)
|
||||||
|
|
||||||
|
## 3.0.1 (2019-09-13)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #125: Fixes issue with module path for v3
|
||||||
|
|
||||||
|
## 3.0.0 (2019-09-12)
|
||||||
|
|
||||||
|
This is a major release of the semver package which includes API changes. The Go
|
||||||
|
API is compatible with ^1. The Go API was not changed because many people are using
|
||||||
|
`go get` without Go modules for their applications and API breaking changes cause
|
||||||
|
errors which we have or would need to support.
|
||||||
|
|
||||||
|
The changes in this release are the handling based on the data passed into the
|
||||||
|
functions. These are described in the added and changed sections below.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- StrictNewVersion function. This is similar to NewVersion but will return an
|
||||||
|
error if the version passed in is not a strict semantic version. For example,
|
||||||
|
1.2.3 would pass but v1.2.3 or 1.2 would fail because they are not strictly
|
||||||
|
speaking semantic versions. This function is faster, performs fewer operations,
|
||||||
|
and uses fewer allocations than NewVersion.
|
||||||
|
- Fuzzing has been performed on NewVersion, StrictNewVersion, and NewConstraint.
|
||||||
|
The Makefile contains the operations used. For more information on you can start
|
||||||
|
on Wikipedia at https://en.wikipedia.org/wiki/Fuzzing
|
||||||
|
- Now using Go modules
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- NewVersion has proper prerelease and metadata validation with error messages
|
||||||
|
to signal an issue with either of them
|
||||||
|
- ^ now operates using a similar set of rules to npm/js and Rust/Cargo. If the
|
||||||
|
version is >=1 the ^ ranges works the same as v1. For major versions of 0 the
|
||||||
|
rules have changed. The minor version is treated as the stable version unless
|
||||||
|
a patch is specified and then it is equivalent to =. One difference from npm/js
|
||||||
|
is that prereleases there are only to a specific version (e.g. 1.2.3).
|
||||||
|
Prereleases here look over multiple versions and follow semantic version
|
||||||
|
ordering rules. This pattern now follows along with the expected and requested
|
||||||
|
handling of this packaged by numerous users.
|
||||||
|
|
||||||
|
## 1.5.0 (2019-09-11)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #103: Add basic fuzzing for `NewVersion()` (thanks @jesse-c)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #82: Clarify wildcard meaning in range constraints and update tests for it (thanks @greysteil)
|
||||||
|
- #83: Clarify caret operator range for pre-1.0.0 dependencies (thanks @greysteil)
|
||||||
|
- #72: Adding docs comment pointing to vert for a cli
|
||||||
|
- #71: Update the docs on pre-release comparator handling
|
||||||
|
- #89: Test with new go versions (thanks @thedevsaddam)
|
||||||
|
- #87: Added $ to ValidPrerelease for better validation (thanks @jeremycarroll)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #78: Fix unchecked error in example code (thanks @ravron)
|
||||||
|
- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
|
||||||
|
- #97: Fixed copyright file for proper display on GitHub
|
||||||
|
- #107: Fix handling prerelease when sorting alphanum and num
|
||||||
|
- #109: Fixed where Validate sometimes returns wrong message on error
|
||||||
|
|
||||||
|
## 1.4.2 (2018-04-10)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #72: Updated the docs to point to vert for a console appliaction
|
||||||
|
- #71: Update the docs on pre-release comparator handling
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
|
||||||
|
|
||||||
|
## 1.4.1 (2018-04-02)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed #64: Fix pre-release precedence issue (thanks @uudashr)
|
||||||
|
|
||||||
|
## 1.4.0 (2017-10-04)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill)
|
||||||
|
|
||||||
|
## 1.3.1 (2017-07-10)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed #57: number comparisons in prerelease sometimes inaccurate
|
||||||
|
|
||||||
|
## 1.3.0 (2017-05-02)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #45: Added json (un)marshaling support (thanks @mh-cbon)
|
||||||
|
- Stability marker. See https://masterminds.github.io/stability/
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #51: Fix handling of single digit tilde constraint (thanks @dgodd)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #55: The godoc icon moved from png to svg
|
||||||
|
|
||||||
|
## 1.2.3 (2017-04-03)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #46: Fixed 0.x.x and 0.0.x in constraints being treated as *
|
||||||
|
|
||||||
|
## Release 1.2.2 (2016-12-13)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #34: Fixed issue where hyphen range was not working with pre-release parsing.
|
||||||
|
|
||||||
|
## Release 1.2.1 (2016-11-28)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha"
|
||||||
|
properly.
|
||||||
|
|
||||||
|
## Release 1.2.0 (2016-11-04)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #20: Added MustParse function for versions (thanks @adamreese)
|
||||||
|
- #15: Added increment methods on versions (thanks @mh-cbon)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and
|
||||||
|
might not satisfy the intended compatibility. The change here ignores pre-releases
|
||||||
|
on constraint checks (e.g., ~ or ^) when a pre-release is not part of the
|
||||||
|
constraint. For example, `^1.2.3` will ignore pre-releases while
|
||||||
|
`^1.2.3-alpha` will include them.
|
||||||
|
|
||||||
|
## Release 1.1.1 (2016-06-30)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Issue #9: Speed up version comparison performance (thanks @sdboyer)
|
||||||
|
- Issue #8: Added benchmarks (thanks @sdboyer)
|
||||||
|
- Updated Go Report Card URL to new location
|
||||||
|
- Updated Readme to add code snippet formatting (thanks @mh-cbon)
|
||||||
|
- Updating tagging to v[SemVer] structure for compatibility with other tools.
|
||||||
|
|
||||||
|
## Release 1.1.0 (2016-03-11)
|
||||||
|
|
||||||
|
- Issue #2: Implemented validation to provide reasons a versions failed a
|
||||||
|
constraint.
|
||||||
|
|
||||||
|
## Release 1.0.1 (2015-12-31)
|
||||||
|
|
||||||
|
- Fixed #1: * constraint failing on valid versions.
|
||||||
|
|
||||||
|
## Release 1.0.0 (2015-10-20)
|
||||||
|
|
||||||
|
- Initial release
|
@ -1,6 +1,4 @@
|
|||||||
The MIT License (MIT)
|
Copyright (C) 2014-2019, Matt Butcher and Matt Farina
|
||||||
|
|
||||||
Copyright (c) 2017 Yasuhiro Matsumoto
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -9,13 +7,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in
|
||||||
copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
SOFTWARE.
|
THE SOFTWARE.
|
31
vendor/github.com/Masterminds/semver/v3/Makefile
generated
vendored
Normal file
31
vendor/github.com/Masterminds/semver/v3/Makefile
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
GOPATH=$(shell go env GOPATH)
|
||||||
|
GOLANGCI_LINT=$(GOPATH)/bin/golangci-lint
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
|
lint: $(GOLANGCI_LINT)
|
||||||
|
@echo "==> Linting codebase"
|
||||||
|
@$(GOLANGCI_LINT) run
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test:
|
||||||
|
@echo "==> Running tests"
|
||||||
|
GO111MODULE=on go test -v
|
||||||
|
|
||||||
|
.PHONY: test-cover
|
||||||
|
test-cover:
|
||||||
|
@echo "==> Running Tests with coverage"
|
||||||
|
GO111MODULE=on go test -cover .
|
||||||
|
|
||||||
|
.PHONY: fuzz
|
||||||
|
fuzz:
|
||||||
|
@echo "==> Running Fuzz Tests"
|
||||||
|
go env GOCACHE
|
||||||
|
go test -fuzz=FuzzNewVersion -fuzztime=15s .
|
||||||
|
go test -fuzz=FuzzStrictNewVersion -fuzztime=15s .
|
||||||
|
go test -fuzz=FuzzNewConstraint -fuzztime=15s .
|
||||||
|
|
||||||
|
$(GOLANGCI_LINT):
|
||||||
|
# Install golangci-lint. The configuration for it is in the .golangci.yml
|
||||||
|
# file in the root of the repository
|
||||||
|
echo ${GOPATH}
|
||||||
|
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.56.2
|
258
vendor/github.com/Masterminds/semver/v3/README.md
generated
vendored
Normal file
258
vendor/github.com/Masterminds/semver/v3/README.md
generated
vendored
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
# SemVer
|
||||||
|
|
||||||
|
The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to:
|
||||||
|
|
||||||
|
* Parse semantic versions
|
||||||
|
* Sort semantic versions
|
||||||
|
* Check if a semantic version fits within a set of constraints
|
||||||
|
* Optionally work with a `v` prefix
|
||||||
|
|
||||||
|
[](https://masterminds.github.io/stability/active.html)
|
||||||
|
[](https://github.com/Masterminds/semver/actions)
|
||||||
|
[](https://pkg.go.dev/github.com/Masterminds/semver/v3)
|
||||||
|
[](https://goreportcard.com/report/github.com/Masterminds/semver)
|
||||||
|
|
||||||
|
## Package Versions
|
||||||
|
|
||||||
|
Note, import `github.com/Masterminds/semver/v3` to use the latest version.
|
||||||
|
|
||||||
|
There are three major versions fo the `semver` package.
|
||||||
|
|
||||||
|
* 3.x.x is the stable and active version. This version is focused on constraint
|
||||||
|
compatibility for range handling in other tools from other languages. It has
|
||||||
|
a similar API to the v1 releases. The development of this version is on the master
|
||||||
|
branch. The documentation for this version is below.
|
||||||
|
* 2.x was developed primarily for [dep](https://github.com/golang/dep). There are
|
||||||
|
no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer).
|
||||||
|
There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x).
|
||||||
|
* 1.x.x is the original release. It is no longer maintained. You should use the
|
||||||
|
v3 release instead. You can read the documentation for the 1.x.x release
|
||||||
|
[here](https://github.com/Masterminds/semver/blob/release-1/README.md).
|
||||||
|
|
||||||
|
## Parsing Semantic Versions
|
||||||
|
|
||||||
|
There are two functions that can parse semantic versions. The `StrictNewVersion`
|
||||||
|
function only parses valid version 2 semantic versions as outlined in the
|
||||||
|
specification. The `NewVersion` function attempts to coerce a version into a
|
||||||
|
semantic version and parse it. For example, if there is a leading v or a version
|
||||||
|
listed without all 3 parts (e.g. `v1.2`) it will attempt to coerce it into a valid
|
||||||
|
semantic version (e.g., 1.2.0). In both cases a `Version` object is returned
|
||||||
|
that can be sorted, compared, and used in constraints.
|
||||||
|
|
||||||
|
When parsing a version an error is returned if there is an issue parsing the
|
||||||
|
version. For example,
|
||||||
|
|
||||||
|
v, err := semver.NewVersion("1.2.3-beta.1+build345")
|
||||||
|
|
||||||
|
The version object has methods to get the parts of the version, compare it to
|
||||||
|
other versions, convert the version back into a string, and get the original
|
||||||
|
string. Getting the original string is useful if the semantic version was coerced
|
||||||
|
into a valid form.
|
||||||
|
|
||||||
|
## Sorting Semantic Versions
|
||||||
|
|
||||||
|
A set of versions can be sorted using the `sort` package from the standard library.
|
||||||
|
For example,
|
||||||
|
|
||||||
|
```go
|
||||||
|
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
|
||||||
|
vs := make([]*semver.Version, len(raw))
|
||||||
|
for i, r := range raw {
|
||||||
|
v, err := semver.NewVersion(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error parsing version: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
vs[i] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(semver.Collection(vs))
|
||||||
|
```
|
||||||
|
|
||||||
|
## Checking Version Constraints
|
||||||
|
|
||||||
|
There are two methods for comparing versions. One uses comparison methods on
|
||||||
|
`Version` instances and the other uses `Constraints`. There are some important
|
||||||
|
differences to notes between these two methods of comparison.
|
||||||
|
|
||||||
|
1. When two versions are compared using functions such as `Compare`, `LessThan`,
|
||||||
|
and others it will follow the specification and always include pre-releases
|
||||||
|
within the comparison. It will provide an answer that is valid with the
|
||||||
|
comparison section of the spec at https://semver.org/#spec-item-11
|
||||||
|
2. When constraint checking is used for checks or validation it will follow a
|
||||||
|
different set of rules that are common for ranges with tools like npm/js
|
||||||
|
and Rust/Cargo. This includes considering pre-releases to be invalid if the
|
||||||
|
ranges does not include one. If you want to have it include pre-releases a
|
||||||
|
simple solution is to include `-0` in your range.
|
||||||
|
3. Constraint ranges can have some complex rules including the shorthand use of
|
||||||
|
~ and ^. For more details on those see the options below.
|
||||||
|
|
||||||
|
There are differences between the two methods or checking versions because the
|
||||||
|
comparison methods on `Version` follow the specification while comparison ranges
|
||||||
|
are not part of the specification. Different packages and tools have taken it
|
||||||
|
upon themselves to come up with range rules. This has resulted in differences.
|
||||||
|
For example, npm/js and Cargo/Rust follow similar patterns while PHP has a
|
||||||
|
different pattern for ^. The comparison features in this package follow the
|
||||||
|
npm/js and Cargo/Rust lead because applications using it have followed similar
|
||||||
|
patters with their versions.
|
||||||
|
|
||||||
|
Checking a version against version constraints is one of the most featureful
|
||||||
|
parts of the package.
|
||||||
|
|
||||||
|
```go
|
||||||
|
c, err := semver.NewConstraint(">= 1.2.3")
|
||||||
|
if err != nil {
|
||||||
|
// Handle constraint not being parsable.
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := semver.NewVersion("1.3")
|
||||||
|
if err != nil {
|
||||||
|
// Handle version not being parsable.
|
||||||
|
}
|
||||||
|
// Check if the version meets the constraints. The variable a will be true.
|
||||||
|
a := c.Check(v)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Basic Comparisons
|
||||||
|
|
||||||
|
There are two elements to the comparisons. First, a comparison string is a list
|
||||||
|
of space or comma separated AND comparisons. These are then separated by || (OR)
|
||||||
|
comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a
|
||||||
|
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
|
||||||
|
greater than or equal to 4.2.3.
|
||||||
|
|
||||||
|
The basic comparisons are:
|
||||||
|
|
||||||
|
* `=`: equal (aliased to no operator)
|
||||||
|
* `!=`: not equal
|
||||||
|
* `>`: greater than
|
||||||
|
* `<`: less than
|
||||||
|
* `>=`: greater than or equal to
|
||||||
|
* `<=`: less than or equal to
|
||||||
|
|
||||||
|
### Working With Prerelease Versions
|
||||||
|
|
||||||
|
Pre-releases, for those not familiar with them, are used for software releases
|
||||||
|
prior to stable or generally available releases. Examples of pre-releases include
|
||||||
|
development, alpha, beta, and release candidate releases. A pre-release may be
|
||||||
|
a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the
|
||||||
|
order of precedence, pre-releases come before their associated releases. In this
|
||||||
|
example `1.2.3-beta.1 < 1.2.3`.
|
||||||
|
|
||||||
|
According to the Semantic Version specification, pre-releases may not be
|
||||||
|
API compliant with their release counterpart. It says,
|
||||||
|
|
||||||
|
> A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version.
|
||||||
|
|
||||||
|
SemVer's comparisons using constraints without a pre-release comparator will skip
|
||||||
|
pre-release versions. For example, `>=1.2.3` will skip pre-releases when looking
|
||||||
|
at a list of releases while `>=1.2.3-0` will evaluate and find pre-releases.
|
||||||
|
|
||||||
|
The reason for the `0` as a pre-release version in the example comparison is
|
||||||
|
because pre-releases can only contain ASCII alphanumerics and hyphens (along with
|
||||||
|
`.` separators), per the spec. Sorting happens in ASCII sort order, again per the
|
||||||
|
spec. The lowest character is a `0` in ASCII sort order
|
||||||
|
(see an [ASCII Table](http://www.asciitable.com/))
|
||||||
|
|
||||||
|
Understanding ASCII sort ordering is important because A-Z comes before a-z. That
|
||||||
|
means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case
|
||||||
|
sensitivity doesn't apply here. This is due to ASCII sort ordering which is what
|
||||||
|
the spec specifies.
|
||||||
|
|
||||||
|
### Hyphen Range Comparisons
|
||||||
|
|
||||||
|
There are multiple methods to handle ranges and the first is hyphens ranges.
|
||||||
|
These look like:
|
||||||
|
|
||||||
|
* `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5`
|
||||||
|
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5`
|
||||||
|
|
||||||
|
Note that `1.2-1.4.5` without whitespace is parsed completely differently; it's
|
||||||
|
parsed as a single constraint `1.2.0` with _prerelease_ `1.4.5`.
|
||||||
|
|
||||||
|
### Wildcards In Comparisons
|
||||||
|
|
||||||
|
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
|
||||||
|
for all comparison operators. When used on the `=` operator it falls
|
||||||
|
back to the patch level comparison (see tilde below). For example,
|
||||||
|
|
||||||
|
* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
|
||||||
|
* `>= 1.2.x` is equivalent to `>= 1.2.0`
|
||||||
|
* `<= 2.x` is equivalent to `< 3`
|
||||||
|
* `*` is equivalent to `>= 0.0.0`
|
||||||
|
|
||||||
|
### Tilde Range Comparisons (Patch)
|
||||||
|
|
||||||
|
The tilde (`~`) comparison operator is for patch level ranges when a minor
|
||||||
|
version is specified and major level changes when the minor number is missing.
|
||||||
|
For example,
|
||||||
|
|
||||||
|
* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
|
||||||
|
* `~1` is equivalent to `>= 1, < 2`
|
||||||
|
* `~2.3` is equivalent to `>= 2.3, < 2.4`
|
||||||
|
* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
|
||||||
|
* `~1.x` is equivalent to `>= 1, < 2`
|
||||||
|
|
||||||
|
### Caret Range Comparisons (Major)
|
||||||
|
|
||||||
|
The caret (`^`) comparison operator is for major level changes once a stable
|
||||||
|
(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts
|
||||||
|
as the API stability level. This is useful when comparisons of API versions as a
|
||||||
|
major change is API breaking. For example,
|
||||||
|
|
||||||
|
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
|
||||||
|
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
|
||||||
|
* `^2.3` is equivalent to `>= 2.3, < 3`
|
||||||
|
* `^2.x` is equivalent to `>= 2.0.0, < 3`
|
||||||
|
* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0`
|
||||||
|
* `^0.2` is equivalent to `>=0.2.0 <0.3.0`
|
||||||
|
* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4`
|
||||||
|
* `^0.0` is equivalent to `>=0.0.0 <0.1.0`
|
||||||
|
* `^0` is equivalent to `>=0.0.0 <1.0.0`
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
In addition to testing a version against a constraint, a version can be validated
|
||||||
|
against a constraint. When validation fails a slice of errors containing why a
|
||||||
|
version didn't meet the constraint is returned. For example,
|
||||||
|
|
||||||
|
```go
|
||||||
|
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
|
||||||
|
if err != nil {
|
||||||
|
// Handle constraint not being parseable.
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := semver.NewVersion("1.3")
|
||||||
|
if err != nil {
|
||||||
|
// Handle version not being parseable.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate a version against a constraint.
|
||||||
|
a, msgs := c.Validate(v)
|
||||||
|
// a is false
|
||||||
|
for _, m := range msgs {
|
||||||
|
fmt.Println(m)
|
||||||
|
|
||||||
|
// Loops over the errors which would read
|
||||||
|
// "1.3 is greater than 1.2.3"
|
||||||
|
// "1.3 is less than 1.4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contribute
|
||||||
|
|
||||||
|
If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
|
||||||
|
or [create a pull request](https://github.com/Masterminds/semver/pulls).
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
Security is an important consideration for this project. The project currently
|
||||||
|
uses the following tools to help discover security issues:
|
||||||
|
|
||||||
|
* [CodeQL](https://github.com/Masterminds/semver)
|
||||||
|
* [gosec](https://github.com/securego/gosec)
|
||||||
|
* Daily Fuzz testing
|
||||||
|
|
||||||
|
If you believe you have found a security vulnerability you can privately disclose
|
||||||
|
it through the [GitHub security page](https://github.com/Masterminds/semver/security).
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user