Compare commits

...

2 Commits

Author SHA1 Message Date
Dustin 9679c78419 ci: Build container image
dustin/sshca-cli/pipeline/pr-master Build started... Details
dustin/sshca-cli/pipeline/head This commit looks good Details
In addition to building an RPM package for regular Fedora machines, we
now build a container image containing a statically-linked `sshca-cli`
executable.
2024-01-18 09:43:36 -06:00
Dustin 2b87aca9f1 Add rustls feature
The `rustls` feature will enable building with [rustls] instead of
OpenSSL.  This will make it so the `sshca-cli` binary can be statically
linked, and thus distributable as a single file.

[rustls]: https://github.com/rustls/rustls
2024-01-17 21:24:21 -06:00
9 changed files with 230 additions and 5 deletions

4
.containerignore Normal file
View File

@ -0,0 +1,4 @@
*
!src
!Cargo.lock
!Cargo.toml

78
Cargo.lock generated
View File

@ -419,6 +419,20 @@ dependencies = [
"want", "want",
] ]
[[package]]
name = "hyper-rustls"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
dependencies = [
"futures-util",
"http",
"hyper",
"rustls",
"tokio",
"tokio-rustls",
]
[[package]] [[package]]
name = "hyper-tls" name = "hyper-tls"
version = "0.5.0" version = "0.5.0"
@ -780,6 +794,7 @@ dependencies = [
"http", "http",
"http-body", "http-body",
"hyper", "hyper",
"hyper-rustls",
"hyper-tls", "hyper-tls",
"ipnet", "ipnet",
"js-sys", "js-sys",
@ -790,17 +805,21 @@ dependencies = [
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"rustls",
"rustls-pemfile",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"system-configuration", "system-configuration",
"tokio", "tokio",
"tokio-native-tls", "tokio-native-tls",
"tokio-rustls",
"tower-service", "tower-service",
"url", "url",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"web-sys", "web-sys",
"webpki-roots",
"winreg", "winreg",
] ]
@ -837,6 +856,37 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "rustls"
version = "0.21.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
dependencies = [
"log",
"ring",
"rustls-webpki",
"sct",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64",
]
[[package]]
name = "rustls-webpki"
version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
"ring",
"untrusted",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.15"
@ -852,6 +902,16 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring",
"untrusted",
]
[[package]] [[package]]
name = "security-framework" name = "security-framework"
version = "2.9.2" version = "2.9.2"
@ -970,7 +1030,7 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]] [[package]]
name = "sshca-cli" name = "sshca-cli"
version = "0.1.0" version = "0.1.1"
dependencies = [ dependencies = [
"argh", "argh",
"argon2", "argon2",
@ -1097,6 +1157,16 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tokio-rustls"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
"rustls",
"tokio",
]
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.10" version = "0.7.10"
@ -1352,6 +1422,12 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "webpki-roots"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10"
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"

View File

@ -12,9 +12,18 @@ argh = "0.1.12"
argon2 = { version = "0.5.2", default-features = false, features = ["alloc"] } argon2 = { version = "0.5.2", default-features = false, features = ["alloc"] }
gethostname = "0.4.3" gethostname = "0.4.3"
jsonwebtoken = { version = "9.1.0", default-features = false } jsonwebtoken = { version = "9.1.0", default-features = false }
reqwest = { version = "0.11.22", features = ["multipart"] } reqwest = { version = "0.11.22", default-features = false, features = ["multipart"] }
serde = { version = "1.0.190", features = ["derive"] } serde = { version = "1.0.190", features = ["derive"] }
tokio = { version = "1.33.0", features = ["rt", "macros"] } tokio = { version = "1.33.0", features = ["rt", "macros"] }
tracing = "0.1.40" tracing = "0.1.40"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
uuid = "1.5.0" uuid = "1.5.0"
[features]
default = ["native-tls"]
native-tls = [
"reqwest/default-tls",
]
rustls = [
"reqwest/rustls-tls",
]

18
Containerfile Normal file
View File

@ -0,0 +1,18 @@
FROM docker.io/library/rust:1.73-alpine AS build
COPY . /build
WORKDIR /build
RUN --mount=type=cache,target=/var/cache \
apk add --no-cache g++ \
&& :
RUN cargo build --release --no-default-features --features rustls \
&& strip target/release/sshca-cli
FROM scratch
COPY --from=build /build/target/release/sshca-cli /
ENTRYPOINT ["/sshca-cli"]

73
ci/Jenkinsfile vendored
View File

@ -2,7 +2,7 @@ pipeline {
agent none agent none
stages { stages {
stage('SSHCA CLI') { stage('RPM') {
matrix { matrix {
axes { axes {
axis { axis {
@ -16,7 +16,7 @@ pipeline {
} }
stages { stages {
stage('CLI') { stage('Build RPM') {
agent { agent {
kubernetes { kubernetes {
yamlFile 'ci/podTemplate.yaml' yamlFile 'ci/podTemplate.yaml'
@ -79,8 +79,73 @@ pipeline {
} }
} }
} }
}
}
stage('Build Container') {
matrix {
axes {
axis {
name 'ARCH'
values 'amd64', 'arm64'
}
}
stages {
stage('Container') {
agent {
kubernetes {
yamlFile 'ci/podTemplate-container.yaml'
yamlMergeStrategy merge()
defaultContainer 'buildah'
nodeSelector "kubernetes.io/arch=${ARCH}"
}
}
stages {
stage('Build') {
steps {
sh '. ci/build-container.sh'
stash name: env.ARCH, includes: "*.oci.tar"
}
}
}
}
}
}
}
stage('Publish Container') {
agent {
kubernetes {
yamlFile 'ci/podTemplate-container.yaml'
yamlMergeStrategy merge()
defaultContainer 'buildah'
}
}
environment {
REGISTRY_AUTH_FILE = "${env.WORKSPACE_TMP}/auth.json"
}
steps {
unstash 'amd64'
unstash 'arm64'
withCredentials([usernamePassword(
credentialsId: 'jenkins-packages',
usernameVariable: 'BUILDAH_USERNAME',
passwordVariable: 'BUILDAH_PASSWORD',
)]) {
sh """
buildah login \
--username \${BUILDAH_USERNAME} \
--password \${BUILDAH_PASSWORD} \
git.pyrocufflink.net
"""
}
sh '. ci/publish-container.sh'
}
}
} }
} }
}
}

6
ci/build-container.sh Normal file
View File

@ -0,0 +1,6 @@
. ci/common.sh
buildah build -t "${IMAGE_NAME}:${TAG}" .
buildah push \
"${IMAGE_NAME}:${TAG}" \
oci-archive:"${PWD}/${NAME}-${ARCH}.oci.tar:${IMAGE_NAME}:${TAG}"

13
ci/common.sh Normal file
View File

@ -0,0 +1,13 @@
escape_name() {
echo "$1" \
| tr A-Z a-z \
| sed -e 's/[^a-zA-Z0-9._-]/-/g' -e 's/^[.-]/_/'
}
REGISTRY_URL=git.pyrocufflink.net
NAMESPACE=containerimages
NAME="${JOB_NAME#*/}"
NAME=$(escape_name "${NAME%/*}")
TAG=$(escape_name "${BRANCH_NAME}")
IMAGE_NAME="${REGISTRY_URL}/${NAMESPACE}/${NAME}"

View File

@ -0,0 +1,19 @@
spec:
containers:
- name: buildah
image: quay.io/containers/buildah:v1
command:
- cat
stdin: true
tty: true
securityContext:
capabilities:
add:
- SYS_ADMIN
- MKNOD
- SYS_CHROOT
- SETFCAP
resources:
limits:
github.com/fuse: 1
hostUsers: false

15
ci/publish-container.sh Normal file
View File

@ -0,0 +1,15 @@
. ci/common.sh
buildah manifest create "${IMAGE_NAME}:${TAG}"
for arch in amd64 arm64; do
buildah manifest add "${IMAGE_NAME}:${TAG}" \
oci-archive:"${PWD}/${NAME}-${arch}.oci.tar:${IMAGE_NAME}:${TAG}"
done
buildah manifest push --all "${IMAGE_NAME}:${TAG}" \
"docker://${IMAGE_NAME}:${TAG}-${BUILD_NUMBER}"
buildah manifest push "${IMAGE_NAME}:${TAG}" "docker://${IMAGE_NAME}:${TAG}"
if [ ${BRANCH_NAME} = master ]; then
buildah manifest push "${IMAGE_NAME}:${TAG}" \
"docker://${IMAGE_NAME}:latest"
fi