Skip to content
Open
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
50 changes: 47 additions & 3 deletions cmd/porchctl/main.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023 The kpt and Nephio Authors
// Copyright 2023,2026 The kpt and Nephio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -25,7 +25,7 @@ import (
"github.com/nephio-project/porch/cmd/porchctl/run"
"github.com/spf13/cobra"
_ "k8s.io/client-go/plugin/pkg/client/auth"
"k8s.io/component-base/cli"
"k8s.io/component-base/logs"
"k8s.io/klog/v2"
k8scmdutil "k8s.io/kubectl/pkg/cmd/util"
)
Expand All @@ -49,13 +49,57 @@ func runMain() int {

cmd := run.GetMain(ctx)

err = cli.RunNoErrOutput(cmd)
err = k8sCliRunNoErrOutput(cmd)
if err != nil {
return handleErr(cmd, err)
}
return 0
}

// k8sCliRunNoErrOutput is a copy of k8s.io/component-base/cli.RunNoErrOutput
// that does not mess up the global normalization func. This means that we lose
// the WordSepNormalize functionality in porchctl.
//
// TODO: is that a problem?
func k8sCliRunNoErrOutput(cmd *cobra.Command) error {
defer logs.FlushLogs()

// cmd.SetGlobalNormalizationFunc(cliflag.WordSepNormalizeFunc)

if !cmd.SilenceUsage {
cmd.SilenceUsage = true
cmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
c.SilenceUsage = false
return err
})
}

cmd.SilenceErrors = true

logs.AddFlags(cmd.PersistentFlags())

switch {
case cmd.PersistentPreRun != nil:
pre := cmd.PersistentPreRun
cmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
logs.InitLogs()
pre(cmd, args)
}
case cmd.PersistentPreRunE != nil:
pre := cmd.PersistentPreRunE
cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
logs.InitLogs()
return pre(cmd, args)
}
default:
cmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
logs.InitLogs()
}
}

return cmd.Execute()
}

