Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ validate-source_task:
image_name: "${FEDORA_CACHE_IMAGE_NAME}" # from stdenvars
env:
TEST_FLAVOR: validate-source
TEST_BUILD_TAGS: ""
# NOTE: The default way Cirrus-CI clones is *NOT* compatible with
# environment expectations in contrib/cirrus/lib.sh. Specifically
# the 'origin' remote must be defined, and all remote branches/tags
Expand Down Expand Up @@ -151,23 +152,27 @@ build_task:
# Ref: https://cirrus-ci.org/guide/writing-tasks/#matrix-modification
- env: &stdenvars
DISTRO_NV: ${FEDORA_NAME}
TEST_BUILD_TAGS: ""
# Not used here, is used in other tasks
VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
- env:
DISTRO_NV: ${PRIOR_FEDORA_NAME}
TEST_BUILD_TAGS: ""
VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
CI_DESIRED_DATABASE: boltdb
CI_DESIRED_STORAGE: vfs
- env:
<<: *stdenvars
DISTRO_NV: ${RAWHIDE_NAME}
TEST_BUILD_TAGS: "containers_image_sequoia"
VM_IMAGE_NAME: ${RAWHIDE_CACHE_IMAGE_NAME}
CI_DESIRED_STORAGE: composefs
CTR_FQIN: ""
- env:
DISTRO_NV: ${DEBIAN_NAME}
TEST_BUILD_TAGS: ""
VM_IMAGE_NAME: ${DEBIAN_CACHE_IMAGE_NAME}
env:
TEST_FLAVOR: build
Expand Down Expand Up @@ -209,6 +214,7 @@ build_aarch64_task:
VM_IMAGE_NAME: ${FEDORA_AARCH64_AMI}
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
TEST_FLAVOR: build
TEST_BUILD_TAGS: ""
clone_script: *full_clone
# TODO: Rename to "ci-sanity" and move into task that runs in parallel to build
prebuild_script: *prebuild
Expand Down Expand Up @@ -236,6 +242,7 @@ alt_build_task:
env:
<<: *stdenvars
TEST_FLAVOR: "altbuild"
TEST_BUILD_TAGS: ""
gce_instance: *fastvm
matrix:
- env:
Expand Down Expand Up @@ -402,6 +409,7 @@ bindings_task:
env:
<<: *stdenvars
TEST_FLAVOR: bindings
TEST_BUILD_TAGS: ""
# N/B: This script depends on ${DISTRO_NV} being defined for the task.
clone_script: &get_gosrc |
cd /tmp
Expand Down Expand Up @@ -443,6 +451,7 @@ swagger_task:
GCPJSON: ENCRYPTED[927dc01e755eaddb4242b0845cf86c9098d1e3dffac38c70aefb1487fd8b4fe6dd6ae627b3bffafaba70e2c63172664e]
GCPNAME: ENCRYPTED[c145e9c16b6fb88d476944a454bf4c1ccc84bb4ecaca73bdd28bdacef0dfa7959ebc8171a27b2e4064d66093b2cdba49]
GCPPROJECT: 'libpod-218412'
TEST_BUILD_TAGS: ""
clone_script: *get_gosrc
setup_script: *setup
main_script: *main
Expand Down Expand Up @@ -536,6 +545,7 @@ docker-py_test_task:
<<: *stdenvars
TEST_FLAVOR: docker-py
TEST_ENVIRON: container
TEST_BUILD_TAGS: ""
clone_script: *get_gosrc
setup_script: *setup
main_script: *main
Expand Down Expand Up @@ -568,6 +578,7 @@ unit_test_task:
gce_instance: *standardvm
env:
TEST_FLAVOR: unit
TEST_BUILD_TAGS: ""
clone_script: *get_gosrc
setup_script: *setup
main_script: *main
Expand Down Expand Up @@ -630,6 +641,7 @@ apiv2_test_task:
env:
<<: *stdenvars
TEST_FLAVOR: apiv2
TEST_BUILD_TAGS: ""
matrix:
- env:
PRIV_NAME: root
Expand Down Expand Up @@ -664,6 +676,7 @@ compose_test_task:
env:
<<: *stdenvars
TEST_FLAVOR: compose_v2
TEST_BUILD_TAGS: ""
clone_script: *get_gosrc
setup_script: *setup
main_script: *main
Expand Down Expand Up @@ -736,6 +749,7 @@ container_integration_test_task:
env:
TEST_FLAVOR: int
TEST_ENVIRON: container
TEST_BUILD_TAGS: ""
clone_script: *get_gosrc
setup_script: *setup
main_script: *main
Expand Down Expand Up @@ -780,6 +794,7 @@ podman_machine_task:
env:
EC2_INST_TYPE: "m5zn.metal" # Bare-metal instance is required
TEST_FLAVOR: "machine-linux"
TEST_BUILD_TAGS: ""
PRIV_NAME: "rootless" # intended use-case
DISTRO_NV: "${FEDORA_NAME}"
VM_IMAGE_NAME: "${FEDORA_AMI}"
Expand All @@ -799,6 +814,7 @@ podman_machine_aarch64_task:
timeout_in: 30m
env:
TEST_FLAVOR: "machine-linux"
TEST_BUILD_TAGS: ""
EC2_INST_TYPE: c6g.metal
PRIV_NAME: "rootless" # intended use-case
DISTRO_NV: "${FEDORA_AARCH64_NAME}"
Expand Down Expand Up @@ -954,6 +970,7 @@ local_system_test_aarch64_task: &local_system_test_task_aarch64
env:
<<: *stdenvars_aarch64
TEST_FLAVOR: sys
TEST_BUILD_TAGS: ""
DISTRO_NV: ${FEDORA_AARCH64_NAME}
clone_script: *get_gosrc_aarch64
setup_script: *setup
Expand Down Expand Up @@ -1031,6 +1048,7 @@ farm_test_task:
env:
<<: *stdenvars
TEST_FLAVOR: farm
TEST_BUILD_TAGS: ""
PRIV_NAME: rootless
clone_script: *get_gosrc
setup_script: *setup
Expand All @@ -1053,6 +1071,7 @@ buildah_bud_test_task:
env:
<<: *stdenvars
TEST_FLAVOR: bud
TEST_BUILD_TAGS: ""
matrix:
- env:
PODBIN_NAME: podman
Expand Down Expand Up @@ -1090,6 +1109,7 @@ upgrade_test_task:
gce_instance: *standardvm
env:
TEST_FLAVOR: upgrade_test
TEST_BUILD_TAGS: ""
DISTRO_NV: ${FEDORA_NAME}
VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
# Never force a DB, let the old version decide its default
Expand Down Expand Up @@ -1238,6 +1258,7 @@ release_task:
env:
<<: *stdenvars
TEST_FLAVOR: release
TEST_BUILD_TAGS: ""
clone_script: *get_gosrc
setup_script: *setup
main_script: *main
Expand Down Expand Up @@ -1265,6 +1286,7 @@ release_test_task:
env:
<<: *stdenvars
TEST_FLAVOR: release
TEST_BUILD_TAGS: ""
clone_script: *get_gosrc
setup_script: *setup
main_script: *main
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ SYSTEMDDIR ?= ${LIBDIR}/systemd/system
USERSYSTEMDDIR ?= ${LIBDIR}/systemd/user
SYSTEMDGENERATORSDIR ?= ${LIBDIR}/systemd/system-generators
USERSYSTEMDGENERATORSDIR ?= ${LIBDIR}/systemd/user-generators
SEQUOIA_SONAME_DIR =
REMOTETAGS ?= remote exclude_graphdriver_btrfs containers_image_openpgp
BUILDTAGS ?= \
grpcnotrace \
Expand Down Expand Up @@ -131,6 +132,7 @@ LDFLAGS_PODMAN ?= \
-X $(LIBPOD)/config._installPrefix=$(PREFIX) \
-X $(LIBPOD)/config._etcDir=$(ETCDIR) \
-X $(PROJECT)/v5/pkg/systemd/quadlet._binDir=$(BINDIR) \
-X go.podman.io/image/v5/signature/internal/sequoia.sequoiaLibraryDir='"$(SEQUOIA_SONAME_DIR)"' \
-X go.podman.io/common/pkg/config.additionalHelperBinariesDir=$(HELPER_BINARIES_DIR)\
$(EXTRA_LDFLAGS)
LDFLAGS_PODMAN_STATIC ?= \
Expand Down
49 changes: 45 additions & 4 deletions cmd/podman/common/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import (
"go.podman.io/image/v5/pkg/cli"
"go.podman.io/image/v5/pkg/cli/sigstore"
"go.podman.io/image/v5/signature/signer"
"go.podman.io/image/v5/signature/simplesequoia"
)

