diff --git a/pkg/cmd/roachtest/cluster.go b/pkg/cmd/roachtest/cluster.go index f237a1402bf8..3c9e9311b352 100644 --- a/pkg/cmd/roachtest/cluster.go +++ b/pkg/cmd/roachtest/cluster.go @@ -2490,6 +2490,12 @@ func (c *clusterImpl) ExternalAdminUIAddr( return c.adminUIAddr(ctx, l, node, true) } +func (c *clusterImpl) AdminUIPorts( + ctx context.Context, l *logger.Logger, nodes option.NodeListOption, +) ([]int, error) { + return roachprod.AdminPorts(ctx, l, c.MakeNodes(nodes), c.IsSecure()) +} + func (c *clusterImpl) adminUIAddr( ctx context.Context, l *logger.Logger, node option.NodeListOption, external bool, ) ([]string, error) { diff --git a/pkg/cmd/roachtest/cluster/cluster_interface.go b/pkg/cmd/roachtest/cluster/cluster_interface.go index 7dba4593551a..dc54c2fb0d98 100644 --- a/pkg/cmd/roachtest/cluster/cluster_interface.go +++ b/pkg/cmd/roachtest/cluster/cluster_interface.go @@ -86,10 +86,11 @@ type Cluster interface { Conn(ctx context.Context, l *logger.Logger, node int, opts ...func(*option.ConnOption)) *gosql.DB ConnE(ctx context.Context, l *logger.Logger, node int, opts ...func(*option.ConnOption)) (*gosql.DB, error) - // URLs for the Admin UI. + // URLs and Ports for the Admin UI. InternalAdminUIAddr(ctx context.Context, l *logger.Logger, node option.NodeListOption) ([]string, error) ExternalAdminUIAddr(ctx context.Context, l *logger.Logger, node option.NodeListOption) ([]string, error) + AdminUIPorts(ctx context.Context, l *logger.Logger, node option.NodeListOption) ([]int, error) // Running commands on nodes. diff --git a/pkg/cmd/roachtest/option/options.go b/pkg/cmd/roachtest/option/options.go index 3d24df4e9a79..29717bcdc3e9 100644 --- a/pkg/cmd/roachtest/option/options.go +++ b/pkg/cmd/roachtest/option/options.go @@ -63,6 +63,8 @@ func DefaultStartVirtualClusterOpts(tenantName string, sqlInstance int) StartOpt startOpts.RoachprodOpts.Target = install.StartServiceForVirtualCluster startOpts.RoachprodOpts.VirtualClusterName = tenantName startOpts.RoachprodOpts.SQLInstance = sqlInstance + startOpts.RoachprodOpts.SQLPort = 0 + startOpts.RoachprodOpts.AdminUIPort = 0 return startOpts } diff --git a/pkg/cmd/roachtest/tests/gossip.go b/pkg/cmd/roachtest/tests/gossip.go index ea3afd04665a..49ddac1f934a 100644 --- a/pkg/cmd/roachtest/tests/gossip.go +++ b/pkg/cmd/roachtest/tests/gossip.go @@ -425,13 +425,18 @@ SELECT count(replicas) t.L().Printf("killing all nodes\n") c.Stop(ctx, t.L(), option.DefaultStopOpts()) + adminPorts, err := c.AdminUIPorts(ctx, t.L(), c.Node(1)) + if err != nil { + t.Fatal(err) + } + // Restart node 1, but have it listen on a different port for internal // connections. This will require node 1 to reach out to the other nodes in // the cluster for gossip info. - err := c.RunE(ctx, c.Node(1), + err = c.RunE(ctx, c.Node(1), ` ./cockroach start --insecure --background --store={store-dir} `+ `--log-dir={log-dir} --cache=10% --max-sql-memory=10% `+ - `--listen-addr=:$[{pgport:1}+1000] --http-port=$[{pgport:1}+1] `+ + fmt.Sprintf(`--listen-addr=:$[{pgport:1}+1000] --http-port=%d `, adminPorts[0])+ `--join={pghost:1}:{pgport:1} `+ `--advertise-addr={pghost:1}:$[{pgport:1}+1000] `+ `> {log-dir}/cockroach.stdout 2> {log-dir}/cockroach.stderr`) diff --git a/pkg/roachprod/roachprod.go b/pkg/roachprod/roachprod.go index e24bd7418285..a956a8214561 100644 --- a/pkg/roachprod/roachprod.go +++ b/pkg/roachprod/roachprod.go @@ -1075,6 +1075,28 @@ func AdminURL( return urlGenerator(ctx, c, l, c.TargetNodes(), uConfig) } +// AdminPorts finds the AdminUI ports for a cluster. +func AdminPorts( + ctx context.Context, l *logger.Logger, clusterName string, secure bool, +) ([]int, error) { + if err := LoadClusters(); err != nil { + return nil, err + } + c, err := newCluster(l, clusterName, install.SecureOption(secure)) + if err != nil { + return nil, err + } + var ports []int + for _, node := range c.Nodes { + port, err := c.NodeUIPort(ctx, node) + if err != nil { + return nil, errors.Wrapf(err, "Error discovering UI Port for node %d", node) + } + ports = append(ports, port) + } + return ports, nil +} + // PprofOpts specifies the options needed by Pprof(). type PprofOpts struct { Heap bool