Skip to content
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
25 changes: 25 additions & 0 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Examples:
cmd.Flags().BoolVar(&singleNamespace, "single-namespace", false, "Deploy all components in a single namespace ('stackrox' by default)")
cmd.Flags().StringVarP(&tag, "tag", "t", "", "Main image tag to use for deployment (takes precedence over MAIN_IMAGE_TAG environment variable)")
cmd.Flags().StringSliceVar(&featureFlags, "features", []string{}, "Feature flag settings (e.g., +ROX_FOO,-ROX_BAR,ROX_BAZ=true)")
cmd.Flags().StringVar(&centralWait, "central-wait", deployer.DefaultCentralWaitTimeout.String(), "Maximum wait time for Central to become ready (e.g., 5m, 10m)")
cmd.Flags().StringVar(&securedClusterWait, "secured-cluster-wait", deployer.DefaultSecuredClusterWaitTimeout.String(), "Maximum wait time for SecuredCluster to become ready (e.g., 5m, 10m)")

return cmd
}
Expand Down Expand Up @@ -207,6 +209,29 @@ func runDeploy(cmd *cobra.Command, args []string) error {
d.SetPauseReconciliation(pauseReconciliation)
d.SetSingleNamespace(singleNamespace)

// Parse and set wait timeouts only if flags were provided
if cmd.Flags().Changed("central-wait") {
centralWaitDuration, err := time.ParseDuration(centralWait)
Comment thread
AlexVulaj marked this conversation as resolved.
if err == nil && centralWaitDuration <= 0 {
err = errors.New("--central-wait duration must be positive")
}
if err != nil {
return fmt.Errorf("invalid --central-wait duration: %w", err)
}
d.SetCentralWaitTimeout(centralWaitDuration)
}

if cmd.Flags().Changed("secured-cluster-wait") {
securedClusterWaitDuration, err := time.ParseDuration(securedClusterWait)
Comment thread
AlexVulaj marked this conversation as resolved.
if err == nil && securedClusterWaitDuration <= 0 {
err = errors.New("--secured-cluster-wait duration must be positive")
}
if err != nil {
return fmt.Errorf("invalid --secured-cluster-wait duration: %w", err)
}
d.SetSecuredClusterWaitTimeout(securedClusterWaitDuration)
}

var mainImageTag string
if tag != "" {
log.Dimf("Using main image tag from --tag flag: %s", tag)
Expand Down
2 changes: 2 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ var (
singleNamespace bool
tag string
featureFlags []string
centralWait string
securedClusterWait string
)

func main() {
Expand Down
4 changes: 2 additions & 2 deletions internal/deployer/deploy_via_helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (d *Deployer) deployCentralHelm(ctx context.Context, resources, exposure st
return fmt.Errorf("failed to install helm chart: %w", err)
}

if err := d.waitForCentralReady(ctx, 600); err != nil {
if err := d.waitForCentralReady(ctx, d.centralWaitTimeout); err != nil {
return fmt.Errorf("failed waiting for Central: %w", err)
}

Expand Down Expand Up @@ -168,7 +168,7 @@ func (d *Deployer) deploySecuredClusterHelm(ctx context.Context, resources strin
return fmt.Errorf("failed to install helm chart: %w", err)
}

if err := d.waitForSecuredClusterReady(ctx, 600); err != nil {
if err := d.waitForSecuredClusterReady(ctx, d.securedClusterWaitTimeout); err != nil {
return fmt.Errorf("failed waiting for SecuredCluster: %w", err)
}

Expand Down
16 changes: 8 additions & 8 deletions internal/deployer/deploy_via_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func (d *Deployer) deployCentralOperator(ctx context.Context, resources, exposur
return fmt.Errorf("failed to apply Central CR: %w", err)
}

if err := d.waitForCentralReady(ctx, 600); err != nil {
if err := d.waitForCentralReady(ctx, d.centralWaitTimeout); err != nil {
return fmt.Errorf("failed waiting for Central: %w", err)
}

Expand Down Expand Up @@ -441,8 +441,8 @@ func (d *Deployer) applyCentralCR(ctx context.Context, cr map[string]interface{}
}

// waitForCentralReady waits for Central to be ready
func (d *Deployer) waitForCentralReady(ctx context.Context, timeout int) error {
d.logger.Info("⏳ Waiting for Central to become ready...")
func (d *Deployer) waitForCentralReady(ctx context.Context, timeout time.Duration) error {
d.logger.Infof("⏳ Waiting for Central to become ready (timeout: %s)...", timeout)

// Track seen deployments and their states to avoid duplicate messages
seenDeployments := make(map[string]string)
Expand All @@ -451,7 +451,7 @@ func (d *Deployer) waitForCentralReady(ctx context.Context, timeout int) error {
start := time.Now()
checkInterval := 3 * time.Second

for time.Since(start) < time.Duration(timeout)*time.Second {
for time.Since(start) < timeout {
// Check for new deployments
d.checkDeploymentProgress(ctx, seenDeployments)

Expand Down Expand Up @@ -643,7 +643,7 @@ func (d *Deployer) deploySecuredClusterOperator(ctx context.Context, resources s
return fmt.Errorf("failed to apply SecuredCluster CR: %w", err)
}

if err := d.waitForSecuredClusterReady(ctx, 600); err != nil {
if err := d.waitForSecuredClusterReady(ctx, d.securedClusterWaitTimeout); err != nil {
return fmt.Errorf("failed waiting for SecuredCluster: %w", err)
}

Expand Down Expand Up @@ -770,8 +770,8 @@ func (d *Deployer) applySecuredClusterCR(ctx context.Context, cr map[string]inte
}

// waitForSecuredClusterReady waits for SecuredCluster to be ready
func (d *Deployer) waitForSecuredClusterReady(ctx context.Context, timeout int) error {
d.logger.Info("⏳ Waiting for SecuredCluster to become ready...")
func (d *Deployer) waitForSecuredClusterReady(ctx context.Context, timeout time.Duration) error {
d.logger.Infof("⏳ Waiting for SecuredCluster to become ready (timeout: %s)...", timeout)

// Track seen deployments and their states to avoid duplicate messages
seenDeployments := make(map[string]string)
Expand All @@ -780,7 +780,7 @@ func (d *Deployer) waitForSecuredClusterReady(ctx context.Context, timeout int)
start := time.Now()
checkInterval := 3 * time.Second

for time.Since(start) < time.Duration(timeout)*time.Second {
for time.Since(start) < timeout {
d.checkDeploymentProgressInNamespace(ctx, d.sensorNamespace, seenDeployments)

if d.earlyReadiness || d.verbose {
Expand Down
93 changes: 54 additions & 39 deletions internal/deployer/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ var (
sensorNamespace = "acs-sensor"
defaultExposure = "loadbalancer"

DefaultCentralWaitTimeout = 10 * time.Minute
DefaultSecuredClusterWaitTimeout = 10 * time.Minute

pauseReconcileAnnotationKey = "stackrox.io/pause-reconcile"

// AdminUsername is the default admin username for StackRox Central
Expand Down Expand Up @@ -98,37 +101,39 @@ var (

// Deployer is the base deployer for ACS
type Deployer struct {
logger *logger.Logger
startTime time.Time
dockerAuth *dockerauth.DockerAuth
imageCache *imagecache.ImageCache
portForward *portforward.Manager
clusterDefaults *clusterdefaults.Manager
kubectl string
roxctlVersion string
centralNamespace string
sensorNamespace string
mainImageTag string
operatorTag string
centralEndpoint string
centralPassword string
roxCACertFile string
kubeContext string
portForwardEnabled bool
pauseReconciliation bool
exposure string
centralOverrides map[string]interface{}
securedClusterOverrides map[string]interface{}
featureFlagOverrides map[string]interface{}
envrcFile string
useHelm bool
useOLM bool
useKonflux bool
shouldDeployOperator bool
verbose bool
earlyReadiness bool
dockerCreds *dockerauth.Credentials
clusterResourceKinds map[string]struct{}
logger *logger.Logger
startTime time.Time
dockerAuth *dockerauth.DockerAuth
imageCache *imagecache.ImageCache
portForward *portforward.Manager
clusterDefaults *clusterdefaults.Manager
kubectl string
roxctlVersion string
centralNamespace string
sensorNamespace string
mainImageTag string
operatorTag string
centralEndpoint string
centralPassword string
roxCACertFile string
kubeContext string
portForwardEnabled bool
pauseReconciliation bool
exposure string
centralOverrides map[string]interface{}
securedClusterOverrides map[string]interface{}
featureFlagOverrides map[string]interface{}
envrcFile string
useHelm bool
useOLM bool
useKonflux bool
shouldDeployOperator bool
verbose bool
earlyReadiness bool
centralWaitTimeout time.Duration
securedClusterWaitTimeout time.Duration
dockerCreds *dockerauth.Credentials
clusterResourceKinds map[string]struct{}
}

type ResourceKindWithName struct {
Expand Down Expand Up @@ -476,14 +481,16 @@ func New(log *logger.Logger) (*Deployer, error) {
kubectl := getKubectl()

d := &Deployer{
logger: log,
startTime: time.Now(),
kubectl: kubectl,
roxctlVersion: roxctlVersion,
centralNamespace: centralNamespace,
sensorNamespace: sensorNamespace,
exposure: defaultExposure,
shouldDeployOperator: true,
logger: log,
startTime: time.Now(),
kubectl: kubectl,
roxctlVersion: roxctlVersion,
centralNamespace: centralNamespace,
sensorNamespace: sensorNamespace,
exposure: defaultExposure,
shouldDeployOperator: true,
centralWaitTimeout: DefaultCentralWaitTimeout,
securedClusterWaitTimeout: DefaultSecuredClusterWaitTimeout,
}

d.dockerAuth = dockerauth.New(log)
Expand Down Expand Up @@ -923,6 +930,14 @@ func (d *Deployer) SetEarlyReadiness(enabled bool) {
d.earlyReadiness = enabled
}

func (d *Deployer) SetCentralWaitTimeout(timeout time.Duration) {
d.centralWaitTimeout = timeout
}

func (d *Deployer) SetSecuredClusterWaitTimeout(timeout time.Duration) {
d.securedClusterWaitTimeout = timeout
}

func (d *Deployer) SetPauseReconciliation(enabled bool) {
d.pauseReconciliation = enabled
}
Expand Down
Loading