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
50 changes: 8 additions & 42 deletions cmd/agentbasedinstaller/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,10 @@ func main() {
ctx := context.Background()
log.Info("SERVICE_BASE_URL: " + Options.ServiceBaseUrl)

// TODO: This is for backward compatibility and should be removed once the
// ephemeral ISO services are using the subcommands.
if path.Base(os.Args[0]) == "agent-based-installer-register-cluster-and-infraenv" {
register(ctx, log, bmInventory)
return
}
if len(os.Args) < 2 {
log.Fatal("No subcommand specified")
}
switch os.Args[1] {
case "register":
// registers both cluster and infraenv
infraEnvID := register(ctx, log, bmInventory)
os.WriteFile("/etc/assisted/client_config", []byte("INFRA_ENV_ID="+infraEnvID), 0644)
case "registerCluster":
clusterID := registerCluster(ctx, log, bmInventory)
os.WriteFile("/etc/assisted/client_config", []byte("CLUSTER_ID="+clusterID), 0644)
Expand All @@ -121,45 +111,17 @@ func main() {
}
}

func register(ctx context.Context, log *log.Logger, bmInventory *client.AssistedInstall) string {
func registerCluster(ctx context.Context, log *log.Logger, bmInventory *client.AssistedInstall) string {
err := envconfig.Process("", &RegisterOptions)
if err != nil {
log.Fatal(err.Error())
}

pullSecret, err := agentbasedinstaller.GetPullSecret(RegisterOptions.PullSecretFile)
if err != nil {
log.Fatal("Failed to get pull secret: ", err.Error())
}

modelsCluster, err := agentbasedinstaller.RegisterCluster(ctx, log, bmInventory, pullSecret,
RegisterOptions.ClusterDeploymentFile, RegisterOptions.AgentClusterInstallFile, RegisterOptions.ClusterImageSetFile,
RegisterOptions.ReleaseImageMirror, RegisterOptions.OperatorInstallFile, false)
if err != nil {
log.Fatal("Failed to register cluster with assisted-service: ", err)
}

modelsInfraEnv, err := agentbasedinstaller.RegisterInfraEnv(ctx, log, bmInventory, pullSecret,
modelsCluster, RegisterOptions.InfraEnvFile, RegisterOptions.NMStateConfigFile, RegisterOptions.ImageTypeISO, "")
if err != nil {
log.Fatal("Failed to register infraenv with assisted-service: ", err)
}
err = agentbasedinstaller.RegisterExtraManifests(os.DirFS(RegisterOptions.ExtraManifests), ctx, log, bmInventory.Manifests, modelsCluster)
if err != nil {
log.Fatal("Failed to register extra manifests with assisted-service: ", err)
}

return modelsInfraEnv.ID.String()
}

func registerCluster(ctx context.Context, log *log.Logger, bmInventory *client.AssistedInstall) string {
err := envconfig.Process("", &RegisterOptions)
existingCluster, err := agentbasedinstaller.GetCluster(ctx, log, bmInventory)
if err != nil {
log.Fatal(err.Error())
}

existingCluster, err := agentbasedinstaller.GetCluster(ctx, log, bmInventory)
if err == nil {
if existingCluster != nil {
log.Infof("Skipping cluster registration. Found existing cluster with id: %s", existingCluster.ID.String())
return existingCluster.ID.String()
}
Expand Down Expand Up @@ -205,7 +167,11 @@ func registerInfraEnv(ctx context.Context, log *log.Logger, bmInventory *client.
if err != nil {
log.Fatal("Failed to find cluster when registering infraenv: ", err)
} else {
log.Infof("Reference to cluster id: %s", modelsCluster.ID.String())
if modelsCluster != nil {
log.Infof("Reference to cluster id: %s", modelsCluster.ID.String())
} else {
log.Info("No Cluster found, registering InfraEnv for late binding")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried a POC including this PR and openshift/installer#9960 This works fine such that now first the infra-env is created and cluster object is only attempted to be created when in case of OVE, user enters details such as name, basedomain, pull-secret etc from the first page and hits next button. At that time, assisted service does throw an error here because the infra-env was already created. -

Sep 30 19:04:47 localhost.localdomain service[3731]: time="2025-09-30T19:04:47Z" 
level=error msg="failed to create infraenv" 
func="github.com/openshift/assisted-service/internal/bminventory.(*bareMetalInventory).RegisterInfraEnvInternal.func1" 

file="/src/internal/bminventory/inventory.go:4983" cluster_id=f7861ee0-b07d-428a-b1c3-020c84ff3651 

error="ERROR: duplicate key value violates unique constraint \"infra_envs_pkey\" (SQLSTATE 23505)" 

go-id=324 pkg=Inventory request_id=16e21b82-9d86-424e-8a41-86c7ce3bd108

Sep 30 19:04:47 localhost.localdomain service[3731]: time="2025-09-30T19:04:47Z" 
level=error msg="Failed to register InfraEnv mycluster_infra-env with id f7861ee0-b07d-428a-b1c3-020c84ff3651. 
Error: ERROR: duplicate key value violates unique constraint \"infra_envs_pkey\" (SQLSTATE 23505)" 
func="github.com/openshift/assisted-service/internal/bminventory.(*bareMetalInventory).RegisterInfraEnvInternal"
file="/src/internal/bminventory/inventory.go:4993" 
cluster_id=f7861ee0-b07d-428a-b1c3-020c84ff3651 go-id=324 pkg=Inventory request_id=16e21b82-9d86-424e-8a41-86c7ce3bd108

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, it should first check if infra-env is already created

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agent-register-infraenv.service

Sep 30 18:51:47 localhost.localdomain agent-register-infraenv[4018]: time="2025-09-30T18:51:47Z" level=info msg="No Cluster found, registering InfraEnv for late binding"
Sep 30 18:51:47 localhost.localdomain agent-register-infraenv[4018]: time="2025-09-30T18:51:47Z" level=info msg="Registering infraenv"
Sep 30 18:51:47 localhost.localdomain podman[4001]: time="2025-09-30T18:51:47Z" level=info msg="No Cluster found, registering InfraEnv for late binding"
Sep 30 18:51:47 localhost.localdomain podman[4001]: time="2025-09-30T18:51:47Z" level=info msg="Registering infraenv"
Sep 30 18:51:47 localhost.localdomain podman[4001]: time="2025-09-30T18:51:47Z" level=info msg="Registered infraenv with id: f7861ee0-b07d-428a-b1c3-020c84ff3651"
Sep 30 18:51:47 localhost.localdomain agent-register-infraenv[4018]: time="2025-09-30T18:51:47Z" level=info msg="Registered infraenv with id: f7861ee0-b07d-428a-b1c3-020c84ff3651"```

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is expected with the current UI implementation, because in ABI we define the InfraEnv UUID at ISO generation time (it's passed as an env var to assisted-service). That shouldn't block merging of this PR because this one has no effect in practice by itself.

However, before merging openshift/installer#9960 we will need to update the UI to cope with this flow. To start with, having the UI check for the existence of an InfraEnv before creating a new one would allow you to get a bit further with the PoC.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pawanpinjarkar the main goal of the PoC is to support designing a solution for https://issues.redhat.com/browse/AGENT-1294, and thus identify a gap list - to prepare a breakdown for the epic. I also didn't expect that the UI worked out-of-the-box, and the good thing is that the PoC confirmed that - so another point for the gap list.
A quick hack to proceed with the exploration in the PoC is to disable the UI and manually simulate its behavior by directly interacting with AS after the agent-register-infraenv service (with the basic idea of supporting just one workflow, where instead of running the start-cluster-installation service then the agent-start-ui is executed (when requested)

}
}

modelsInfraEnv, err := agentbasedinstaller.RegisterInfraEnv(ctx, log, bmInventory, pullSecret,
Expand Down
11 changes: 8 additions & 3 deletions cmd/agentbasedinstaller/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"reflect"
"regexp"

"github.com/go-openapi/strfmt"
hiveext "github.com/openshift/assisted-service/api/hiveextension/v1beta1"
aiv1beta1 "github.com/openshift/assisted-service/api/v1beta1"
"github.com/openshift/assisted-service/client"
Expand Down Expand Up @@ -159,7 +160,11 @@ func RegisterInfraEnv(ctx context.Context, log *log.Logger, bmInventory *client.
return nil, infraenvErr
}

infraEnvParams := controllers.CreateInfraEnvParams(&infraEnv, models.ImageType(imageTypeISO), pullSecret, modelsCluster.ID, modelsCluster.OpenshiftVersion)
var clusterID *strfmt.UUID
if modelsCluster != nil {
clusterID = modelsCluster.ID
}
infraEnvParams := controllers.CreateInfraEnvParams(&infraEnv, models.ImageType(imageTypeISO), pullSecret, clusterID, "")

var nmStateConfig aiv1beta1.NMStateConfig

Expand Down Expand Up @@ -237,7 +242,7 @@ func RegisterExtraManifests(fsys fs.FS, ctx context.Context, log *log.Logger, cl
func GetCluster(ctx context.Context, log *log.Logger, bmInventory *client.AssistedInstall) (cluster *models.Cluster, err error) {
list, err := bmInventory.Installer.V2ListClusters(ctx, &installer.V2ListClustersParams{})
if err != nil {
return nil, err
return nil, errorutil.GetAssistedError(err)
}
clusterList := list.Payload
numClusters := len(clusterList)
Expand All @@ -246,7 +251,7 @@ func GetCluster(ctx context.Context, log *log.Logger, bmInventory *client.Assist
return nil, errors.New(errorMessage)
}
if numClusters == 0 {
return nil, errors.New("No clusters registered in assisted-service")
return nil, nil
}
return clusterList[0], nil
}
Expand Down