diff --git a/cli/cmd/chains/kusama/run.go b/cli/cmd/chains/kusama/run.go index e38b63ae..9e9b6c8f 100644 --- a/cli/cmd/chains/kusama/run.go +++ b/cli/cmd/chains/kusama/run.go @@ -2,6 +2,7 @@ package kusama import ( "fmt" + "regexp" "slices" "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves" @@ -12,8 +13,9 @@ import ( ) const ( - localChain = "local" - polkadotJUrl = "http://127.0.0.1:80" + localChain = "local" + polkadotJUrl = "http://127.0.0.1/?rpc=ws%3A%2F%2F127.0.0.1%3A91941#/explorer" + PolkadotJsServiceName = "polkadot-js-explorer" ) func RunKusama(cli *common.Cli) (*common.DiveMultipleServiceResponse, error) { @@ -160,20 +162,48 @@ func startRelayAndParaChain(cli *common.Cli, enclaveContext *enclaves.EnclaveCon } if serviceConfig.Explorer { - explorerResult, err = startExplorer(cli, enclaveContext) + publicEndpoint := "ws://127.0.0.1:9944" + + var isExplorerRunning bool + + allEclaveServices, err := cli.Context().GetAllEnlavesServices() if err != nil { return nil, err } - finalResult = finalResult.ConcatenateDiveResults(explorerResult) - cli.Logger().Info("Redirecting to Polkadot explorer UI...") - if err := common.OpenFile(polkadotJUrl); err != nil { - cli.Logger().Fatalf(common.CodeOf(err), "Failed to open HugoByte Polkadot explorer UI with error %v", err) + for _, enclave := range allEclaveServices { + for serviceName, _ := range enclave { + if serviceName == PolkadotJsServiceName { + isExplorerRunning = true + } + } + } + + if len(finalResult.Dive) > 0 { + for _, serviceResponse := range finalResult.Dive { + publicEndpoint = serviceResponse.PublicEndpoint + break + } } + if !isExplorerRunning { + explorerResult, err = startExplorer(cli, enclaveContext, publicEndpoint) + if err != nil { + return nil, err + } + finalResult = finalResult.ConcatenateDiveResults(explorerResult) + } else { + cli.Logger().Info("Explorer service is already running.") + } + url := updatePort(polkadotJUrl, extractPort(publicEndpoint)) + cli.Logger().Info("Redirecting to Polkadote explorer UI...") + if err := common.OpenFile(url); err != nil { + cli.Logger().Fatalf(common.CodeOf(err), "Failed to open HugoByte Polkadot explorer UI with error %v", err) + } } + return finalResult, nil } @@ -275,7 +305,7 @@ func configureService(serviceConfig *utils.PolkadotServiceConfig) error { func flagCheck() error { if configFilePath != "" { - if len(paraChain) != 0 || network != "" || explorer || metrics || noRelay{ + if len(paraChain) != 0 || network != "" || explorer || metrics || noRelay { return common.WrapMessageToError(common.ErrInvalidFlag, "The '-c' flag does not allow additional flags.") } } @@ -353,8 +383,9 @@ func uploadFiles(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext) error { return nil } -func startExplorer(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext) (*common.DiveMultipleServiceResponse, error) { - para := `{"ws_url":"ws://127.0.0.1:9944"}` +func startExplorer(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext, publicEndpoint string) (*common.DiveMultipleServiceResponse, error) { + para := fmt.Sprintf(`{"ws_url":"%s"}`, publicEndpoint) + runConfig := common.GetStarlarkRunConfig(para, common.DivePolkaDotExplorerPath, runKusamaExplorer) explorerResponseData, err := startService(cli, enclaveCtx, runConfig, "Explorer") if err != nil { @@ -370,7 +401,7 @@ func startMetrics(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext, final_re } paraPrometheus := fmt.Sprintf(`{"service_details":%s}`, service_details) - + runConfigPrometheus := common.GetStarlarkRunConfig(paraPrometheus, common.DivePolkaDotPrometheusPath, runKusamaPrometheus) prometheusResult, err := startService(cli, enclaveCtx, runConfigPrometheus, "Prometheus") if err != nil { @@ -420,3 +451,18 @@ func startService(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext, runConfi return result, nil } + +func updatePort(url string, newPort string) string { + re := regexp.MustCompile(`ws%3A%2F%2F127\.0\.0\.1%3A(\d+)`) + newUrl := re.ReplaceAllString(url, fmt.Sprintf("ws%%3A%%2F%%2F127.0.0.1%%3A%s", newPort)) + return newUrl +} + +func extractPort(url string) string { + re := regexp.MustCompile(`ws://127\.0\.0\.1:(\d+)`) + match := re.FindStringSubmatch(url) + if len(match) > 1 { + return match[1] + } + return "" +} diff --git a/cli/cmd/chains/polkadot/run.go b/cli/cmd/chains/polkadot/run.go index 5d78e74e..90d4c75e 100644 --- a/cli/cmd/chains/polkadot/run.go +++ b/cli/cmd/chains/polkadot/run.go @@ -2,6 +2,7 @@ package polkadot import ( "fmt" + "regexp" "slices" "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves" @@ -12,13 +13,15 @@ import ( ) const ( - localChain = "local" - polkadotJUrl = "http://127.0.0.1:80" + localChain = "local" + polkadotJUrl = "http://127.0.0.1/?rpc=ws%3A%2F%2F127.0.0.1%3A43965#/explorer" + PolkadotJsServiceName = "polkadot-js-explorer" ) func RunPolkadot(cli *common.Cli) (*common.DiveMultipleServiceResponse, error) { enclaveContext, err := cli.Context().GetEnclaveContext(common.EnclaveName) + if err != nil { return nil, common.WrapMessageToError(err, "Failed to retrieve the enclave context for Polkadot.") } @@ -160,14 +163,43 @@ func startRelayAndParaChain(cli *common.Cli, enclaveContext *enclaves.EnclaveCon } if serviceConfig.Explorer { - explorerResult, err = startExplorer(cli, enclaveContext) + publicEndpoint := "ws://127.0.0.1:9944" + + var isExplorerRunning bool + + allEclaveServices, err := cli.Context().GetAllEnlavesServices() if err != nil { return nil, err } - finalResult = finalResult.ConcatenateDiveResults(explorerResult) + for _, enclave := range allEclaveServices { + for serviceName, _ := range enclave { + if serviceName == PolkadotJsServiceName { + isExplorerRunning = true + } + } + } + + if len(finalResult.Dive) > 0 { + for _, serviceResponse := range finalResult.Dive { + publicEndpoint = serviceResponse.PublicEndpoint + break + } + } + + if !isExplorerRunning { + explorerResult, err = startExplorer(cli, enclaveContext, publicEndpoint) + if err != nil { + return nil, err + } + finalResult = finalResult.ConcatenateDiveResults(explorerResult) + } else { + cli.Logger().Info("Explorer service is already running.") + } + + url := updatePort(polkadotJUrl, extractPort(publicEndpoint)) cli.Logger().Info("Redirecting to Polkadote explorer UI...") - if err := common.OpenFile(polkadotJUrl); err != nil { + if err := common.OpenFile(url); err != nil { cli.Logger().Fatalf(common.CodeOf(err), "Failed to open HugoByte Polkadot explorer UI with error %v", err) } } @@ -273,7 +305,7 @@ func configureService(serviceConfig *utils.PolkadotServiceConfig) error { func flagCheck() error { if configFilePath != "" { - if len(paraChain) != 0 || network != "" || explorer || metrics || noRelay{ + if len(paraChain) != 0 || network != "" || explorer || metrics || noRelay { return common.WrapMessageToError(common.ErrInvalidFlag, "The '-c' flag does not allow additional flags.") } } @@ -351,8 +383,8 @@ func uploadFiles(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext) error { return nil } -func startExplorer(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext) (*common.DiveMultipleServiceResponse, error) { - para := `{"ws_url":"ws://127.0.0.1:9944"}` +func startExplorer(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext, publicEndpoint string) (*common.DiveMultipleServiceResponse, error) { + para := fmt.Sprintf(`{"ws_url":"%s"}`, publicEndpoint) runConfig := common.GetStarlarkRunConfig(para, common.DivePolkaDotExplorerPath, runPolkadotExplorer) explorerResponseData, err := startService(cli, enclaveCtx, runConfig, "Explorer") if err != nil { @@ -418,3 +450,18 @@ func startService(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext, runConfi return result, nil } + +func updatePort(url string, newPort string) string { + re := regexp.MustCompile(`ws%3A%2F%2F127\.0\.0\.1%3A(\d+)`) + newUrl := re.ReplaceAllString(url, fmt.Sprintf("ws%%3A%%2F%%2F127.0.0.1%%3A%s", newPort)) + return newUrl +} + +func extractPort(url string) string { + re := regexp.MustCompile(`ws://127\.0\.0\.1:(\d+)`) + match := re.FindStringSubmatch(url) + if len(match) > 1 { + return match[1] + } + return "" +} diff --git a/cli/common/context.go b/cli/common/context.go index f39532da..fabba94f 100644 --- a/cli/common/context.go +++ b/cli/common/context.go @@ -9,6 +9,7 @@ import ( "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves" "github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context" + "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/services" ) type diveContext struct { @@ -85,6 +86,33 @@ func (dc *diveContext) GetEnclaveContext(enclaveName string) (*enclaves.EnclaveC } +func (dc *diveContext) GetAllEnlavesServices() (map[string]map[services.ServiceName]services.ServiceUUID, error) { + enclaves, err := dc.GetEnclaves() + + if err != nil { + return nil, err + } + + allEnclaveSevices := make(map[string]map[services.ServiceName]services.ServiceUUID) + for _, enclave := range enclaves { + enclaveContext, err := dc.GetEnclaveContext(enclave.Name) + + if err != nil { + return nil, err + } + + enclaveServices, err := enclaveContext.GetServices() + + if err != nil { + return nil, err + } + + allEnclaveSevices[enclave.Name] = enclaveServices + } + + return allEnclaveSevices, nil +} + // The `CleanEnclaves` function is a method of the `diveContext` struct. // Used to Cleans given Running Enclaves func (dc *diveContext) CleanEnclaves() ([]*EnclaveInfo, error) { @@ -311,3 +339,4 @@ func (dc *diveContext) GetShortUuid(enclaveName string) (string, error) { return shortUuid, nil } + diff --git a/cli/common/interfaces.go b/cli/common/interfaces.go index 80ae84a9..3350bfdc 100644 --- a/cli/common/interfaces.go +++ b/cli/common/interfaces.go @@ -7,6 +7,7 @@ import ( "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves" "github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context" + "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/services" "github.com/spf13/cobra" ) @@ -86,6 +87,9 @@ type Context interface { // GetEnclaves retrieves information about all enclaves currently running. GetEnclaves() ([]EnclaveInfo, error) + // GetAllEnclavesServices retrives the all running services for all active enclaves. + GetAllEnlavesServices() (map[string]map[services.ServiceName]services.ServiceUUID, error) + // GetEnclaveContext retrieves the context of a specific enclave by its name. GetEnclaveContext(enclaveName string) (*enclaves.EnclaveContext, error) diff --git a/cli/output/dive/services_dive_f4bd60ed5923.json b/cli/output/dive/services_dive_f4bd60ed5923.json deleted file mode 100644 index 8f990e01..00000000 --- a/cli/output/dive/services_dive_f4bd60ed5923.json +++ /dev/null @@ -1 +0,0 @@ -{"node-service-archway-node-0":{"service_name":"node-service-archway-node-0","endpoint_public":"http://127.0.0.1:4564","endpoint":"http://172.16.4.5:26657","chain_id":"archway-node-0","chain_key":"archway-node-0-key"}} \ No newline at end of file