// handleErr takes care of printing an error message for a given error.
func handleErr(cmd *cobra.Command, err error) int {
// First attempt to see if we can resolve the error into a specific
Expand Down
4 changes: 4 additions & 0 deletions make/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ porch:
porchctl:
go build -ldflags="-X github.com/nephio-project/porch/cmd/porchctl/run.version=$(PORCHCTL_VERSION)" -o $(PORCHCTL) ./cmd/porchctl

.PHONY: install-porchctl
install-porchctl:
go install -ldflags="-X github.com/nephio-project/porch/cmd/porchctl/run.version=$(PORCHCTL_VERSION)" ./cmd/porchctl

.PHONY: build-images
build-images:
ALPINE_VERSION="$(ALPINE_VERSION)" GOLANG_BOOKWORM_VERSION="$(GOLANG_BOOKWORM_VERSION)" IMAGE_NAME="$(PORCH_SERVER_IMAGE)" make -C build/ build-image
Expand Down
20 changes: 10 additions & 10 deletions pkg/cli/commands/repo/docs/docs.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The kpt and Nephio Authors
// Copyright 2022,2026 The kpt and Nephio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -53,33 +53,33 @@ Args:

Flags:

--branch:
--branch
Branch within the repository where finalized packages are
commited. The default is to use the 'main' branch.

--deployment:
--deployment, --deploy
Tags the repository as a deployment repository. Packages in
a deployment repository are considered ready for deployment.

--description:
--description, --desc, -d
Description of the repository.

--directory:
--directory, --dir
Directory within the repository where packages are found. The
default is the root of the repository.

--sync-schedule:
--sync-schedule
Cron schedule for reconciling packages in the repository.
If not specified, porch will use --repo-sync-frequency.

--name:
--name
Name of the repository. By default the last segment of the
repository URL will be used as the name.

--repo-basic-username:
--repo-basic-username, --username, --user
Username for authenticating to a repository with basic auth.

--repo-basic-password:
--repo-basic-password, --password, --pass
Password for authenticating to a repository with basic auth.
`
var RegExamples = `
Expand All @@ -104,7 +104,7 @@ Args:

Flags:

--keep-auth-secret:
--keep-auth-secret
Keep the Secret object with auth information referenced by the repository.
By default, it will be deleted when the repository is unregistered.
`
Expand Down
47 changes: 30 additions & 17 deletions pkg/cli/commands/repo/reg/command.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022-2025 The kpt and Nephio Authors
// Copyright 2022-2026 The kpt and Nephio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -23,8 +23,10 @@ import (
configapi "github.com/nephio-project/porch/api/porchconfig/v1alpha1"
cliutils "github.com/nephio-project/porch/internal/cliutils"
"github.com/nephio-project/porch/pkg/cli/commands/repo/docs"
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/util"
"github.com/robfig/cron/v3"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
coreapi "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
Expand Down Expand Up @@ -56,16 +58,37 @@ func newRunner(ctx context.Context, rcg *genericclioptions.ConfigFlags) *runner
c.Flags().StringVar(&r.branch, "branch", "main", "Branch in the repository where finalized packages are committed.")
c.Flags().BoolVar(&r.createBranch, "create-branch", false, "Create the package branch if it doesn't already exist.")
c.Flags().StringVar(&r.name, "name", "", "Name of the package repository. If unspecified, will use the name portion (last segment) of the repository URL.")
c.Flags().StringVar(&r.description, "description", "", "Brief description of the package repository.")
c.Flags().StringVarP(&r.description, "description", "d", "", "Brief description of the package repository.")
c.Flags().BoolVar(&r.deployment, "deployment", false, "Repository is a deployment repository; packages in a deployment repository are considered deployment-ready.")
c.Flags().StringVar(&r.username, "repo-basic-username", "", "Username for repository authentication using basic auth.")
c.Flags().StringVar(&r.password, "repo-basic-password", "", "Password for repository authentication using basic auth.")
c.Flags().BoolVar(&r.workloadIdentity, "repo-workload-identity", false, "Use workload identity for authentication with the repo")
c.Flags().StringVar(&r.syncSchedule, "sync-schedule", "", "Cron schedule for reconciling packages in the repository.")

c.Flags().SetNormalizeFunc(aliasNormalizeFunc)

return r
}

// aliasNormalizeFunc adds some sensible short versions of flags
// TODO: document
func aliasNormalizeFunc(_ *pflag.FlagSet, name string) pflag.NormalizedName {
switch name {
case "user", "username":
name = "repo-basic-username"
case "pw", "pass", "password":
name = "repo-basic-password"
case "deploy":
name = "deployment"
case "desc":
name = "description"
case "dir", "folder":
name = "directory"
}

return pflag.NormalizedName(name)
}

func NewCommand(ctx context.Context, rcg *genericclioptions.ConfigFlags) *cobra.Command {
return newRunner(ctx, rcg).Command
}
Expand All @@ -92,21 +115,11 @@ type runner struct {
func (r *runner) preRunE(_ *cobra.Command, _ []string) error {
const op errors.Op = command + ".preRunE"

// todo if namespace flag missing, use kubeconfig
if *r.cfg.Namespace == "" {
// Get the namespace from kubeconfig
namespace, _, err := r.cfg.ToRawKubeConfigLoader().Namespace()
if err != nil {
return fmt.Errorf("error getting namespace: %w", err)
}
r.cfg.Namespace = &namespace
}

client, err := cliutils.CreateClientWithFlags(r.cfg)
var err error
r.client, err = cliutils.CreateClientWithFlags(r.cfg)
if err != nil {
return errors.E(op, err)
}
r.client = client
return nil
}

Expand Down Expand Up @@ -185,7 +198,7 @@ func (r *runner) runE(_ *cobra.Command, args []string) error {
},
ObjectMeta: metav1.ObjectMeta{
Name: r.name,
Namespace: *r.cfg.Namespace,
Namespace: util.EnsureNamespace(r.cfg),
},
Spec: configapi.RepositorySpec{
Description: r.description,
Expand Down Expand Up @@ -225,7 +238,7 @@ func (r *runner) buildAuthSecret() (*coreapi.Secret, error) {
},
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-auth", r.name),
Namespace: *r.cfg.Namespace,
Namespace: util.EnsureNamespace(r.cfg),
},
Data: map[string][]byte{},
Type: "kpt.dev/workload-identity-auth",
Expand All @@ -238,7 +251,7 @@ func (r *runner) buildAuthSecret() (*coreapi.Secret, error) {
},
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-auth", r.name),
Namespace: *r.cfg.Namespace,
Namespace: util.EnsureNamespace(r.cfg),
},
Data: map[string][]byte{
"username": []byte(r.username),
Expand Down
14 changes: 3 additions & 11 deletions pkg/cli/commands/repo/unreg/command.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The kpt and Nephio Authors
// Copyright 2022,2026 The kpt and Nephio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -22,6 +22,7 @@ import (
configapi "github.com/nephio-project/porch/api/porchconfig/v1alpha1"
cliutils "github.com/nephio-project/porch/internal/cliutils"
"github.com/nephio-project/porch/pkg/cli/commands/repo/docs"
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/util"
"github.com/spf13/cobra"
coreapi "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -72,15 +73,6 @@ type runner struct {
func (r *runner) preRunE(_ *cobra.Command, _ []string) error {
const op errors.Op = command + ".preRunE"

if *r.cfg.Namespace == "" {
// Get the namespace from kubeconfig
namespace, _, err := r.cfg.ToRawKubeConfigLoader().Namespace()
if err != nil {
return fmt.Errorf("error getting namespace: %w", err)
}
r.cfg.Namespace = &namespace
}

client, err := cliutils.CreateClientWithFlags(r.cfg)
if err != nil {
return errors.E(op, err)
Expand All @@ -100,7 +92,7 @@ func (r *runner) runE(_ *cobra.Command, args []string) error {

var repo configapi.Repository
if err := r.client.Get(r.ctx, client.ObjectKey{
Namespace: *r.cfg.Namespace,
Namespace: util.EnsureNamespace(r.cfg),
Name: repository,
}, &repo); err != nil {
return errors.E(op, err)
Expand Down
7 changes: 3 additions & 4 deletions pkg/cli/commands/rpkg/approve/command.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The kpt and Nephio Authors
// Copyright 2022,2026 The kpt and Nephio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -23,6 +23,7 @@ import (
porchapi "github.com/nephio-project/porch/api/porch/v1alpha1"
cliutils "github.com/nephio-project/porch/internal/cliutils"
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/docs"
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/util"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/util/retry"
Expand Down Expand Up @@ -81,11 +82,9 @@ func (r *runner) runE(_ *cobra.Command, args []string) error {
const op errors.Op = command + ".runE"
var messages []string

namespace := *r.cfg.Namespace

for _, name := range args {
key := client.ObjectKey{
Namespace: namespace,
Namespace: util.EnsureNamespace(r.cfg),
Name: name,
}
var lastErr error
Expand Down
5 changes: 3 additions & 2 deletions pkg/cli/commands/rpkg/clone/command.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The kpt and Nephio Authors
// Copyright 2022,2026 The kpt and Nephio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -24,6 +24,7 @@ import (
porchapi "github.com/nephio-project/porch/api/porch/v1alpha1"
cliutils "github.com/nephio-project/porch/internal/cliutils"
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/docs"
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/util"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
Expand Down Expand Up @@ -169,7 +170,7 @@ func (r *runner) runE(cmd *cobra.Command, _ []string) error {
APIVersion: porchapi.SchemeGroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
Namespace: *r.cfg.Namespace,
Namespace: util.EnsureNamespace(r.cfg),
},
Spec: porchapi.PackageRevisionSpec{
PackageName: r.target,
Expand Down
24 changes: 20 additions & 4 deletions pkg/cli/commands/rpkg/copy/command.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The kpt and Nephio Authors
// Copyright 2022,2026 The kpt and Nephio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -22,7 +22,9 @@ import (
porchapi "github.com/nephio-project/porch/api/porch/v1alpha1"
cliutils "github.com/nephio-project/porch/internal/cliutils"
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/docs"
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/util"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/cli-runtime/pkg/genericclioptions"
Expand Down Expand Up @@ -52,10 +54,24 @@ func newRunner(ctx context.Context, rcg *genericclioptions.ConfigFlags) *runner
RunE: r.runE,
Hidden: cliutils.HidePorchCommands,
}
r.Command.Flags().StringVar(&r.workspace, "workspace", "", "Workspace name of the copy of the package.")

r.Command.Flags().StringVarP(&r.workspace, "workspace", "w", "", "Workspace name of the copy of the package.")

r.Command.Flags().SetNormalizeFunc(aliasNormalizeFunc)

return r
}

// aliasNormalizeFunc adds some sensible short versions of flags
func aliasNormalizeFunc(_ *pflag.FlagSet, name string) pflag.NormalizedName {
switch name {
case "ws":
name = "workspace"
}

return pflag.NormalizedName(name)
}

type runner struct {
ctx context.Context
cfg *genericclioptions.ConfigFlags
Expand Down Expand Up @@ -102,7 +118,7 @@ func (r *runner) runE(cmd *cobra.Command, _ []string) error {
APIVersion: porchapi.SchemeGroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
Namespace: *r.cfg.Namespace,
Namespace: util.EnsureNamespace(r.cfg),
},
Spec: *revisionSpec,
}
Expand All @@ -117,7 +133,7 @@ func (r *runner) getPackageRevisionSpec() (*porchapi.PackageRevisionSpec, error)
packageRevision := porchapi.PackageRevision{}
err := r.client.Get(r.ctx, types.NamespacedName{
Name: r.copy.Source.Name,
Namespace: *r.cfg.Namespace,
Namespace: util.EnsureNamespace(r.cfg),
}, &packageRevision)
if err != nil {
return nil, err
Expand Down
Loading
Loading