git: initial commit
This commit is contained in:
commit
393bc80c03
9 changed files with 460 additions and 0 deletions
3
.dockerignore
Normal file
3
.dockerignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
.git
|
||||
.dockerignore
|
||||
target
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
290
Cargo.lock
generated
Normal file
290
Cargo.lock
generated
Normal file
|
@ -0,0 +1,290 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
"textwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "woodpecker-buildkit"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"clap",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "woodpecker-buildkit"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "3", features = ["env", "derive"] }
|
||||
base64 = "0"
|
||||
serde_json = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
12
Dockerfile
Normal file
12
Dockerfile
Normal file
|
@ -0,0 +1,12 @@
|
|||
FROM rust:alpine AS builder
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
COPY . .
|
||||
RUN cargo install --path .
|
||||
|
||||
FROM alpine:3
|
||||
|
||||
COPY --from=builder /usr/local/cargo/bin/app /usr/local/bin/buildkit-plugin
|
||||
COPY --from=moby/buildkit /usr/bin/buildctl /usr/bin/buildctl
|
||||
|
||||
CMD ["buildkit-plugin"]
|
45
src/auth.rs
Normal file
45
src/auth.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
use std::{fs, collections::HashMap};
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::error::{Redacted, redact};
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Logins {
|
||||
auths: HashMap<String, Credentials>
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Credentials {
|
||||
auth: String
|
||||
}
|
||||
|
||||
impl Credentials {
|
||||
fn new(username: &str, password: &str) -> Credentials {
|
||||
let mut s = String::new();
|
||||
s.push_str(username);
|
||||
s.push_str(":");
|
||||
s.push_str(password);
|
||||
Credentials {
|
||||
auth: base64::encode(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn login(registry: &str, username: &str, password: &str) -> Result<(), Redacted> {
|
||||
let home = std::env::var("HOME").unwrap();
|
||||
redact(fs::create_dir_all(format!("{}/.docker", home)), password)?;
|
||||
let mut auths = HashMap::new();
|
||||
|
||||
auths.insert(String::from(registry), Credentials::new(username, password));
|
||||
|
||||
let data = Logins {
|
||||
auths
|
||||
};
|
||||
|
||||
let file = redact(fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.open(format!("{}/.docker/config.json", home)), password)?;
|
||||
redact(serde_json::to_writer(file, &data), password)
|
||||
}
|
15
src/cmd.rs
Normal file
15
src/cmd.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
pub fn gen_args(config: &crate::Cli) -> Vec<String> {
|
||||
let mut args = vec![String::from("buildctl"), String::from("build"), String::from("--frontend=dockerfile.v0")];
|
||||
|
||||
// Context
|
||||
args.push(String::from("--local"));
|
||||
args.push(format!("context={}", config.context));
|
||||
|
||||
args.push(String::from("--local"));
|
||||
args.push(format!("dockerfile={}", config.dockerfile));
|
||||
|
||||
args.push(String::from("--output"));
|
||||
args.push(format!("type=image,name={}{},push=true", config.registry, config.repo));
|
||||
|
||||
args
|
||||
}
|
38
src/error.rs
Normal file
38
src/error.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
pub struct Redacted {
|
||||
inner: Box<dyn Error>,
|
||||
target: String,
|
||||
}
|
||||
|
||||
pub fn redact<T, E: Error + 'static>(r: Result<T, E>, target: &str) -> Result<T, Redacted> {
|
||||
match r {
|
||||
Err(e) => Err(Redacted {
|
||||
inner: Box::new(e),
|
||||
target: String::from(target),
|
||||
}),
|
||||
Ok(v) => Ok(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for Redacted { }
|
||||
|
||||
impl Redacted {
|
||||
fn format(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let s = format!("{}", self.inner);
|
||||
write!(f, "{}", s.replace(&self.target, "<redacted>"))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Redacted {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Redacted {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
44
src/main.rs
Normal file
44
src/main.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
use clap::Parser;
|
||||
|
||||
mod cmd;
|
||||
mod auth;
|
||||
mod error;
|
||||
|
||||
use std::{process::{Command, Stdio}, os::unix::process::CommandExt};
|
||||
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(name = "ci-buildkit")]
|
||||
#[clap(about = "Buildkit for Drone/Woodpecker", long_about = None)]
|
||||
pub struct Cli {
|
||||
#[clap(short = 'R', long = "registry", env = "PLUGIN_REGISTRY", default_value = "docker.io")]
|
||||
registry: String,
|
||||
#[clap(short = 'r', long = "repo", env = "PLUGIN_REPO")]
|
||||
repo: String,
|
||||
#[clap(short = 'u', long = "username", env = "PLUGIN_USERNAME")]
|
||||
username: String,
|
||||
#[clap(short = 'p', long = "password", hide_env = true, env = "PLUGIN_PASSWORD")]
|
||||
password: String,
|
||||
#[clap(short = 'd', long = "dockerfile", env = "PLUGIN_DOCKERFILE", default_value = ".")]
|
||||
dockerfile: String,
|
||||
#[clap(short = 'c', long = "context", env = "PLUGIN_CONTEXT", default_value = ".")]
|
||||
context: String,
|
||||
#[clap(short = 't', long = "tag", env = "PLUGIN_TAG", default_value = "latest")]
|
||||
tag: String,
|
||||
#[clap(short = 'i', long = "pull", env = "PLUGIN_PULL_IMAGE")]
|
||||
pull_image: bool,
|
||||
}
|
||||
|
||||
fn main() -> Result<(), error::Redacted> {
|
||||
let args = Cli::parse();
|
||||
|
||||
auth::login(&args.registry, &args.username, &args.password)?;
|
||||
|
||||
|
||||
error::redact(Err(Command::new("/usr/bin/env")
|
||||
.args(cmd::gen_args(&args))
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::inherit())
|
||||
.stderr(Stdio::inherit())
|
||||
.exec()), &args.password)
|
||||
}
|
Reference in a new issue