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

main: add --verbose,-v persistent flag that increases verbosity #790

Merged
merged 2 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ Flags:
--progress string type of progress bar to use (e.g. verbose, term)
--type string image type to build [qcow2, ami] (default "qcow2")
--target-arch string architecture to build image for (default is the native architecture)

Global Flags:
-v, --verbose Switch to verbose mode
```

### Detailed description of optional flags
Expand All @@ -143,6 +146,7 @@ Flags:
| **--tls-verify** | Require HTTPS and verify certificates when contacting registries | `true` |
| **--type** | [Image type](#-image-types) to build | `qcow2` |
| **--target-arch** | [Target arch](#-target-architecture) to build | ❌ |
| **--verbose** | Switch output/progress to verbose mode | `false` |

The `--type` parameter can be given multiple times and multiple outputs will
be produced.
Expand Down
72 changes: 31 additions & 41 deletions bib/cmd/bootc-image-builder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,72 +546,61 @@ func chownR(path string, chown string) error {
var rootLogLevel string

func rootPreRunE(cmd *cobra.Command, _ []string) error {
if rootLogLevel == "" {
verbose, _ := cmd.Flags().GetBool("verbose")
progress, _ := cmd.Flags().GetString("progress")
switch {
case rootLogLevel != "":
level, err := logrus.ParseLevel(rootLogLevel)
if err != nil {
return err
}
logrus.SetLevel(level)
case verbose:
logrus.SetLevel(logrus.InfoLevel)
default:
logrus.SetLevel(logrus.ErrorLevel)
return nil
}

level, err := logrus.ParseLevel(rootLogLevel)
if err != nil {
return err
if verbose && progress == "auto" {
if err := cmd.Flags().Set("progress", "verbose"); err != nil {
return err
}
}

logrus.SetLevel(level)

return nil
}

func cmdVersion() (string, error) {
func versionFromBuildInfo() (string, error) {
info, ok := debug.ReadBuildInfo()
if !ok {
return "", fmt.Errorf("cannot read build info")
}
var gitRev string
var buildTime string
var buildTainted bool
ret := []string{}
gitRev := "unknown"
buildTime := "unknown"
for _, bs := range info.Settings {
if bs.Key == "vcs.revision" {
gitRev = bs.Value
continue
}
if bs.Key == "vcs.time" {
switch bs.Key {
case "vcs.revision":
gitRev = bs.Value[:7]
case "vcs.time":
buildTime = bs.Value
continue
}
if bs.Key == "vcs.modified" {
case "vcs.modified":
bT, err := strconv.ParseBool(bs.Value)
if err != nil {
logrus.Errorf("Error parsing 'vcs.modified': %v", err)
bT = true
}

buildTainted = bT
continue
}
}
if gitRev != "" {
ret = append(ret, fmt.Sprintf("build_revision: %s", gitRev[:7]))
} else {
ret = append(ret, "build_revision: unknown")
}
if buildTime != "" {
ret = append(ret, fmt.Sprintf("build_time: %s", buildTime))
}
if buildTainted {
ret = append(ret, "build_status: tainted")
} else {
ret = append(ret, "build_status: ok")
}

// append final newline
ret = append(ret, "")

return strings.Join(ret, "\n"), nil
return fmt.Sprintf(`build_revision: %s
build_time: %s
build_tainted: %v
`, gitRev, buildTime, buildTainted), nil
}

func buildCobraCmdline() (*cobra.Command, error) {
version, err := cmdVersion()
version, err := versionFromBuildInfo()
if err != nil {
return nil, err
}
Expand All @@ -626,6 +615,7 @@ func buildCobraCmdline() (*cobra.Command, error) {
rootCmd.SetVersionTemplate(version)

rootCmd.PersistentFlags().StringVar(&rootLogLevel, "log-level", "", "logging level (debug, info, error); default error")
rootCmd.PersistentFlags().BoolP("verbose", "v", false, `Switch to verbose mode`)

buildCmd := &cobra.Command{
Use: "build IMAGE_NAME",
Expand All @@ -639,7 +629,7 @@ func buildCobraCmdline() (*cobra.Command, error) {
SilenceUsage: true,
Example: rootCmd.Use + " build quay.io/centos-bootc/centos-bootc:stream9\n" +
rootCmd.Use + " quay.io/centos-bootc/centos-bootc:stream9\n",
Version: rootCmd.Version,
Version: rootCmd.Version,
}
buildCmd.SetVersionTemplate(version)

Expand Down
46 changes: 46 additions & 0 deletions bib/cmd/bootc-image-builder/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"
"testing"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -573,3 +574,48 @@ func TestCobraCmdline(t *testing.T) {
})
}
}

func TestCobraCmdlineVerbose(t *testing.T) {
for _, tc := range []struct {
cmdline []string
expectedProgress string
expectedLogrusLevel logrus.Level
}{
{
[]string{"quay.io..."},
"auto",
logrus.ErrorLevel,
},
{
[]string{"-v", "quay.io..."},
"verbose",
logrus.InfoLevel,
},
} {
restore := mockOsArgs(tc.cmdline)
defer restore()

rootCmd, err := main.BuildCobraCmdline()
assert.NoError(t, err)

// collect progressFlag value
var progressFlag string
for _, cmd := range rootCmd.Commands() {
cmd.RunE = func(cmd *cobra.Command, args []string) error {
if progressFlag != "" {
t.Error("progressFlag set twice")
}
progressFlag, err = cmd.Flags().GetString("progress")
assert.NoError(t, err)
return nil
}
}

t.Run(tc.expectedProgress, func(t *testing.T) {
err = rootCmd.Execute()
assert.NoError(t, err)
assert.Equal(t, tc.expectedProgress, progressFlag)
assert.Equal(t, tc.expectedLogrusLevel, logrus.GetLevel())
})
}
}
9 changes: 6 additions & 3 deletions test/test_opts.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def test_bib_errors_only_once(tmp_path, container_storage, build_fake_container)
assert res.stderr.count(needle) == 1


@pytest.mark.parametrize("version_argument", ["version", "--version", "-v"])
@pytest.mark.parametrize("version_argument", ["version", "--version"])
def test_bib_version(tmp_path, container_storage, build_fake_container, version_argument):
output_path = tmp_path / "output"
output_path.mkdir(exist_ok=True)
Expand All @@ -169,8 +169,11 @@ def test_bib_version(tmp_path, container_storage, build_fake_container, version_
capture_output=True, text=True, check=False)
if git_res.returncode == 0:
expected_rev = git_res.stdout.strip()
needle = f"revision: {expected_rev}"
assert needle in res.stdout
assert f"build_revision: {expected_rev}" in res.stdout
assert "build_time: " in res.stdout
assert "build_tainted: " in res.stdout
# we have a final newline
assert res.stdout[-1] == "\n"


def test_bib_no_outside_container_warning_in_container(tmp_path, container_storage, build_fake_container):
Expand Down
Loading