Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: base img support #46

Merged
merged 12 commits into from
Jul 3, 2024
Merged
5 changes: 0 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ jobs:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Check Nixpkgs inputs
uses: DeterminateSystems/flake-checker-action@main
with:
fail-mode: true
flake-lock-path: ./bsf/flake.lock
- uses: nicknovitski/nix-develop@v1
with:
arguments: bsf/.#devShell
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# BuildSafe

[![Discord Server](https://img.shields.io/badge/discord-gray?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/xrwYkuFT)
[![Discord Server](https://img.shields.io/badge/discord-gray?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/geGGKhrz)

## About

Expand All @@ -16,7 +16,7 @@ Follow [Quickstart](https://buildsafe.dev/guides/getting-started/)
## Where Do I Learn More?

For more information on how to use and develop the BuildSafe software, talk to us on
[our Discord](https://discord.gg/xrwYkuFT) and see our website [docs](https://buildsafe.dev/guides/getting-started/).
[our Discord](https://discord.gg/geGGKhrz) and see our website [docs](https://buildsafe.dev/guides/getting-started/).

## How Can I Contribute?

Expand Down
86 changes: 76 additions & 10 deletions cmd/init/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,49 @@ import (
"github.com/buildsafedev/bsf/pkg/langdetect"
)

func generatehcl2NixConf(pt langdetect.ProjectType, pd *langdetect.ProjectDetails) (hcl2nix.Config, error) {
func generatehcl2NixConf(pt langdetect.ProjectType, pd *langdetect.ProjectDetails) (hcl2nix.Config, bool, error) {
switch pt {
case langdetect.GoModule:
return genGoModuleConf(pd), nil
return genGoModuleConf(pd), false, nil
case langdetect.PythonPoetry:
return genPythonPoetryConf(), nil
return genPythonPoetryConf(), false, nil
case langdetect.RustCargo:
config, err := genRustCargoConf()
if err != nil {
return hcl2nix.Config{}, err
return hcl2nix.Config{}, false, err
}
return config, nil
return config, false, nil
case langdetect.JsNpm:
config, err := genJsNpmConf()
if err != nil {
return hcl2nix.Config{}, err
return hcl2nix.Config{}, false, err
}
return config, nil
return config, false, nil
default:
return hcl2nix.Config{
Packages: hcl2nix.Packages{},
}, nil
return generateEmptyConf(), true, nil
}
}

func generateEmptyConf() hcl2nix.Config {
return hcl2nix.Config{
rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
Packages: hcl2nix.Packages{
Development: []string{""},
Runtime: []string{"[email protected]"},
},
OCIArtifact: []hcl2nix.OCIArtifact{
{
Artifact: "pkgs",
Name: "bsf-base-image",
Cmd: []string{},
Entrypoint: []string{},
EnvVars: []string{},
ExposedPorts: []string{},
ImportConfigs: []string{},
DevDeps: false,
},
},
}
}
func genRustCargoConf() (hcl2nix.Config, error) {
content, err := os.ReadFile("Cargo.toml")
if err != nil {
Expand Down Expand Up @@ -65,6 +83,18 @@ func genRustCargoConf() (hcl2nix.Config, error) {
RustVersion: "1.75.0",
Release: true,
},
OCIArtifact: []hcl2nix.OCIArtifact{
{
Artifact: "pkgs",
Name: "bsf-base-image",
Cmd: []string{},
Entrypoint: []string{},
EnvVars: []string{},
ExposedPorts: []string{},
ImportConfigs: []string{},
DevDeps: false,
},
},
}, nil
}

Expand All @@ -83,6 +113,18 @@ func genPythonPoetryConf() hcl2nix.Config {
PreferWheels: false,
CheckGroups: []string{"dev"},
},
OCIArtifact: []hcl2nix.OCIArtifact{
{
Artifact: "pkgs",
Name: "bsf-base-image",
Cmd: []string{},
Entrypoint: []string{},
EnvVars: []string{},
ExposedPorts: []string{},
ImportConfigs: []string{},
DevDeps: false,
},
},
}
}

Expand All @@ -106,6 +148,18 @@ func genGoModuleConf(pd *langdetect.ProjectDetails) hcl2nix.Config {
Name: name,
SourcePath: entrypoint,
},
OCIArtifact: []hcl2nix.OCIArtifact{
{
Artifact: "pkgs",
Name: "bsf-base-image",
Cmd: []string{},
Entrypoint: []string{},
EnvVars: []string{},
ExposedPorts: []string{},
ImportConfigs: []string{},
DevDeps: false,
},
},
}

}
Expand Down Expand Up @@ -134,5 +188,17 @@ func genJsNpmConf() (hcl2nix.Config, error) {
PackageName: name,
PackageRoot: "./.",
},
OCIArtifact: []hcl2nix.OCIArtifact{
{
Artifact: "pkgs",
Name: "bsf-base-image",
Cmd: []string{},
Entrypoint: []string{},
EnvVars: []string{},
ExposedPorts: []string{},
ImportConfigs: []string{},
DevDeps: false,
},
},
}, nil
}
5 changes: 4 additions & 1 deletion cmd/init/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (m *model) processStages(stage int) error {
defer fh.FlakeFile.Close()
defer fh.DefFlakeFile.Close()

conf, err := generatehcl2NixConf(m.pt, m.pd)
conf, isBase, err := generatehcl2NixConf(m.pt, m.pd)
if err != nil {
m.stageMsg = errorStyle(err.Error())
return err
Expand All @@ -127,6 +127,9 @@ func (m *model) processStages(stage int) error {
m.stageMsg = errorStyle(err.Error())
return err
}
if isBase {
return nil
}

err = generate.Generate(fh, m.sc)
if err != nil {
Expand Down
67 changes: 36 additions & 31 deletions cmd/oci/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,30 @@ import (
)

var (
platform, output string
push, loadDocker, loadPodman bool
platform, output string
push, loadDocker, loadPodman, devDeps bool
)
var (
supportedPlatforms = []string{"linux/amd64", "linux/arm64"}
)

func init() {
OCICmd.Flags().StringVarP(&platform, "platform", "p", "", "The platform to build the image for")
OCICmd.Flags().StringVarP(&output, "output", "o", "", "location of the build artifacts generated")
OCICmd.Flags().BoolVarP(&loadDocker, "load-docker", "", false, "Load the image into docker daemon")
OCICmd.Flags().BoolVarP(&loadPodman, "load-podman", "", false, "Load the image into podman")
OCICmd.Flags().BoolVarP(&push, "push", "", false, "Push the image to the registry")
OCICmd.Flags().BoolVarP(&devDeps, "dev", "", false, "Build base image for Dev Dependencies")
}

// OCICmd represents the export command
var OCICmd = &cobra.Command{
Use: "oci",
Short: "Builds an OCI image",
Long: `
bsf oci <environment name>
bsf oci <environment name> --platform <platform>
bsf oci <environment name> --platform <platform> --output <output directory>
bsf oci <artifact>
bsf oci <artifact> --platform <platform>
bsf oci <artifact> --platform <platform> --output <output directory>
`,
Run: func(cmd *cobra.Command, args []string) {
// todo: we could provide a TUI list dropdown to select
Expand All @@ -45,7 +54,7 @@ var OCICmd = &cobra.Command{
os.Exit(1)
}

env, p, err := ProcessPlatformAndConfig(platform, args[0])
artifact, p, err := ProcessPlatformAndConfig(platform, args[0])
if err != nil {
fmt.Println(styles.ErrorStyle.Render("error: ", err.Error()))
os.Exit(1)
Expand All @@ -57,8 +66,8 @@ var OCICmd = &cobra.Command{
fmt.Println(styles.ErrorStyle.Render("error: ", err.Error()))
os.Exit(1)
}

err = generate.Generate(fh, sc)

if err != nil {
fmt.Println(styles.ErrorStyle.Render("error: ", err.Error()))
os.Exit(1)
Expand All @@ -82,7 +91,7 @@ var OCICmd = &cobra.Command{

symlink := "/result"

err = nixcmd.Build(output+symlink, genOCIAttrName(env.Environment, platform))
err = nixcmd.Build(output+symlink, genOCIAttrName(artifact.Artifact, platform, artifact))
if err != nil {
fmt.Println(styles.ErrorStyle.Render("error: ", err.Error()))
os.Exit(1)
Expand All @@ -107,7 +116,7 @@ var OCICmd = &cobra.Command{
fmt.Println(styles.ErrorStyle.Render("error:", err.Error()))
os.Exit(1)
}
appDetails.Name = env.Name
appDetails.Name = artifact.Name

tos, tarch := findPlatform(platform)
err = build.GenerateArtifcats(output, symlink, lockFile, appDetails, graph, tos, tarch)
Expand Down Expand Up @@ -141,7 +150,7 @@ var OCICmd = &cobra.Command{
contextEP[currentContext] = "unix:///var/run/docker.sock"
}

err = oci.LoadDocker(contextEP[currentContext], output+"/result", env.Name)
err = oci.LoadDocker(contextEP[currentContext], output+"/result", artifact.Name)
if err != nil {
fmt.Println(styles.ErrorStyle.Render("error:", err.Error()))
if !expectedInstall {
Expand All @@ -150,30 +159,29 @@ var OCICmd = &cobra.Command{
os.Exit(1)
}

fmt.Println(styles.SucessStyle.Render(fmt.Sprintf("Image %s loaded to docker daemon", env.Name)))
fmt.Println(styles.SucessStyle.Render(fmt.Sprintf("Image %s loaded to docker daemon", artifact.Name)))

}

if loadPodman {
fmt.Println(styles.HighlightStyle.Render("Loading image to podman..."))
err = oci.LoadPodman(output+"/result", env.Name)
err = oci.LoadPodman(output+"/result", artifact.Name)
if err != nil {
fmt.Println(styles.ErrorStyle.Render("error:", err.Error()))
os.Exit(1)
}
fmt.Println(styles.SucessStyle.Render(fmt.Sprintf("Image %s loaded to podman", env.Name)))
fmt.Println(styles.SucessStyle.Render(fmt.Sprintf("Image %s loaded to podman", artifact.Name)))
}

if push {
fmt.Println(styles.HighlightStyle.Render("Pushing image to registry..."))
err = oci.Push(output+"/result", env.Name)
err = oci.Push(output+"/result", artifact.Name)
if err != nil {
fmt.Println(styles.ErrorStyle.Render("error:", err.Error()))
os.Exit(1)
}
fmt.Println(styles.SucessStyle.Render(fmt.Sprintf("Image %s pushed to registry", env.Name)))
fmt.Println(styles.SucessStyle.Render(fmt.Sprintf("Image %s pushed to registry", artifact.Name)))
}

},
}

Expand Down Expand Up @@ -220,29 +228,29 @@ func ProcessPlatformAndConfig(plat string, envName string) (hcl2nix.OCIArtifact,

envNames := make([]string, 0, len(conf.OCIArtifact))
var found bool
env := hcl2nix.OCIArtifact{}
artifact := hcl2nix.OCIArtifact{}
for _, ec := range conf.OCIArtifact {
errStr := ec.Validate(conf)
if errStr != nil {
return hcl2nix.OCIArtifact{}, "", fmt.Errorf("Config for export block %s is invalid\n Error: %s", ec.Name, *errStr)
}

if ec.Environment == envName {
if ec.Artifact == envName {
found = true
env = ec
artifact = ec
break
}
envNames = append(envNames, ec.Environment)
envNames = append(envNames, ec.Artifact)
}

if !found {
return hcl2nix.OCIArtifact{}, "", fmt.Errorf("error: No such environment found. Valid oci environment that can be built are: %s", strings.Join(envNames, ", "))
}

return env, plat, nil
return artifact, plat, nil
}

func genOCIAttrName(env, platform string) string {
func genOCIAttrName(env, platform string, artifact hcl2nix.OCIArtifact) string {
// .#ociImages.x86_64-linux.ociImage_caddy-as-dir
tostarch := ""
switch platform {
Expand All @@ -251,14 +259,11 @@ func genOCIAttrName(env, platform string) string {
case "linux/arm64":
tostarch = "aarch64-linux"
}
if env == "pkgs" {
if devDeps || artifact.DevDeps {
return fmt.Sprintf("bsf/.#ociImages.%s.ociImage_%s_dev-as-dir", tostarch, env)
}
return fmt.Sprintf("bsf/.#ociImages.%s.ociImage_%s_runtime-as-dir", tostarch, env)
}
return fmt.Sprintf("bsf/.#ociImages.%s.ociImage_%s-as-dir", tostarch, env)
}

func init() {
OCICmd.Flags().StringVarP(&platform, "platform", "p", "", "The platform to build the image for")
OCICmd.Flags().StringVarP(&output, "output", "o", "", "location of the build artifacts generated")
OCICmd.Flags().BoolVarP(&loadDocker, "load-docker", "", false, "Load the image into docker daemon")
OCICmd.Flags().BoolVarP(&loadPodman, "load-podman", "", false, "Load the image into podman")
OCICmd.Flags().BoolVarP(&push, "push", "", false, "Push the image to the registry")

}
Loading
Loading