diff --git a/example/rust-bin/.dockerignore b/example/rust-bin/.dockerignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/example/rust-bin/.dockerignore @@ -0,0 +1 @@ +target/ diff --git a/example/rust-bin/.gitignore b/example/rust-bin/.gitignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/example/rust-bin/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/example/rust-bin/Cargo.lock b/example/rust-bin/Cargo.lock new file mode 100644 index 0000000..b425a03 --- /dev/null +++ b/example/rust-bin/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "rust-bin" +version = "0.1.0" diff --git a/example/rust-bin/Cargo.toml b/example/rust-bin/Cargo.toml new file mode 100644 index 0000000..c97aa53 --- /dev/null +++ b/example/rust-bin/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust-bin" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/example/rust-bin/main.go b/example/rust-bin/main.go new file mode 100644 index 0000000..d81ab4c --- /dev/null +++ b/example/rust-bin/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "context" + "log" + + "git.front.kjuulh.io/kjuulh/bust/pkg/builder" + "git.front.kjuulh.io/kjuulh/bust/pkg/pipelines" +) + +func main() { + ctx := context.Background() + + if err := run(ctx); err != nil { + log.Fatal(err) + } +} +func run(ctx context.Context) error { + builder, err := builder.New(ctx) + if err != nil { + return err + } + defer builder.CleanUp() + + return pipelines. + New(builder). + WithRustBin(&pipelines.RustBinOpts{ + DockerImageOpt: &pipelines.DockerImageOpt{ + ImageName: "rust-bin", + }, + BinName: "rust-bin", + }). + Execute(ctx) +} diff --git a/example/rust-bin/src/main.rs b/example/rust-bin/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/example/rust-bin/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/pkg/cli/build.go b/pkg/cli/build.go index 33c9822..a47a79b 100644 --- a/pkg/cli/build.go +++ b/pkg/cli/build.go @@ -10,6 +10,7 @@ func Build() *cobra.Command { } cmd.AddCommand( + BuildRustBin(), BuildGolangBin(), BuildDocker(), ) diff --git a/pkg/cli/build_rust_bin.go b/pkg/cli/build_rust_bin.go new file mode 100644 index 0000000..e6eab80 --- /dev/null +++ b/pkg/cli/build_rust_bin.go @@ -0,0 +1,52 @@ +package cli + +import ( + "errors" + "os" + + "git.front.kjuulh.io/kjuulh/bust/pkg/builder" + "git.front.kjuulh.io/kjuulh/bust/pkg/pipelines" + "github.com/spf13/cobra" +) + +func BuildRustBin() *cobra.Command { + var ( + binName string + ) + + cmd := &cobra.Command{ + Use: "rustbin", + RunE: func(cmd *cobra.Command, args []string) error { + if err := cmd.ParseFlags(args); err != nil { + return err + } + + repoName := os.Getenv("DRONE_REPO_NAME") + if repoName == "" { + return errors.New("could not find DRONE_REPO_NAME") + } + + ctx := cmd.Context() + + builder, err := builder.New(ctx) + if err != nil { + return err + } + defer builder.CleanUp() + + return pipelines. + New(builder). + WithRustBin(&pipelines.RustBinOpts{ + DockerImageOpt: &pipelines.DockerImageOpt{ + ImageName: repoName, + }, + BinName: binName, + }). + Execute(ctx) + }, + } + + cmd.PersistentFlags().StringVar(&binName, "bin-name", "", "bin-name is the binary to build, and what will be present in the output folder") + + return cmd +} diff --git a/pkg/cli/templatecmd/init.go b/pkg/cli/templatecmd/init.go index f3e01d2..5bb2145 100644 --- a/pkg/cli/templatecmd/init.go +++ b/pkg/cli/templatecmd/init.go @@ -19,6 +19,9 @@ var docker embed.FS //go:embed templates/default/* var defaultFs embed.FS +//go:embed templates/rustbin_default/* +var rustbinDefault embed.FS + func NewInitCmd() *cobra.Command { var ( template string @@ -48,6 +51,11 @@ func NewInitCmd() *cobra.Command { return err } break + case "rustbin_default": + if err := initializeTemplate(&rustbinDefault, "rustbin_default", name); err != nil { + return err + } + break default: return errors.New("could not find matching templates, please run [bust template ls] instead") } diff --git a/pkg/cli/templatecmd/ls.go b/pkg/cli/templatecmd/ls.go index cf0b6c1..bf8f690 100644 --- a/pkg/cli/templatecmd/ls.go +++ b/pkg/cli/templatecmd/ls.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" ) -var templates = []string{"docker", "gobin_default", "default"} +var templates = []string{"docker", "gobin_default", "default", "rustbin_default"} func NewLsCmd() *cobra.Command { return &cobra.Command{ diff --git a/pkg/cli/templatecmd/templates/rustbin_default/.drone.yml b/pkg/cli/templatecmd/templates/rustbin_default/.drone.yml new file mode 100644 index 0000000..ba3e0ba --- /dev/null +++ b/pkg/cli/templatecmd/templates/rustbin_default/.drone.yml @@ -0,0 +1,5 @@ +kind: template +load: bust_rustbin_default_template.yaml +name: [[.Name]] +data: + bin_name: default diff --git a/pkg/pipelines/golang-bin.go b/pkg/pipelines/golang-bin.go index a8724f1..5ba1fc8 100644 --- a/pkg/pipelines/golang-bin.go +++ b/pkg/pipelines/golang-bin.go @@ -9,10 +9,10 @@ import ( "time" "dagger.io/dagger" - "git.front.kjuulh.io/kjuulh/byg" "git.front.kjuulh.io/kjuulh/bust/pkg/tasks/container" "git.front.kjuulh.io/kjuulh/bust/pkg/tasks/golang" golangbin "git.front.kjuulh.io/kjuulh/bust/pkg/tasks/golang-bin" + "git.front.kjuulh.io/kjuulh/byg" ) type DockerImageOpt struct { diff --git a/pkg/pipelines/pipeline.go b/pkg/pipelines/pipeline.go index 2b69584..3f54eb0 100644 --- a/pkg/pipelines/pipeline.go +++ b/pkg/pipelines/pipeline.go @@ -3,8 +3,8 @@ package pipelines import ( "context" - "git.front.kjuulh.io/kjuulh/byg" "git.front.kjuulh.io/kjuulh/bust/pkg/builder" + "git.front.kjuulh.io/kjuulh/byg" "golang.org/x/sync/errgroup" ) diff --git a/pkg/pipelines/rust-bin.go b/pkg/pipelines/rust-bin.go new file mode 100644 index 0000000..a80811c --- /dev/null +++ b/pkg/pipelines/rust-bin.go @@ -0,0 +1,105 @@ +package pipelines + +import ( + "context" + "fmt" + "log" + "path" + "strconv" + "time" + + "dagger.io/dagger" + "git.front.kjuulh.io/kjuulh/bust/pkg/tasks/container" + rustbin "git.front.kjuulh.io/kjuulh/bust/pkg/tasks/rust-bin" + "git.front.kjuulh.io/kjuulh/byg" +) + +type RustBinOpts struct { + *DockerImageOpt + BinName string + BaseImage string +} + +func (p *Pipeline) WithRustBin(opts *RustBinOpts) *Pipeline { + log.Printf("building image: %s", opts.ImageName) + + client := p.builder.Dagger + ctx := context.Background() + + var ( + bin dagger.FileID + finalImage *dagger.Container + ) + + pipeline := byg. + New(). + Step( + "build rust", + byg.Step{ + Execute: func(_ byg.Context) error { + var err error + c := container.LoadImage(client, "harbor.server.kjuulh.io/docker-proxy/library/rust") + c, err = container.MountCurrent(ctx, client, c, "/src") + if err != nil { + return err + } + c = container.Workdir(c, "/src") + + if bin, err = rustbin.Build(ctx, c, opts.BinName); err != nil { + return err + } + + return err + }, + }, + ). + Step( + "create-production-image", + byg.Step{ + Execute: func(_ byg.Context) error { + if opts.BaseImage == "" { + opts.BaseImage = "harbor.server.kjuulh.io/docker-proxy/library/alpine" + } + + binpath := "/usr/bin" + usrbin := path.Join(binpath, opts.BinName) + c := container.LoadImage(client, opts.BaseImage) + c = c.Exec(dagger.ContainerExecOpts{ + Args: []string{"mkdir", "-p", binpath}, + }) + _, err := c.ExitCode(ctx) + if err != nil { + return err + } + + c, err = container.MountFileFromLoaded(ctx, c, bin, usrbin) + if err != nil { + return err + } + finalImage = c + + return nil + }, + }, + ). + Step( + "upload-image", + byg.Step{ + Execute: func(_ byg.Context) error { + + if opts.ImageTag == "" { + opts.ImageTag = strconv.FormatInt(time.Now().UTC().UnixMilli(), 10) + } + + tag := fmt.Sprintf("harbor.server.kjuulh.io/kjuulh/%s:%s", opts.ImageName, opts.ImageTag) + + _, err := finalImage.Publish(ctx, tag) + return err + }, + }, + ) + + p.add(pipeline) + + return p +} diff --git a/pkg/tasks/rust-bin/build.go b/pkg/tasks/rust-bin/build.go new file mode 100644 index 0000000..93ebaa2 --- /dev/null +++ b/pkg/tasks/rust-bin/build.go @@ -0,0 +1,43 @@ +package rustbin + +import ( + "context" + "fmt" + "log" + + "dagger.io/dagger" +) + +func Build(ctx context.Context, container *dagger.Container, binName string) (dagger.FileID, error) { + log.Printf("building binary: (binName=%s)", binName) + c := container.Exec(dagger.ContainerExecOpts{ + Args: []string{ + "rustup", + "target", + "add", + "x86_64-unknown-linux-musl", + }, + }) + if _, err := c.ExitCode(ctx); err != nil { + return "", err + } + + c = c.Exec(dagger.ContainerExecOpts{ + Args: []string{ + "cargo", + "build", + "--release", + "--target=x86_64-unknown-linux-musl", + }, + }) + if _, err := c.ExitCode(ctx); err != nil { + return "", err + } + + bin, err := c.File(fmt.Sprintf("target/release/%s", binName)).ID(ctx) + if err != nil { + return "", err + } + + return bin, nil +} diff --git a/templates/bust_rustbin_default_template.yaml b/templates/bust_rustbin_default_template.yaml new file mode 100644 index 0000000..ef508fa --- /dev/null +++ b/templates/bust_rustbin_default_template.yaml @@ -0,0 +1,40 @@ +type: docker +kind: pipeline +name: "drone-dagger-test" + +steps: + - name: "build" + image: harbor.server.kjuulh.io/kjuulh/bust:1667244085545 + volumes: + - name: dockersock + path: /var/run + environment: + DOCKER_BUILDKIT: 1 + HARBOR_DOCKER_HOST: "harbor.server.kjuulh.io" + HARBOR_DOCKER_USERNAME: + from_secret: "harbor_docker_username" + HARBOR_DOCKER_PASSWORD: + from_secret: "harbor_docker_password" + commands: + - sleep 5 + - > + echo "$${HARBOR_DOCKER_PASSWORD}" | docker login + --password-stdin + --username="$${HARBOR_DOCKER_USERNAME}" + "$${HARBOR_DOCKER_HOST}" + - bust build rustbin --bin-name {{ .input.binName }} + +services: + - name: docker + image: docker:dind + privileged: true + volumes: + - name: dockersock + path: /var/run + +volumes: + - name: dockersock + temp: {} + +image_pull_secrets: + - dockerconfig diff --git a/templates/uploadtemplate.sh b/templates/uploadtemplate.sh index 9ec833e..e256295 100755 --- a/templates/uploadtemplate.sh +++ b/templates/uploadtemplate.sh @@ -11,3 +11,4 @@ add_template kjuulh bust_default_template.yaml add_template kjuulh bust_docker_template.yaml add_template kjuulh bust_gobin_template.yaml add_template kjuulh bust_gobin_default_template.yaml +add_template kjuulh bust_rustbin_default_template.yaml