aboutsummaryrefslogtreecommitdiffstats
path: root/node-repository/src/main/java/com/yahoo/vespa/hosted/provision
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2023-07-06 17:37:08 +0200
committerjonmv <venstad@gmail.com>2023-07-06 17:37:08 +0200
commit49b755a8636f0f5a7c1ff3518f91bc1b278efc09 (patch)
treef4d293239087b373947ab63f95e4e1e817742e91 /node-repository/src/main/java/com/yahoo/vespa/hosted/provision
parent2411f3779211e182d155c88e674cbb274035b78a (diff)
Look up GCP hosts by GCP instance ID
Diffstat (limited to 'node-repository/src/main/java/com/yahoo/vespa/hosted/provision')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java58
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostResumeProvisioner.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostIpConfig.java10
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java2
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