// SigningCLIOnlyOptions contains signing-related CLI options.
// Some other options are defined in entities.ImagePushOptions.
type SigningCLIOnlyOptions struct {
signPassphraseFile string
signBySigstoreParamFile string
signPassphraseFile string
signBySequoiaFingerprint string
signBySigstoreParamFile string
}

func DefineSigningFlags(cmd *cobra.Command, cliOpts *SigningCLIOnlyOptions, pushOpts *entities.ImagePushOptions) {
Expand All @@ -28,6 +30,10 @@ func DefineSigningFlags(cmd *cobra.Command, cliOpts *SigningCLIOnlyOptions, push
flags.StringVar(&pushOpts.SignBy, signByFlagName, "", "Add a signature at the destination using the specified key")
_ = cmd.RegisterFlagCompletionFunc(signByFlagName, completion.AutocompleteNone)

signBySequoiaFingerprintFlagName := "sign-by-sq-fingerprint"
flags.StringVar(&cliOpts.signBySequoiaFingerprint, signBySequoiaFingerprintFlagName, "", "Sign the image using a Sequoia-PGP key with the specified `FINGERPRINT`")
_ = cmd.RegisterFlagCompletionFunc(signBySequoiaFingerprintFlagName, completion.AutocompleteNone)

signBySigstoreFlagName := "sign-by-sigstore"
flags.StringVar(&cliOpts.signBySigstoreParamFile, signBySigstoreFlagName, "", "Sign the image using a sigstore parameter file at `PATH`")
_ = cmd.RegisterFlagCompletionFunc(signBySigstoreFlagName, completion.AutocompleteDefault)
Expand All @@ -42,6 +48,7 @@ func DefineSigningFlags(cmd *cobra.Command, cliOpts *SigningCLIOnlyOptions, push

if registry.IsRemote() {
_ = flags.MarkHidden(signByFlagName)
_ = flags.MarkHidden(signBySequoiaFingerprintFlagName)
_ = flags.MarkHidden(signBySigstoreFlagName)
_ = flags.MarkHidden(signBySigstorePrivateKeyFlagName)
_ = flags.MarkHidden(signPassphraseFileFlagName)
Expand All @@ -57,8 +64,20 @@ func PrepareSigning(pushOpts *entities.ImagePushOptions, cliOpts *SigningCLIOnly
// c/common/libimage.Image does allow creating both simple signing and sigstore signatures simultaneously,
// with independent passphrases, but that would make the CLI probably too confusing.
// For now, use the passphrase with either, but only one of them.
if cliOpts.signPassphraseFile != "" && pushOpts.SignBy != "" && pushOpts.SignBySigstorePrivateKeyFile != "" {
return nil, fmt.Errorf("only one of --sign-by and sign-by-sigstore-private-key can be used with --sign-passphrase-file")
if cliOpts.signPassphraseFile != "" {
count := 0
if pushOpts.SignBy != "" {
count++
}
if cliOpts.signBySequoiaFingerprint != "" {
count++
}
if pushOpts.SignBySigstorePrivateKeyFile != "" {
count++
}
if count > 1 {
return nil, fmt.Errorf("only one of --sign-by, --sign-by-sq-fingerprint and --sign-by-sigstore-private-key can be used with --sign-passphrase-file")
}
}

var passphrase string
Expand All @@ -72,9 +91,16 @@ func PrepareSigning(pushOpts *entities.ImagePushOptions, cliOpts *SigningCLIOnly
p := ssh.ReadPassphrase()
passphrase = string(p)
} // pushOpts.SignBy triggers a GPG-agent passphrase prompt, possibly using a more secure channel, so we usually shouldn’t prompt ourselves if no passphrase was explicitly provided.
// With signBySequoiaFingerprint, we don’t prompt for a passphrase (for now??): We don’t know whether the key requires a passphrase.
pushOpts.SignPassphrase = passphrase
pushOpts.SignSigstorePrivateKeyPassphrase = []byte(passphrase)
cleanup := signingCleanup{}
succeeded := false
defer func() {
if !succeeded {
cleanup.cleanup()
}
}()
if cliOpts.signBySigstoreParamFile != "" {
signer, err := sigstore.NewSignerFromParameterFile(cliOpts.signBySigstoreParamFile, &sigstore.Options{
PrivateKeyPassphrasePrompt: cli.ReadPassphraseFile,
Expand All @@ -87,6 +113,21 @@ func PrepareSigning(pushOpts *entities.ImagePushOptions, cliOpts *SigningCLIOnly
pushOpts.Signers = append(pushOpts.Signers, signer)
cleanup.signers = append(cleanup.signers, signer)
}
if cliOpts.signBySequoiaFingerprint != "" {
opts := []simplesequoia.Option{
simplesequoia.WithKeyFingerprint(cliOpts.signBySequoiaFingerprint),
}
if passphrase != "" {
opts = append(opts, simplesequoia.WithPassphrase(passphrase))
}
signer, err := simplesequoia.NewSigner(opts...)
if err != nil {
return nil, fmt.Errorf("error using --sign-by-sq-fingerprint: %w", err)
}
pushOpts.Signers = append(pushOpts.Signers, signer)
cleanup.signers = append(cleanup.signers, signer)
}
succeeded = true
return cleanup.cleanup, nil
}

Expand Down
5 changes: 3 additions & 2 deletions contrib/cirrus/runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ function _run_build() {
# Ensure always start from clean-slate with all vendor modules downloaded
showrun make clean
showrun make vendor
showrun make -j $(nproc) --output-sync=target podman-release # includes podman, podman-remote, and docs
# shellcheck disable=SC2154
showrun make -j $(nproc) --output-sync=target podman-release EXTRA_BUILDTAGS="$TEST_BUILD_TAGS" # includes podman, podman-remote, and docs

# There's no reason to validate-binaries across multiple linux platforms
# shellcheck disable=SC2154
Expand Down Expand Up @@ -416,7 +417,7 @@ dotest() {
die "The CI test TMPDIR is not on a tmpfs mount, we need tmpfs to make the tests faster"
fi

showrun make ${localremote}${testsuite} PODMAN_SERVER_LOG=$PODMAN_SERVER_LOG \
showrun make ${localremote}${testsuite} PODMAN_SERVER_LOG=$PODMAN_SERVER_LOG EXTRA_BUILDTAGS="$TEST_BUILD_TAGS" \
|& logformatter

# FIXME: https://github.com/containers/podman/issues/22642
Expand Down
4 changes: 2 additions & 2 deletions contrib/cirrus/setup_environment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -422,11 +422,11 @@ case "$TEST_FLAVOR" in
die "Refusing to config. host-test in container";
fi
remove_packaged_podman_files
make install PREFIX=/usr ETCDIR=/etc
make install PREFIX=/usr ETCDIR=/etc EXTRA_BUILDTAGS="$TEST_BUILD_TAGS"
elif [[ "$TEST_ENVIRON" == "container" ]]; then
if ((CONTAINER)); then
remove_packaged_podman_files
make install PREFIX=/usr ETCDIR=/etc
make install PREFIX=/usr ETCDIR=/etc EXTRA_BUILDTAGS="$TEST_BUILD_TAGS"
fi
else
die "Invalid value for \$TEST_ENVIRON=$TEST_ENVIRON"
Expand Down
8 changes: 8 additions & 0 deletions docs/source/markdown/options/sign-by-sq-fingerprint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
####> This option file is used in:
####> podman artifact push, manifest push, push
####> If file is edited, make sure the changes
####> are applicable to all of those.
#### **--sign-by-sq-fingerprint**=*fingerprint*

Add a “simple signing” signature using a Sequoia-PGP key with the specified fingerprint.
(This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)
This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines.

Not a strong suggestion, but I'd remove the first set of parens here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Searching for “This option is not available with”, there are ~40 other instances which parenthesize this, or a similar, remark.

I have no preference at all as to whether this should be parenthesized.

2 changes: 1 addition & 1 deletion docs/source/markdown/options/sign-passphrase-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
####> are applicable to all of those.
#### **--sign-passphrase-file**=*path*

If signing the image (using either **--sign-by** or **--sign-by-sigstore-private-key**), read the passphrase to use from the specified path.
If signing the image (using **--sign-by**, **sign-by-sq-fingerprint** or **--sign-by-sigstore-private-key**), read the passphrase to use from the specified path.
3 changes: 2 additions & 1 deletion docs/source/markdown/podman-artifact-push.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ Add a “simple signing” signature at the destination using the specified key.

@@option sign-by-sigstore


#### **--sign-by-sigstore-private-key**=*path*

Add a sigstore signature at the destination using a private key at the specified path. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)

@@option sign-by-sq-fingerprint

@@option sign-passphrase-file

@@option tls-verify
Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-manifest-push.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ Sign the pushed images with a “simple signing” signature using the specified

Sign the pushed images with a sigstore signature using a private key at the specified path. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)

@@option sign-by-sq-fingerprint

@@option sign-passphrase-file

@@option tls-verify
Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-push.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ Add a “simple signing” signature at the destination using the specified key.

Add a sigstore signature at the destination using a private key at the specified path. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)

@@option sign-by-sq-fingerprint

@@option sign-passphrase-file

@@option tls-verify
Expand Down
13 changes: 10 additions & 3 deletions test/e2e/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1309,8 +1309,8 @@ func (p *PodmanTestIntegration) removeNetwork(name string) {

// generatePolicyFile generates a signature verification policy file.
// it returns the policy file path.
func generatePolicyFile(tempDir string, port int) string {
keyPath := filepath.Join(tempDir, "key.gpg")
func generatePolicyFile(tempDir string, port int, sequoiaKeyPath string) string {
gpgKeyPath := filepath.Join(tempDir, "key.gpg")
policyPath := filepath.Join(tempDir, "policy.json")
conf := fmt.Sprintf(`
{
Expand Down Expand Up @@ -1339,11 +1339,18 @@ func generatePolicyFile(tempDir string, port int) string {
"type": "sigstoreSigned",
"keyPath": "testdata/sigstore-key.pub"
}
],
"localhost:%[1]d/simple-sq-signed": [
{
"type": "signedBy",
"keyType": "GPGKeys",
"keyPath": "%[3]s"
}
]
}
}
}
`, port, keyPath)
`, port, gpgKeyPath, sequoiaKeyPath)
writeConf([]byte(conf), policyPath)
return policyPath
}
Expand Down
Loading