diff --git a/.github/workflows/pr-workflow.yaml b/.github/workflows/pr-workflow.yaml index d56f950d4..89851c187 100644 --- a/.github/workflows/pr-workflow.yaml +++ b/.github/workflows/pr-workflow.yaml @@ -46,4 +46,4 @@ jobs: - name: Deploy Counter Demo run: hack/install-ate-kind.sh --deploy-demo-counter - name: Run E2E tests - run: hack/run-e2e-kind.sh -v -args -no-color + run: hack/run-e2e-kind.sh -v -args --no-color diff --git a/cmd/ateapi/main.go b/cmd/ateapi/main.go index 6feb976a0..87d5a7433 100644 --- a/cmd/ateapi/main.go +++ b/cmd/ateapi/main.go @@ -18,7 +18,6 @@ import ( "context" "crypto/tls" "crypto/x509" - "flag" "fmt" "log/slog" "net" @@ -36,6 +35,7 @@ import ( "github.com/agent-substrate/substrate/pkg/client/informers/externalversions" "github.com/agent-substrate/substrate/pkg/proto/ateapipb" "github.com/redis/go-redis/v9" + "github.com/spf13/pflag" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" sdktrace "go.opentelemetry.io/otel/sdk/trace" "golang.org/x/oauth2/google" @@ -47,28 +47,28 @@ import ( ) var ( - listenAddr = flag.String("grpc-listen-addr", ":443", "Address and port the gRPC server should listen on.") - metricsListenAddr = flag.String("metrics-listen-addr", ":9090", "Address and port the prometheus metrics server should listen on.") - grpcServerCredBundle = flag.String("grpc-server-cred-bundle", "", "File with the server TLS credential bundle.") + listenAddr = pflag.String("grpc-listen-addr", ":443", "Address and port the gRPC server should listen on.") + metricsListenAddr = pflag.String("metrics-listen-addr", ":9090", "Address and port the prometheus metrics server should listen on.") + grpcServerCredBundle = pflag.String("grpc-server-cred-bundle", "", "File with the server TLS credential bundle.") - redisClusterAddress = flag.String("redis-cluster-address", "", "The address of the redis cluster.") - redisCACerts = flag.String("redis-ca-certs", "", "The file that contains the CA certificate for Redis cluster.") - redisUseIAMAuth = flag.String("redis-use-iam-auth", "true", "Whether to use Google IAM authentication for Redis/Valkey.") - redisTLSServerName = flag.String("redis-tls-server-name", "", "The ServerName to use for Redis TLS hostname verification.") - redisClientCert = flag.String("redis-client-cert", "", "The file containing client TLS certificate/key credential bundle for Redis/Valkey.") + redisClusterAddress = pflag.String("redis-cluster-address", "", "The address of the redis cluster.") + redisCACerts = pflag.String("redis-ca-certs", "", "The file that contains the CA certificate for Redis cluster.") + redisUseIAMAuth = pflag.String("redis-use-iam-auth", "true", "Whether to use Google IAM authentication for Redis/Valkey.") + redisTLSServerName = pflag.String("redis-tls-server-name", "", "The ServerName to use for Redis TLS hostname verification.") + redisClientCert = pflag.String("redis-client-cert", "", "The file containing client TLS certificate/key credential bundle for Redis/Valkey.") - clientJWTIssuer = flag.String("client-jwt-issuer", "", "The expected issuer URL for client JWTs.") - clientJWTAudience = flag.String("client-jwt-audience", "", "The expected audience for client JWTs.") - sessionIDJWTPoolFile = flag.String("session-id-jwt-pool", "", "The file that contains the serialized JWT authority pool for signing session JWTs") + clientJWTIssuer = pflag.String("client-jwt-issuer", "", "The expected issuer URL for client JWTs.") + clientJWTAudience = pflag.String("client-jwt-audience", "", "The expected audience for client JWTs.") + sessionIDJWTPoolFile = pflag.String("session-id-jwt-pool", "", "The file that contains the serialized JWT authority pool for signing session JWTs") - sessionIDCAPoolFile = flag.String("session-id-ca-pool", "", "The file that contains the CA pool for signing session JWTs") - workerpoolCACerts = flag.String("workerpool-ca-certs", "", "The file that contains the CA for verifying workerpool client certificates.") + sessionIDCAPoolFile = pflag.String("session-id-ca-pool", "", "The file that contains the CA pool for signing session JWTs") + workerpoolCACerts = pflag.String("workerpool-ca-certs", "", "The file that contains the CA for verifying workerpool client certificates.") - showVersion = flag.Bool("version", false, "Print version and exit.") + showVersion = pflag.Bool("version", false, "Print version and exit.") ) func main() { - flag.Parse() + pflag.Parse() if *showVersion { fmt.Println(version.String()) return diff --git a/cmd/atecontroller/main.go b/cmd/atecontroller/main.go index 61a591032..f7e922273 100644 --- a/cmd/atecontroller/main.go +++ b/cmd/atecontroller/main.go @@ -15,12 +15,12 @@ package main import ( "crypto/tls" - "flag" "os" "github.com/agent-substrate/substrate/internal/controllers" clientv1alpha1 "github.com/agent-substrate/substrate/pkg/api/v1alpha1" "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "github.com/spf13/pflag" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "k8s.io/apimachinery/pkg/runtime" @@ -38,7 +38,7 @@ var ( scheme = runtime.NewScheme() setupLog = ctrl.Log.WithName("setup") - ateAPIConnSpec = flag.String("ateapi-conn-spec", "dns:///api.ate-system.svc:443", "") + ateAPIConnSpec = pflag.String("ateapi-conn-spec", "dns:///api.ate-system.svc:443", "") ) func init() { diff --git a/cmd/atelet/main.go b/cmd/atelet/main.go index 984eef879..cd010e040 100644 --- a/cmd/atelet/main.go +++ b/cmd/atelet/main.go @@ -20,7 +20,6 @@ import ( "crypto/sha256" "encoding/hex" "errors" - "flag" "fmt" "log/slog" "net" @@ -43,6 +42,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/google/go-containerregistry/pkg/authn" googlecontainerauth "github.com/google/go-containerregistry/pkg/v1/google" + "github.com/spf13/pflag" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -57,17 +57,17 @@ import ( ) var ( - port = flag.Int("port", 8085, "The port to listen on") - metricsListenAddr = flag.String("metrics-listen-addr", ":9090", "Address and port the prometheus metrics server should listen on.") + port = pflag.Int("port", 8085, "The port to listen on") + metricsListenAddr = pflag.String("metrics-listen-addr", ":9090", "Address and port the prometheus metrics server should listen on.") - gcpAuthForImagePulls = flag.Bool("gcp-auth-for-image-pulls", true, "Use GCP application default credentials mechanism.") - localhostRegistryReplacement = flag.String("localhost-registry-replacement", "", "The replacement registry endpoint for localhost and/or loopback IP addresses, useful for local development. for example kind-registry:5000") + gcpAuthForImagePulls = pflag.Bool("gcp-auth-for-image-pulls", true, "Use GCP application default credentials mechanism.") + localhostRegistryReplacement = pflag.String("localhost-registry-replacement", "", "The replacement registry endpoint for localhost and/or loopback IP addresses, useful for local development. for example kind-registry:5000") - showVersion = flag.Bool("version", false, "Print version and exit.") + showVersion = pflag.Bool("version", false, "Print version and exit.") ) func main() { - flag.Parse() + pflag.Parse() if *showVersion { fmt.Println(version.String()) return diff --git a/cmd/ateom-gvisor/main.go b/cmd/ateom-gvisor/main.go index cc3aab45c..4adeabfde 100644 --- a/cmd/ateom-gvisor/main.go +++ b/cmd/ateom-gvisor/main.go @@ -18,7 +18,6 @@ package main import ( "context" - "flag" "fmt" "log/slog" "net" @@ -36,6 +35,7 @@ import ( "github.com/agent-substrate/substrate/internal/serverboot" "github.com/agent-substrate/substrate/internal/version" "github.com/hashicorp/go-reap" + "github.com/spf13/pflag" "github.com/vishvananda/netlink" "github.com/vishvananda/netns" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" @@ -45,19 +45,20 @@ import ( ) var ( - podUID = flag.String("pod-uid", "", "The UID of the current pod") + podUID = pflag.String("pod-uid", "", "The UID of the current pod") - showVersion = flag.Bool("version", false, "Print version and exit.") + showVersion = pflag.Bool("version", false, "Print version and exit.") reapLock sync.RWMutex ) func main() { - flag.Parse() + pflag.Parse() if *showVersion { fmt.Println(version.String()) return } + ctx := context.Background() if err := do(ctx); err != nil { diff --git a/cmd/podcertcontroller/main.go b/cmd/podcertcontroller/main.go index a6fb744d9..98a321a6e 100644 --- a/cmd/podcertcontroller/main.go +++ b/cmd/podcertcontroller/main.go @@ -23,7 +23,6 @@ package main import ( "context" - "flag" "fmt" "log/slog" "os" @@ -37,6 +36,7 @@ import ( "github.com/agent-substrate/substrate/internal/servicednssigner" "github.com/agent-substrate/substrate/internal/signercontroller" "github.com/agent-substrate/substrate/internal/version" + "github.com/spf13/pflag" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -54,33 +54,33 @@ func init() { } var ( - kubeconfig = flag.String("kubeconfig", kubeConfigDefault, "absolute path to the kubeconfig file") - inCluster = flag.Bool("in-cluster", false, "Is the controller running in the cluster it should connect to?") + kubeconfig = pflag.String("kubeconfig", kubeConfigDefault, "absolute path to the kubeconfig file") + inCluster = pflag.Bool("in-cluster", false, "Is the controller running in the cluster it should connect to?") - shardingNamespace = flag.String("sharding-pod-namespace", "", "(Work Sharding) The namespace the controller is running in") - shardingPodName = flag.String("sharding-pod-name", "", "(Work Sharding) The pod name of the controller") - shardingPodUID = flag.String("sharding-pod-uid", "", "(Work Sharding) The pod UID of the controller") - shardingApplicationName = flag.String("sharding-application-name", "", "(Work Sharding) The application name to disambiguate Leases") + shardingNamespace = pflag.String("sharding-pod-namespace", "", "(Work Sharding) The namespace the controller is running in") + shardingPodName = pflag.String("sharding-pod-name", "", "(Work Sharding) The pod name of the controller") + shardingPodUID = pflag.String("sharding-pod-uid", "", "(Work Sharding) The pod UID of the controller") + shardingApplicationName = pflag.String("sharding-application-name", "", "(Work Sharding) The application name to disambiguate Leases") - serviceDNSCAPoolFile = flag.String( + serviceDNSCAPoolFile = pflag.String( "service-dns-ca-pool", "", "File that contains the CA pool state for "+servicednssigner.Name, ) - podCAPoolFile = flag.String( + podCAPoolFile = pflag.String( "pod-identity-ca-pool", "", "File that contains the CA pool state for "+podidentitysigner.Name, ) - showVersion = flag.Bool("version", false, "Print version and exit.") + showVersion = pflag.Bool("version", false, "Print version and exit.") ) func main() { ctx := context.Background() - flag.Parse() + pflag.Parse() if *showVersion { fmt.Println(version.String()) return diff --git a/demos/counter/counter.go b/demos/counter/counter.go index 9707672bb..fa667ba91 100644 --- a/demos/counter/counter.go +++ b/demos/counter/counter.go @@ -21,7 +21,6 @@ import ( "crypto/rand" "crypto/sha256" "encoding/base64" - "flag" "fmt" "io" "log/slog" @@ -30,12 +29,14 @@ import ( "os" "sync/atomic" "time" + + "github.com/spf13/pflag" ) var requestCount uint64 func main() { - flag.Parse() + pflag.Parse() ctx := context.Background() slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil))) diff --git a/demos/sandbox/client/main.go b/demos/sandbox/client/main.go index 9bb81e60e..d2b2a5391 100644 --- a/demos/sandbox/client/main.go +++ b/demos/sandbox/client/main.go @@ -19,7 +19,6 @@ import ( "context" "crypto/tls" "encoding/json" - "flag" "fmt" "io" "log" @@ -30,6 +29,7 @@ import ( "syscall" "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "github.com/spf13/pflag" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -59,10 +59,10 @@ func dialAteAPI(endpoint string) (ateapipb.ControlClient, *grpc.ClientConn, erro } func main() { - actorID := flag.String("id", "", "ID of the sandbox actor (required)") - ateapiAddr := flag.String("ateapi", "localhost:8080", "Address of the ateapi gRPC server") - atenetAddr := flag.String("atenet", "localhost:8000", "Address of the atenet HTTP router") - flag.Parse() + actorID := pflag.String("id", "", "ID of the sandbox actor (required)") + ateapiAddr := pflag.String("ateapi", "localhost:8080", "Address of the ateapi gRPC server") + atenetAddr := pflag.String("atenet", "localhost:8000", "Address of the atenet HTTP router") + pflag.Parse() if *actorID == "" { log.Fatal("--id is required") diff --git a/hack/run-e2e.sh b/hack/run-e2e.sh index ce66210d8..d86978afc 100755 --- a/hack/run-e2e.sh +++ b/hack/run-e2e.sh @@ -37,19 +37,19 @@ Arguments after "-args" are passed to the test binary. Example: $0 -run TestExample # Run only TestExample suite - $0 -args -kube-context my-context # Pass kube-context to E2E framework - $0 -run TestExample -args -no-color # Combine both + $0 -args --kube-context my-context # Pass kube-context to E2E framework + $0 -run TestExample -args --no-color # Combine both Common E2E Flags (passed after -args): - -e2e Enable E2E tests (implied by this script) - -no-color Disable colored output - -kube-config Path to kubeconfig file - -kube-context Kubernetes context to use + --e2e Enable E2E tests (implied by this script) + --no-color Disable colored output + --kube-config Path to kubeconfig file + --kube-context Kubernetes context to use Common Go Test Flags (passed before -args): - -run Run only tests matching regexp - -v Verbose output - -count n Run tests n times + -run Run only tests matching regexp + -v Verbose output + -count n Run tests n times See "go help testflag" for more Go test flags. EOF @@ -100,8 +100,8 @@ done extra_e2e_args=() if [[ -n "${KUBECTL_CONTEXT:-}" ]]; then - extra_e2e_args+=("-kube-context" "${KUBECTL_CONTEXT}") + extra_e2e_args+=("--kube-context" "${KUBECTL_CONTEXT}") fi -exec go test -v "$target_path" "${go_test_args[@]}" -args -e2e "${extra_e2e_args[@]}" "${e2e_args[@]}" +exec go test -v "$target_path" "${go_test_args[@]}" -args --e2e "${extra_e2e_args[@]}" "${e2e_args[@]}" diff --git a/internal/controllers/workerpool_controller.go b/internal/controllers/workerpool_controller.go index 7ddaca871..e72d2befd 100644 --- a/internal/controllers/workerpool_controller.go +++ b/internal/controllers/workerpool_controller.go @@ -141,7 +141,7 @@ func buildDeploymentApplyConfig(wp *atev1alpha1.WorkerPool) *appsv1ac.Deployment WithName("ateom"). WithImage(wp.Spec.AteomImage). WithArgs( - "-pod-uid=$(POD_UID)", + "--pod-uid=$(POD_UID)", ). WithSecurityContext(corev1ac.SecurityContext(). WithPrivileged(true). diff --git a/internal/e2e/README.md b/internal/e2e/README.md index 7bddd63d9..99a6cb498 100644 --- a/internal/e2e/README.md +++ b/internal/e2e/README.md @@ -2,7 +2,7 @@ ```shell $ source .ate-dev-env.sh -$ go test -v ./internal/e2e/suites/... -args -e2e +$ go test -v ./internal/e2e/suites/... -args --e2e ``` ## Principles @@ -10,8 +10,8 @@ $ go test -v ./internal/e2e/suites/... -args -e2e * Keep it simple -- use go test for the harness. * e2e tests live under `internal/e2e/suites/` * Each suite should implement TestMain using e2e.RunTestMain() - * e2e tests will be skipped for ordinary unit tests unless the `-e2e` flag - is set e.g. `go test ./internal/e2e/suites/... -args -e2e` + * e2e tests will be skipped for ordinary unit tests unless the `--e2e` flag + is set e.g. `go test ./internal/e2e/suites/... -args --e2e` * Helper libraries live under `internal/e2e` * Setup and Teardown are on a per-component basis and the component's author's responsibility. diff --git a/internal/e2e/testmain.go b/internal/e2e/testmain.go index 490ab39f4..44ae9237c 100644 --- a/internal/e2e/testmain.go +++ b/internal/e2e/testmain.go @@ -16,9 +16,11 @@ package e2e import ( "context" - "flag" + goflag "flag" "fmt" "testing" + + "github.com/spf13/pflag" ) var ( @@ -28,21 +30,22 @@ var ( ) func bindFlags() { - flag.BoolVar(&RunE2E, "e2e", false, "run e2e tests") - flag.BoolVar(&NoColor, "no-color", false, "disable colors in output") - flag.StringVar(&KubeConfig, "kube-config", "", "Location of the kubeconfig") - flag.StringVar(&KubeContext, "kube-context", "", "Kubernetes context to use") + pflag.BoolVar(&RunE2E, "e2e", false, "run e2e tests") + pflag.BoolVar(&NoColor, "no-color", false, "disable colors in output") + pflag.StringVar(&KubeConfig, "kube-config", "", "Location of the kubeconfig") + pflag.StringVar(&KubeContext, "kube-context", "", "Kubernetes context to use") } // RunTestMain should be used to run your e2e test suite. func RunTestMain(m *testing.M) int { bindFlags() - flag.Parse() + pflag.CommandLine.AddGoFlagSet(goflag.CommandLine) + pflag.Parse() if !RunE2E { fmt.Println(Colorf(` This is an e2e test suite and does not run by default. - Run with "go test ./internal/e2e/... -args -e2e"`)) + Run with "go test ./internal/e2e/... -args --e2e"`)) fmt.Println() return 0 }