diff options
author | jonmv <venstad@gmail.com> | 2023-07-06 17:37:08 +0200 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2023-07-06 17:37:08 +0200 |
commit | 49b755a8636f0f5a7c1ff3518f91bc1b278efc09 (patch) | |
tree | f4d293239087b373947ab63f95e4e1e817742e91 /node-repository/src/main/java/com/yahoo/vespa/hosted/provision | |
parent | 2411f3779211e182d155c88e674cbb274035b78a (diff) |
Look up GCP hosts by GCP instance ID
Diffstat (limited to 'node-repository/src/main/java/com/yahoo/vespa/hosted/provision')
6 files changed, 50 insertions, 30 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java index 720b7bca954..48a1f0a72f0 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java @@ -46,6 +46,7 @@ public final class Node implements Nodelike { private final String hostname; private final IP.Config ipConfig; private final String id; + private final Optional<String> extraId; private final Optional<String> parentHostname; private final Flavor flavor; private final Status status; @@ -89,13 +90,14 @@ public final class Node implements Nodelike { } /** DO NOT USE: public for serialization purposes. See {@code create} helper methods. */ - public Node(String id, IP.Config ipConfig, String hostname, Optional<String> parentHostname, + public Node(String id, Optional<String> extraId, IP.Config ipConfig, String hostname, Optional<String> parentHostname, Flavor flavor, Status status, State state, Optional<Allocation> allocation, History history, NodeType type, Reports reports, Optional<String> modelName, Optional<TenantName> reservedTo, Optional<ApplicationId> exclusiveToApplicationId, Optional<Duration> hostTTL, Optional<Instant> hostEmptyAt, Optional<ClusterSpec.Type> exclusiveToClusterType, Optional<String> switchHostname, List<TrustStoreItem> trustStoreItems, CloudAccount cloudAccount, Optional<WireguardKey> wireguardPubKey) { this.id = Objects.requireNonNull(id, "A node must have an ID"); + this.extraId = Objects.requireNonNull(extraId, "Extra ID cannot be null"); this.hostname = requireNonEmptyString(hostname, "A node must have a hostname"); this.ipConfig = Objects.requireNonNull(ipConfig, "A node must a have an IP config"); this.parentHostname = requireNonEmptyString(parentHostname, "A parent host name must be a proper value"); @@ -160,9 +162,13 @@ public final class Node implements Nodelike { * - OpenStack: UUID * - AWS: Instance ID * - Linux containers: UUID + * - GCP: Instance name */ public String id() { return id; } + /** Additional unique identifier for this node, if any, as above. GCP instance ID. */ + public Optional<String> extraId() { return extraId; } + @Override public Optional<String> parentHostname() { return parentHostname; } @@ -351,14 +357,14 @@ public final class Node implements Nodelike { /** Returns a node with the status assigned to the given value */ public Node with(Status status) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } /** Returns a node with the type assigned to the given value */ public Node with(NodeType type) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } @@ -367,35 +373,35 @@ public final class Node implements Nodelike { public Node with(Flavor flavor, Agent agent, Instant instant) { if (flavor.equals(this.flavor)) return this; History updateHistory = history.with(new History.Event(History.Event.Type.resized, agent, instant)); - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, updateHistory, type, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, updateHistory, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } /** Returns a copy of this with the reboot generation set to generation */ public Node withReboot(Generation generation) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status.withReboot(generation), state, allocation, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status.withReboot(generation), state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } /** Returns a copy of this with given id set */ public Node withId(String id) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } /** Returns a copy of this with model name set to given value */ public Node withModelName(String modelName) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, Optional.of(modelName), reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } /** Returns a copy of this with model name cleared */ public Node withoutModelName() { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, Optional.empty(), reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } @@ -437,21 +443,21 @@ public final class Node implements Nodelike { * Do not use this to allocate a node. */ public Node with(Allocation allocation) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, Optional.of(allocation), history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, Optional.of(allocation), history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } /** Returns a copy of this node with IP config set to the given value. */ public Node with(IP.Config ipConfig) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } /** Returns a copy of this node with the parent hostname assigned to the given value. */ public Node withParentHostname(String parentHostname) { - return new Node(id, ipConfig, hostname, Optional.of(parentHostname), flavor, status, state, allocation, + return new Node(id, extraId, ipConfig, hostname, Optional.of(parentHostname), flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } @@ -459,51 +465,57 @@ public final class Node implements Nodelike { public Node withReservedTo(TenantName tenant) { if (type != NodeType.host) throw new IllegalArgumentException("Only host nodes can be reserved, " + hostname + " has type " + type); - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, Optional.of(tenant), exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } /** Returns a copy of this node which is not reserved to a tenant */ public Node withoutReservedTo() { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, Optional.empty(), exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } public Node withExclusiveToApplicationId(ApplicationId exclusiveTo) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, Optional.ofNullable(exclusiveTo), hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } + public Node withExtraId(String extraId) { + return new Node(id, Optional.of(extraId), ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, + exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); + } + public Node withHostTTL(Duration hostTTL) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, Optional.ofNullable(hostTTL), hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } public Node withHostEmptyAt(Instant hostEmptyAt) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, Optional.ofNullable(hostEmptyAt), exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } public Node withExclusiveToClusterType(ClusterSpec.Type exclusiveTo) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, Optional.ofNullable(exclusiveTo), switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } public Node withWireguardPubkey(WireguardKey wireguardPubkey) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, Optional.ofNullable(wireguardPubkey)); } /** Returns a copy of this node with switch hostname set to given value */ public Node withSwitchHostname(String switchHostname) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, Optional.ofNullable(switchHostname), trustStoreItems, cloudAccount, wireguardPubKey); } @@ -556,19 +568,19 @@ public final class Node implements Nodelike { /** Returns a copy of this node with the given history. */ public Node with(History history) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } public Node with(Reports reports) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } public Node with(List<TrustStoreItem> trustStoreItems) { - return new Node(id, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, + return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt, exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey); } @@ -814,7 +826,7 @@ public final class Node implements Nodelike { } public Node build() { - return new Node(id, Optional.ofNullable(ipConfig).orElse(IP.Config.EMPTY), hostname, Optional.ofNullable(parentHostname), + return new Node(id, Optional.empty(), Optional.ofNullable(ipConfig).orElse(IP.Config.EMPTY), hostname, Optional.ofNullable(parentHostname), flavor, Optional.ofNullable(status).orElseGet(Status::initial), state, Optional.ofNullable(allocation), Optional.ofNullable(history).orElseGet(History::empty), type, Optional.ofNullable(reports).orElseGet(Reports::new), Optional.ofNullable(modelName), Optional.ofNullable(reservedTo), Optional.ofNullable(exclusiveToApplicationId), diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostResumeProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostResumeProvisioner.java index 539fef836b1..9279592f4cc 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostResumeProvisioner.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostResumeProvisioner.java @@ -83,9 +83,12 @@ public class HostResumeProvisioner extends NodeRepositoryMaintainer { nodeRepository().nodes().performOnRecursively(NodeList.of(host), __ -> true, nodes -> { List<Node> updated = new ArrayList<>(); - for (NodeMutex mutex : nodes.nodes().nodes()) + for (NodeMutex mutex : nodes.children()) updated.add(nodeRepository().nodes().write(mutex.node().with(hostIpConfig.require(mutex.node().hostname())), mutex)); + updated.add(nodeRepository().nodes().write(nodes.parent().node() + .with(hostIpConfig.require(nodes.parent().node().hostname())), nodes.parent())); + return updated; }); } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java index 037338cb2ed..10e729e87b3 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java @@ -207,7 +207,7 @@ public class CuratorDb { CuratorTransaction curatorTransaction = db.newCuratorTransactionIn(transaction); for (Node node : nodes) { - Node newNode = new Node(node.id(), node.ipConfig(), node.hostname(), + Node newNode = new Node(node.id(), node.extraId(), node.ipConfig(), node.hostname(), node.parentHostname(), node.flavor(), newNodeStatus(node, toState), toState, diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java index f52ce5d690d..76a720e13e8 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java @@ -74,6 +74,7 @@ public class NodeSerializer { private static final String containersKey = "containers"; private static final String containerHostnameKey = "hostname"; private static final String idKey = "openStackId"; + private static final String extraIdKey = "extraId"; private static final String parentHostnameKey = "parentHostname"; private static final String historyKey = "history"; private static final String logKey = "log"; @@ -173,6 +174,7 @@ public class NodeSerializer { toSlime(node.ipConfig().pool().asSet(), object.setArray(ipAddressPoolKey)); toSlime(node.ipConfig().pool().hostnames(), object); object.setString(idKey, node.id()); + node.extraId().ifPresent(id -> object.setString(extraIdKey, id)); node.parentHostname().ifPresent(hostname -> object.setString(parentHostnameKey, hostname)); toSlime(node.flavor(), object); object.setLong(rebootGenerationKey, node.status().reboot().wanted()); @@ -283,6 +285,7 @@ public class NodeSerializer { private Node nodeFromSlime(Inspector object) { Flavor flavor = flavorFromSlime(object); return new Node(object.field(idKey).asString(), + SlimeUtils.optionalString(object.field(extraIdKey)), IP.Config.of(ipAddressesFromSlime(object, ipAddressesKey), ipAddressesFromSlime(object, ipAddressPoolKey), hostnamesFromSlime(object)), diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostIpConfig.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostIpConfig.java index 3c28d9d1196..225f4827a18 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostIpConfig.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostIpConfig.java @@ -5,18 +5,20 @@ import com.yahoo.vespa.hosted.provision.node.IP; import java.util.Map; import java.util.Objects; +import java.util.Optional; /** - * IP config of a host and its children. + * IP config of a host and its children, and an optional extra host ID. * * @author mpolden */ -public record HostIpConfig(Map<String, IP.Config> ipConfigByHostname) { +public record HostIpConfig(Map<String, IP.Config> ipConfigByHostname, Optional<String> hostId) { - public static final HostIpConfig EMPTY = new HostIpConfig(Map.of()); + public static final HostIpConfig EMPTY = new HostIpConfig(Map.of(), Optional.empty()); - public HostIpConfig(Map<String, IP.Config> ipConfigByHostname) { + public HostIpConfig(Map<String, IP.Config> ipConfigByHostname, Optional<String> hostId) { this.ipConfigByHostname = Map.copyOf(Objects.requireNonNull(ipConfigByHostname)); + this.hostId = Objects.requireNonNull(hostId); } public Map<String, IP.Config> asMap() { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java index bc10a97068e..e6a064c7bf5 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java @@ -104,7 +104,7 @@ public class MockHostProvisioner implements HostProvisioner { result.put(host.hostname(), createIpConfig(host)); host.ipConfig().pool().hostnames().forEach(hostname -> result.put(hostname.value(), IP.Config.ofEmptyPool(nameResolver.resolveAll(hostname.value())))); - return new HostIpConfig(result); + return new HostIpConfig(result, Optional.empty()); } @Override |