forked from coreos/coreos-assembler
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is a big step towards coreos#2685 I know there's a lot going on with the pipeline, and I don't want to conflict with all that work - but at the same time, in my opinion we are just too dependent on complex Jenkins flows and our bespoke "meta.json in S3". The core of CoreOS *is a container image* now. This new command adds an opinionated flow where one can do: ``` $ cosa init $ cosa build-cimage quay.io/cgwalters/ostest ``` And *that's it* - we do proper change detection, reading and writing from the remote container image. We don't do silly things like storing an `.ociarchive` in S3 when we have native registries available. Later, we can build on this and rework our disk images to derive from that container image, as coreos#2685 calls for. Also in the near term future, I think we can rework `cmd-build` such that it reuses this flow, but outputs to an `.ociarchive` instead. However, this code is going to need a bit more work to run in supermin.
- Loading branch information
Showing
5 changed files
with
192 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
// See usage below | ||
package main | ||
|
||
// build-cimage is a wrapper for `rpm-ostree compose image`; for more | ||
// on that, see https://coreos.github.io/rpm-ostree/container/ | ||
// | ||
// A key motivation here is to sever the dependency on S3 (and meta.json) for | ||
// our container image builds. As part of the ostree native container work, | ||
// the core of CoreOS becomes a container image. Our disk images | ||
// have always been derivatives of the container, and this is pushing things | ||
// farther in that direction. | ||
// See https://github.com/coreos/coreos-assembler/issues/2685 | ||
// | ||
// This command is opinionated on reading and writing to a remote registry, | ||
// whereas the underlying `rpm-ostree compose image` defaults to | ||
// an ociarchive. | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/coreos/coreos-assembler/internal/pkg/cmdrun" | ||
"github.com/coreos/coreos-assembler/internal/pkg/cosash" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
type BuildCImageOptions struct { | ||
authfile string | ||
initialize bool | ||
} | ||
|
||
var ( | ||
BuildCImageOpts BuildCImageOptions | ||
|
||
cmdBuildCImage = &cobra.Command{ | ||
Use: "build-cimage", | ||
Short: "cosa build-cimage [repository]", | ||
Args: cobra.ExactArgs(1), | ||
Long: "Initialize directory for ostree container image build", | ||
RunE: implRunBuildCImage, | ||
} | ||
) | ||
|
||
func init() { | ||
cmdBuildCImage.Flags().BoolVarP( | ||
&BuildCImageOpts.initialize, "initialize", "i", false, | ||
"Assume target image does not exist") | ||
cmdBuildCImage.Flags().StringVar( | ||
&BuildCImageOpts.authfile, "authfile", "", | ||
"Path to container authentication file") | ||
} | ||
|
||
func runBuildCImage(argv []string) error { | ||
cmdBuildCImage.SetArgs(argv) | ||
return cmdBuildCImage.Execute() | ||
} | ||
|
||
// This is a Go reipmlementation of pick_yaml_or_else_json() from cmdlib.sh | ||
func pickConfigFileYamlOrJson(name string, preferJson bool) (string, error) { | ||
jsonPath := fmt.Sprintf("src/config/%s.json", name) | ||
yamlPath := fmt.Sprintf("src/config/%s.yaml", name) | ||
if _, err := os.Stat(jsonPath); err != nil { | ||
if !os.IsNotExist(err) { | ||
return "", err | ||
} | ||
jsonPath = "" | ||
} | ||
if _, err := os.Stat(yamlPath); err != nil { | ||
if !os.IsNotExist(err) { | ||
return "", err | ||
} | ||
yamlPath = "" | ||
} | ||
if jsonPath != "" && yamlPath != "" { | ||
return "", fmt.Errorf("found both %s and %s", jsonPath, yamlPath) | ||
} | ||
if jsonPath != "" { | ||
return jsonPath, nil | ||
} | ||
return yamlPath, nil | ||
} | ||
|
||
func implRunBuildCImage(c *cobra.Command, args []string) error { | ||
if err := cmdrun.RunCmdSyncV("cosa", "build", "--prepare-only"); err != nil { | ||
return err | ||
} | ||
|
||
csh, err := cosash.NewCosaSh() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
basearch, err := csh.BaseArch() | ||
if err != nil { | ||
return err | ||
} | ||
repository := args[0] | ||
|
||
buildArgs := []string{"compose", "image", "--format", "registry", "--layer-repo", "tmp/repo"} | ||
if BuildCImageOpts.initialize { | ||
buildArgs = append(buildArgs, "--initialize") | ||
} | ||
if BuildCImageOpts.authfile != "" { | ||
buildArgs = append(buildArgs, "--authfile", BuildCImageOpts.authfile) | ||
} | ||
if _, err := os.Stat("tmp/cosa-transient"); err != nil { | ||
if !os.IsNotExist(err) { | ||
return err | ||
} | ||
cachedir := "cache/buildcimage-cache" | ||
if err := os.MkdirAll(cachedir, 0o755); err != nil { | ||
return err | ||
} | ||
buildArgs = append(buildArgs, "--cachedir", cachedir) | ||
} | ||
manifestLock, err := pickConfigFileYamlOrJson(fmt.Sprintf("manifest-lock.%s", basearch), true) | ||
if err != nil { | ||
return err | ||
} | ||
manifestLockOverrides, err := pickConfigFileYamlOrJson("manifest-lock.overrides", false) | ||
if err != nil { | ||
return err | ||
} | ||
manifestLockArchOverrides, err := pickConfigFileYamlOrJson(fmt.Sprintf("manifest-lock.overrides.%s", basearch), false) | ||
if err != nil { | ||
return err | ||
} | ||
for _, lock := range []string{manifestLock, manifestLockOverrides, manifestLockArchOverrides} { | ||
if lock != "" { | ||
buildArgs = append(buildArgs, "--lockfile", lock) | ||
} | ||
} | ||
buildArgs = append(buildArgs, "src/config/manifest.yaml") | ||
buildArgs = append(buildArgs, repository) | ||
|
||
argv0 := "rpm-ostree" | ||
priv, err := csh.HasPrivileges() | ||
if err != nil { | ||
return err | ||
} | ||
if priv { | ||
argv0 = "sudo" | ||
buildArgs = append([]string{"rpm-ostree"}, buildArgs...) | ||
} else { | ||
return fmt.Errorf("this command currently requires the ability to create nested containers") | ||
} | ||
|
||
if err := cmdrun.RunCmdSyncV(argv0, buildArgs...); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package cmdrun | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
"syscall" | ||
) | ||
|
||
// Synchronously invoke a command, logging the command arguments | ||
// to stdout. | ||
func RunCmdSyncV(cmdName string, args ...string) error { | ||
fmt.Printf("Running: %s %s\n", cmdName, strings.Join(args, " ")) | ||
return RunCmdSync(cmdName, args...) | ||
} | ||
|
||
// Synchronously invoke a command, passing both stdout and stderr. | ||
func RunCmdSync(cmdName string, args ...string) error { | ||
cmd := exec.Command(cmdName, args...) | ||
cmd.SysProcAttr = &syscall.SysProcAttr{ | ||
Pdeathsig: syscall.SIGTERM, | ||
} | ||
cmd.Stdout = os.Stdout | ||
cmd.Stderr = os.Stderr | ||
if err := cmd.Run(); err != nil { | ||
return fmt.Errorf("error running %s %s: %w", cmdName, strings.Join(args, " "), err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters