mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-07 06:19:43 -10:00
refactor(runtime): import inline fully qualified names in runtime modules (#16504)
The runtime provisioner, transport and host modules spelled 80 type references as inline fully qualified names. They now use imports. The conversion only touches code (never strings or comments) and leaves a name qualified whenever importing it could change what any name in the file resolves to: an existing or same-package type with that simple name, a declared or nested type, java.lang, a bare identifier already in use, or a wildcard import. The compiled bytecode is unchanged: javap -c -p of all 49 classes in the seven modules is identical before and after, ignoring constant-pool indices. Co-authored-by: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
a84493d628
commit
2258518d46
15 files changed
+119
-74
No files matched your search
+2
-1
@@ -13,6 +13,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -118,7 +119,7 @@ public final class ExternalRuntimeProviderFactory implements RuntimeProviderFact
|
||||
BrokerValues.requireId(runtimeBroker.getWorkspaceId(), "External Runtime workspace ID");
|
||||
String cwd = runtimeBroker.getWorkspaceCwd();
|
||||
if (cwd == null || !cwd.startsWith("/")
|
||||
|| java.util.Arrays.stream(cwd.substring(1).split("/", -1))
|
||||
|| Arrays.stream(cwd.substring(1).split("/", -1))
|
||||
.anyMatch(part -> part.isEmpty() || part.equals(".") || part.equals(".."))) {
|
||||
throw new IllegalStateException("External Runtime workspace cwd must be an absolute normalized"
|
||||
+ " worker path other than the filesystem root");
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ package com.alibaba.qwen.code.runtimebroker.host;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.Instant;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -43,7 +44,7 @@ public final class MacOsHostIdentity {
|
||||
throw new IOException("macOS storage birth time is unavailable");
|
||||
}
|
||||
return birth.toString();
|
||||
} catch (NumberFormatException | java.time.DateTimeException error) {
|
||||
} catch (NumberFormatException | DateTimeException error) {
|
||||
throw new IOException("macOS storage birth time is invalid", error);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.PosixFileAttributes;
|
||||
import java.nio.file.attribute.PosixFilePermissions;
|
||||
import java.nio.file.attribute.UserPrincipal;
|
||||
|
||||
@@ -33,7 +34,7 @@ public final class RuntimeStateFiles {
|
||||
}
|
||||
|
||||
public static void validate(Path path, boolean isDirectory, UserPrincipal owner) throws IOException {
|
||||
var attributes = Files.readAttributes(path, java.nio.file.attribute.PosixFileAttributes.class,
|
||||
var attributes = Files.readAttributes(path, PosixFileAttributes.class,
|
||||
LinkOption.NOFOLLOW_LINKS);
|
||||
if (isDirectory ? !attributes.isDirectory() : !attributes.isRegularFile()) {
|
||||
throw new IOException("Recovery entry has an invalid type");
|
||||
|
||||
+4
-2
@@ -1,5 +1,6 @@
|
||||
package com.alibaba.qwen.code.runtimebroker.host;
|
||||
|
||||
import com.alibaba.qwen.code.managedagent.contracts.workspace.LocalWorkspaceFiles;
|
||||
import com.alibaba.qwen.code.runtimebroker.BrokerValues;
|
||||
import com.alibaba.qwen.code.runtimebroker.JsonCodec;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBrokerException;
|
||||
@@ -11,11 +12,12 @@ import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** Bounded Workspace file exchanges using the configured local CLI. */
|
||||
public final class WorkspaceFileProcess implements com.alibaba.qwen.code.managedagent.contracts.workspace.LocalWorkspaceFiles {
|
||||
public final class WorkspaceFileProcess implements LocalWorkspaceFiles {
|
||||
public static final int MAX_UPLOAD_BYTES = 8 * 1024 * 1024;
|
||||
public static final int MAX_UPLOAD_REQUEST_BYTES = 12 * 1024 * 1024;
|
||||
private static volatile Capability cachedCapability;
|
||||
@@ -87,7 +89,7 @@ public final class WorkspaceFileProcess implements com.alibaba.qwen.code.managed
|
||||
|
||||
private static List<FileIdentity> identity(String node, String entry) {
|
||||
try {
|
||||
var identities = new java.util.ArrayList<FileIdentity>(2);
|
||||
var identities = new ArrayList<FileIdentity>(2);
|
||||
for (String configured : List.of(node, entry)) {
|
||||
Path path = Path.of(configured);
|
||||
if (!path.isAbsolute()) {
|
||||
|
||||
+19
-12
@@ -7,6 +7,7 @@ import com.alibaba.qwen.code.runtimebroker.BrokerValues;
|
||||
import com.alibaba.qwen.code.runtimebroker.CsiFilesRetirementProfile;
|
||||
import com.alibaba.qwen.code.runtimebroker.HarnessOwnership;
|
||||
import com.alibaba.qwen.code.runtimebroker.JsonCodec;
|
||||
import com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile;
|
||||
import com.alibaba.qwen.code.runtimebroker.ResidentWorkspaceProfile;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeAttestation;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBindingRecord;
|
||||
@@ -19,6 +20,7 @@ import com.alibaba.qwen.code.runtimebroker.RuntimeScope;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeSession;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeSessionRecord;
|
||||
import com.alibaba.qwen.code.runtimebroker.WorkspaceExecutionProfile;
|
||||
import com.alibaba.qwen.code.runtimebroker.WorkspacePhysicalTransport;
|
||||
import com.alibaba.qwen.code.runtimebroker.managedworkspace.ContextBinding;
|
||||
import com.alibaba.qwen.code.runtimebroker.protocol.ManagedContextProtocol;
|
||||
import com.alibaba.qwen.code.runtimebroker.protocol.ProviderRuntimeProtocol;
|
||||
@@ -35,6 +37,7 @@ import com.alibaba.qwen.code.runtimebroker.transport.ManagedMonitorProtocol;
|
||||
import com.alibaba.qwen.code.runtimebroker.transport.ManagedShellProtocol;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
@@ -42,11 +45,15 @@ import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
@@ -64,7 +71,7 @@ import java.util.function.Function;
|
||||
* their separate Session control protocol. MCP controls have their own
|
||||
* bounded envelope.
|
||||
*/
|
||||
public final class HttpRuntimeTransport implements com.alibaba.qwen.code.runtimebroker.WorkspacePhysicalTransport {
|
||||
public final class HttpRuntimeTransport implements WorkspacePhysicalTransport {
|
||||
static final int BODY_LIMIT_BYTES = 16 * 1024;
|
||||
static final int TOOL_REQUEST_LIMIT_BYTES = 256 * 1024;
|
||||
static final int TOOL_RESULT_LIMIT_BYTES = 1024 * 1024;
|
||||
@@ -120,7 +127,7 @@ public final class HttpRuntimeTransport implements com.alibaba.qwen.code.runtime
|
||||
private String managedExtensionCgroupRoot;
|
||||
|
||||
public HttpRuntimeTransport withManagedExtensionCacheDirectory(String directory, String cgroupRoot) {
|
||||
if (directory == null || !java.nio.file.Path.of(directory).isAbsolute()) {
|
||||
if (directory == null || !Path.of(directory).isAbsolute()) {
|
||||
throw new IllegalArgumentException("Extension cache must be absolute");
|
||||
}
|
||||
this.managedExtensionCacheDirectory = directory;
|
||||
@@ -131,13 +138,13 @@ public final class HttpRuntimeTransport implements com.alibaba.qwen.code.runtime
|
||||
private Map<String, Object> contextBoot(RuntimeProvisionRequest request, RuntimeProvisionSeed seed) {
|
||||
String digest = request.getScope().getCapabilityDigest();
|
||||
return ManagedContextProtocol.boot(request, seed,
|
||||
com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile.admits(digest)
|
||||
? com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile.configuration(digest,
|
||||
ManagedExtensionExecutionProfile.admits(digest)
|
||||
? ManagedExtensionExecutionProfile.configuration(digest,
|
||||
managedExtensionCacheDirectory, managedExtensionCgroupRoot) : null);
|
||||
}
|
||||
|
||||
public void configureExtensionPreparation(ExtensionPreparation preparation) {
|
||||
this.extensionPreparation = java.util.Objects.requireNonNull(preparation, "preparation");
|
||||
this.extensionPreparation = Objects.requireNonNull(preparation, "preparation");
|
||||
}
|
||||
|
||||
public CompletionStage<Map<String, Object>> extensionControl(RuntimeBindingRecord runtime, String harnessSessionId,
|
||||
@@ -206,7 +213,7 @@ public final class HttpRuntimeTransport implements com.alibaba.qwen.code.runtime
|
||||
}
|
||||
this.client = client;
|
||||
this.requestTimeout = requestTimeout;
|
||||
this.endpointResolver = java.util.Objects.requireNonNull(endpointResolver, "endpointResolver");
|
||||
this.endpointResolver = Objects.requireNonNull(endpointResolver, "endpointResolver");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -472,7 +479,7 @@ public final class HttpRuntimeTransport implements com.alibaba.qwen.code.runtime
|
||||
|| !runtime.getBindingId().equals(sessionRecord.getBindingId())
|
||||
|| runtime.getGeneration() != sessionRecord.getRuntimeGeneration()
|
||||
|| !request.getScope().equals(session.getScope())
|
||||
|| !java.util.Objects.equals(request.getIsolationKey(),
|
||||
|| !Objects.equals(request.getIsolationKey(),
|
||||
isolationKey)) {
|
||||
throw new IllegalArgumentException(
|
||||
"session must belong to a READY Runtime binding");
|
||||
@@ -941,7 +948,7 @@ public final class HttpRuntimeTransport implements com.alibaba.qwen.code.runtime
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionStage<java.util.List<Map<String, Object>>> mcpDefinitions(RuntimeBindingRecord runtime) {
|
||||
public CompletionStage<List<Map<String, Object>>> mcpDefinitions(RuntimeBindingRecord runtime) {
|
||||
var scope = runtime.getRequest().getScope();
|
||||
byte[] request = encodeToolRequest(Map.of("protocolVersion", 1,
|
||||
"tenantId", scope.getTenantId(), "workspaceId", scope.getWorkspaceId()), TOOL_REQUEST_LIMIT_BYTES);
|
||||
@@ -950,19 +957,19 @@ public final class HttpRuntimeTransport implements com.alibaba.qwen.code.runtime
|
||||
}
|
||||
|
||||
public CompletionStage<Map<String, Object>> installExtensionPackage(RuntimeBindingRecord runtime,
|
||||
String digest, java.nio.file.Path archive) {
|
||||
String digest, Path archive) {
|
||||
if (runtime == null || runtime.getLease() == null || digest == null || !digest.matches("[a-f0-9]{64}")) {
|
||||
throw new IllegalArgumentException("An original Runtime and extension archive digest are required");
|
||||
}
|
||||
HttpRequest.BodyPublisher body;
|
||||
try {
|
||||
long length = java.nio.file.Files.size(archive);
|
||||
long length = Files.size(archive);
|
||||
if (length < 1 || length > 100L * 1024 * 1024
|
||||
|| !java.nio.file.Files.isRegularFile(archive, java.nio.file.LinkOption.NOFOLLOW_LINKS)) {
|
||||
|| !Files.isRegularFile(archive, LinkOption.NOFOLLOW_LINKS)) {
|
||||
throw new IllegalArgumentException("Extension archive exceeds its limit");
|
||||
}
|
||||
body = HttpRequest.BodyPublishers.ofFile(archive);
|
||||
} catch (java.io.IOException error) {
|
||||
} catch (IOException error) {
|
||||
return CompletableFuture.failedFuture(unavailable(error));
|
||||
}
|
||||
RuntimeLease lease = runtime.getLease();
|
||||
|
||||
+5
-3
@@ -2,6 +2,7 @@ package com.alibaba.qwen.code.runtimebroker.provisioning.kubernetes;
|
||||
|
||||
import com.alibaba.qwen.code.runtimebroker.BrokerValues;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBrokerException;
|
||||
import com.alibaba.qwen.code.runtimebroker.protocol.KubernetesNames;
|
||||
import com.alibaba.qwen.code.runtimebroker.spi.KubernetesRuntimeClient;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
@@ -10,6 +11,7 @@ import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
@@ -22,8 +24,8 @@ public final class KubernetesCsiLogReader {
|
||||
public record Source(String podName, String podUid, String nodeName, String nodeUid,
|
||||
String daemonSetUid, String containerId, String imageId) {
|
||||
public Source {
|
||||
com.alibaba.qwen.code.runtimebroker.protocol.KubernetesNames.dnsSubdomain(podName);
|
||||
com.alibaba.qwen.code.runtimebroker.protocol.KubernetesNames.dnsSubdomain(nodeName);
|
||||
KubernetesNames.dnsSubdomain(podName);
|
||||
KubernetesNames.dnsSubdomain(nodeName);
|
||||
if (!podName.startsWith("csi-plugin-") || !uuid(podUid) || !uuid(nodeUid) || !uuid(daemonSetUid)
|
||||
|| containerId == null || !containerId.matches("containerd://[0-9a-f]{64}")
|
||||
|| imageId == null || imageId.length() > 512 || !imageId.matches("[^\\s]*sha256:[0-9a-f]{64}")) {
|
||||
@@ -122,7 +124,7 @@ public final class KubernetesCsiLogReader {
|
||||
&& source.imageId().equals(container.get("imageID"))
|
||||
&& Long.valueOf(0).equals(BrokerValues.exactLong(container.get("restartCount")))
|
||||
&& Boolean.TRUE.equals(container.get("ready"))
|
||||
&& map(container.get("state")).keySet().equals(java.util.Set.of("running")));
|
||||
&& map(container.get("state")).keySet().equals(Set.of("running")));
|
||||
var ready = list(map(node.join().get("status")).get("conditions")).stream()
|
||||
.map(KubernetesCsiLogReader::map).filter(value -> "Ready".equals(value.get("type"))).toList();
|
||||
require(ready.size() == 1 && "True".equals(ready.getFirst().get("status")));
|
||||
|
||||
+23
-15
@@ -1,10 +1,16 @@
|
||||
package com.alibaba.qwen.code.runtimebroker.provisioning.kubernetes;
|
||||
|
||||
import com.alibaba.qwen.code.managedagent.contracts.persistence.WorkspaceCsiRegistration;
|
||||
import com.alibaba.qwen.code.managedagent.contracts.runtime.ProtectionIdentity;
|
||||
import com.alibaba.qwen.code.managedagent.contracts.workspace.ResidentReclamation;
|
||||
import com.alibaba.qwen.code.managedagent.settings.ManagedAgentSettings;
|
||||
import com.alibaba.qwen.code.runtimebroker.BrokerValues;
|
||||
import com.alibaba.qwen.code.runtimebroker.JsonCodec;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBindingRecord;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBrokerException;
|
||||
import com.alibaba.qwen.code.runtimebroker.WorkspaceCsiRuntimeIdentity;
|
||||
import com.alibaba.qwen.code.runtimebroker.adapter.HttpRuntimeTransport;
|
||||
import com.alibaba.qwen.code.runtimebroker.spi.KubernetesMaintenanceClient;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
@@ -24,17 +30,19 @@ import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/** Bounded core-v1 API calls with rotating service-account tokens and explicit CA trust. */
|
||||
public final class KubernetesHttpRuntimeClient implements com.alibaba.qwen.code.runtimebroker.spi.KubernetesMaintenanceClient {
|
||||
public final class KubernetesHttpRuntimeClient implements KubernetesMaintenanceClient {
|
||||
private static final int RESPONSE_LIMIT = 1024 * 1024;
|
||||
private static final int CONFIG_MAP_RESPONSE_LIMIT = RESPONSE_LIMIT + 64 * 1024;
|
||||
private static final int DELETE_REQUEST_LIMIT = 16 * 1024;
|
||||
@@ -263,7 +271,7 @@ public final class KubernetesHttpRuntimeClient implements com.alibaba.qwen.code.
|
||||
});
|
||||
return result.exceptionallyCompose(error -> {
|
||||
Throwable cause = error;
|
||||
while (cause instanceof java.util.concurrent.CompletionException && cause.getCause() != null) {
|
||||
while (cause instanceof CompletionException && cause.getCause() != null) {
|
||||
cause = cause.getCause();
|
||||
}
|
||||
return CompletableFuture.failedFuture(cause instanceof RuntimeBrokerException ? cause : failure(503, true));
|
||||
@@ -333,20 +341,20 @@ public final class KubernetesHttpRuntimeClient implements com.alibaba.qwen.code.
|
||||
return new RuntimeBrokerException(status >= 400 && status <= 599 ? status : 502,
|
||||
"runtime_kubernetes_api_failed", "Kubernetes API request failed.", retryable);
|
||||
}
|
||||
public java.util.concurrent.CompletionStage<Void> verifyProtection(
|
||||
com.alibaba.qwen.code.managedagent.contracts.persistence.WorkspaceCsiRegistration registration,
|
||||
com.alibaba.qwen.code.managedagent.contracts.runtime.ProtectionIdentity protection) {
|
||||
return new com.alibaba.qwen.code.runtimebroker.provisioning.kubernetes.WorkspaceCsiResourceGuard(
|
||||
public CompletionStage<Void> verifyProtection(
|
||||
WorkspaceCsiRegistration registration,
|
||||
ProtectionIdentity protection) {
|
||||
return new WorkspaceCsiResourceGuard(
|
||||
this, registration.clusterDomain(), registration, protection).verify().thenApply(receipt -> null);
|
||||
}
|
||||
|
||||
public com.alibaba.qwen.code.managedagent.contracts.workspace.ResidentReclamation.Baseline reclamationBaseline(
|
||||
com.alibaba.qwen.code.runtimebroker.RuntimeBindingRecord original,
|
||||
com.alibaba.qwen.code.managedagent.settings.ManagedAgentSettings.RuntimeBroker.ResidentWorkspace selected,
|
||||
String finalizer, java.time.Instant now) { return com.alibaba.qwen.code.runtimebroker.provisioning.kubernetes.ResidentWorkspaceReclamation.prepare(original, selected, finalizer, this, now); }
|
||||
public com.alibaba.qwen.code.managedagent.contracts.workspace.ResidentReclamation.Receipt reclamationReceipt(
|
||||
com.alibaba.qwen.code.runtimebroker.RuntimeBindingRecord original,
|
||||
com.alibaba.qwen.code.managedagent.settings.ManagedAgentSettings.RuntimeBroker.ResidentWorkspace selected,
|
||||
com.alibaba.qwen.code.managedagent.contracts.workspace.ResidentReclamation.Baseline baseline,
|
||||
Map<String, Object> pod, java.time.Instant now) { return com.alibaba.qwen.code.runtimebroker.provisioning.kubernetes.ResidentWorkspaceReclamation.complete(original, selected, baseline, pod, this, now); }
|
||||
public ResidentReclamation.Baseline reclamationBaseline(
|
||||
RuntimeBindingRecord original,
|
||||
ManagedAgentSettings.RuntimeBroker.ResidentWorkspace selected,
|
||||
String finalizer, Instant now) { return ResidentWorkspaceReclamation.prepare(original, selected, finalizer, this, now); }
|
||||
public ResidentReclamation.Receipt reclamationReceipt(
|
||||
RuntimeBindingRecord original,
|
||||
ManagedAgentSettings.RuntimeBroker.ResidentWorkspace selected,
|
||||
ResidentReclamation.Baseline baseline,
|
||||
Map<String, Object> pod, Instant now) { return ResidentWorkspaceReclamation.complete(original, selected, baseline, pod, this, now); }
|
||||
}
|
||||
+5
-2
@@ -12,11 +12,14 @@ import com.alibaba.qwen.code.runtimebroker.RuntimeProvisioner;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeResourceHandle;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeScope;
|
||||
import com.alibaba.qwen.code.runtimebroker.adapter.HttpRuntimeTransport;
|
||||
import com.alibaba.qwen.code.runtimebroker.protocol.KubernetesNames;
|
||||
import com.alibaba.qwen.code.runtimebroker.spi.KubernetesRuntimeClient;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -65,7 +68,7 @@ public final class KubernetesRuntimeProvisioner implements RuntimeProvisioner {
|
||||
|| startupTimeout == null || startupTimeout.isNegative() || startupTimeout.isZero()) {
|
||||
throw new IllegalArgumentException("Client, pinned image, worker command and positive timeout are required");
|
||||
}
|
||||
com.alibaba.qwen.code.runtimebroker.protocol.KubernetesNames.dnsLabel(namespace);
|
||||
KubernetesNames.dnsLabel(namespace);
|
||||
this.client = client;
|
||||
this.cluster = BrokerValues.requireId(cluster, "cluster");
|
||||
this.namespace = namespace;
|
||||
@@ -589,7 +592,7 @@ public final class KubernetesRuntimeProvisioner implements RuntimeProvisioner {
|
||||
throw conflict();
|
||||
}
|
||||
return new URI("http", null, address.getHostAddress(), 43190, "/", null, null);
|
||||
} catch (java.io.IOException | java.net.URISyntaxException error) {
|
||||
} catch (IOException | URISyntaxException error) {
|
||||
throw conflict();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -2,6 +2,7 @@ package com.alibaba.qwen.code.runtimebroker.provisioning.kubernetes;
|
||||
|
||||
import com.alibaba.qwen.code.managedagent.contracts.workspace.ResidentWorkspaceCatalog;
|
||||
import com.alibaba.qwen.code.managedagent.repository.WorkspaceCsiReservations;
|
||||
import com.alibaba.qwen.code.managedagent.repository.WorkspaceExecutionStore;
|
||||
import com.alibaba.qwen.code.managedagent.settings.ManagedAgentSettings;
|
||||
import com.alibaba.qwen.code.managedagent.settings.ManagedAgentSettings.RuntimeBroker.ResidentWorkspace;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBindingRecord;
|
||||
@@ -19,6 +20,7 @@ import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
|
||||
public final class ResidentWorkspaceProvisioner implements RuntimeProvisioner {
|
||||
@@ -63,7 +65,7 @@ public final class ResidentWorkspaceProvisioner implements RuntimeProvisioner {
|
||||
var mapping = residents.require(request.getScope());
|
||||
if (request.getIsolationKey() != null || !mapping.registration().storageId().equals(request.getStorageId())
|
||||
|| !kind().equals(request.getProvisionerKind())) {
|
||||
throw com.alibaba.qwen.code.managedagent.repository.WorkspaceExecutionStore.unavailable();
|
||||
throw WorkspaceExecutionStore.unavailable();
|
||||
}
|
||||
return providers.get(mapping);
|
||||
}
|
||||
@@ -75,7 +77,7 @@ public final class ResidentWorkspaceProvisioner implements RuntimeProvisioner {
|
||||
public RuntimeProvisionRequest createRequest(RuntimeScope scope, String isolationKey) {
|
||||
var mapping = residents.require(scope);
|
||||
if (isolationKey != null) {
|
||||
throw com.alibaba.qwen.code.managedagent.repository.WorkspaceExecutionStore.unavailable();
|
||||
throw WorkspaceExecutionStore.unavailable();
|
||||
}
|
||||
return new RuntimeProvisionRequest(scope, null, kind(), mapping.registration().storageId());
|
||||
}
|
||||
@@ -112,7 +114,7 @@ public final class ResidentWorkspaceProvisioner implements RuntimeProvisioner {
|
||||
|
||||
@Override
|
||||
public CompletionStage<Void> release(RuntimeProvisionRequest request, RuntimeLease lease) {
|
||||
return java.util.concurrent.CompletableFuture.failedFuture(com.alibaba.qwen.code.managedagent.repository.WorkspaceExecutionStore.unavailable());
|
||||
return CompletableFuture.failedFuture(WorkspaceExecutionStore.unavailable());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+13
-8
@@ -1,8 +1,11 @@
|
||||
package com.alibaba.qwen.code.runtimebroker.provisioning.kubernetes;
|
||||
|
||||
import com.alibaba.qwen.code.managedagent.contracts.persistence.WorkspaceCsiRegistration;
|
||||
import com.alibaba.qwen.code.managedagent.contracts.runtime.Receipt;
|
||||
import com.alibaba.qwen.code.managedagent.contracts.runtime.WorkerArtifact;
|
||||
import com.alibaba.qwen.code.managedagent.repository.WorkspaceCsiReservations;
|
||||
import com.alibaba.qwen.code.runtimebroker.CsiOwnershipRevision;
|
||||
import com.alibaba.qwen.code.runtimebroker.ResidentWorkspaceProfile;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBindingRecord;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBindingRepository;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBrokerException;
|
||||
@@ -14,6 +17,7 @@ import com.alibaba.qwen.code.runtimebroker.RuntimeProvisioner;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeResourceHandle;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeScope;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeTransport;
|
||||
import com.alibaba.qwen.code.runtimebroker.StoreFailureException;
|
||||
import com.alibaba.qwen.code.runtimebroker.WorkspaceCsiRuntimeIdentity;
|
||||
import com.alibaba.qwen.code.runtimebroker.adapter.HttpRuntimeTransport;
|
||||
import com.alibaba.qwen.code.runtimebroker.spi.KubernetesRuntimeClient;
|
||||
@@ -27,6 +31,7 @@ import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
@@ -256,7 +261,7 @@ public final class WorkspaceCsiRuntimeProvisioner implements RuntimeProvisioner
|
||||
} catch (RuntimeException error) {
|
||||
forgetPlacement(request, seed, handle);
|
||||
return error instanceof RuntimeBrokerException failure && failure.isRetryable()
|
||||
|| error instanceof com.alibaba.qwen.code.runtimebroker.StoreFailureException
|
||||
|| error instanceof StoreFailureException
|
||||
? RuntimeObservation.unknown(handle) : RuntimeObservation.conflict(handle);
|
||||
}
|
||||
});
|
||||
@@ -317,9 +322,9 @@ public final class WorkspaceCsiRuntimeProvisioner implements RuntimeProvisioner
|
||||
RuntimeBindingRecord.State.RECOVERY_BLOCKED).contains(original.getState())
|
||||
&& (fresh && original.getResourceHandle() == null || handle.equals(original.getResourceHandle())));
|
||||
var expectedStorage = storageTuple(reserved);
|
||||
require(com.alibaba.qwen.code.runtimebroker.ResidentWorkspaceProfile.selects(request.getScope())
|
||||
? com.alibaba.qwen.code.runtimebroker.CsiOwnershipRevision.residentReserved(reserved.revision())
|
||||
: com.alibaba.qwen.code.runtimebroker.CsiOwnershipRevision.reserved(reserved.revision()));
|
||||
require(ResidentWorkspaceProfile.selects(request.getScope())
|
||||
? CsiOwnershipRevision.residentReserved(reserved.revision())
|
||||
: CsiOwnershipRevision.reserved(reserved.revision()));
|
||||
require(same(expectedStorage, value.get("storage")));
|
||||
checkObservation(request, seed, handle);
|
||||
var receipt = attest(request, seed, placement, WorkspaceCsiRuntimeIdentity.boot(request, seed, handle));
|
||||
@@ -434,7 +439,7 @@ public final class WorkspaceCsiRuntimeProvisioner implements RuntimeProvisioner
|
||||
&& ((Number) current.get("restartCount")).doubleValue() == 0
|
||||
&& !map(current.get("state")).containsKey("terminated"));
|
||||
return "Running".equals(status.get("phase")) && Boolean.TRUE.equals(current.get("ready"))
|
||||
&& map(current.get("state")).keySet().equals(java.util.Set.of("running")) ? current : null;
|
||||
&& map(current.get("state")).keySet().equals(Set.of("running")) ? current : null;
|
||||
}
|
||||
|
||||
private Map<String, Object> secret(RuntimeProvisionSeed seed, Map<String, Object> boot) {
|
||||
@@ -457,7 +462,7 @@ public final class WorkspaceCsiRuntimeProvisioner implements RuntimeProvisioner
|
||||
var sources = new ArrayList<Map<String, Object>>();
|
||||
for (int index = 0; index < artifacts.size(); index++) {
|
||||
sources.add(Map.of("configMap", Map.of("name", artifacts.get(index).configMapName(),
|
||||
"items", List.of(Map.of("key", "chunk", "path", String.format(java.util.Locale.ROOT, "%03d", index))))));
|
||||
"items", List.of(Map.of("key", "chunk", "path", String.format(Locale.ROOT, "%03d", index))))));
|
||||
}
|
||||
volumes.add(Map.of("name", "worker", "projected", Map.of("defaultMode", 292, "sources", sources)));
|
||||
}
|
||||
@@ -496,7 +501,7 @@ public final class WorkspaceCsiRuntimeProvisioner implements RuntimeProvisioner
|
||||
"metadata", Map.of("name", artifact.configMapName(), "namespace", registration.namespace())), artifact.uid());
|
||||
require(object.get("data") == null || map(object.get("data")).isEmpty());
|
||||
var data = map(object.get("binaryData"));
|
||||
require(data.keySet().equals(java.util.Set.of("chunk")));
|
||||
require(data.keySet().equals(Set.of("chunk")));
|
||||
byte[] chunk = Base64.getDecoder().decode(text(data, "chunk", 1024 * 1024));
|
||||
require(chunk.length > 0 && artifact.sha256().equals(rawDigest(chunk)));
|
||||
}
|
||||
@@ -526,7 +531,7 @@ public final class WorkspaceCsiRuntimeProvisioner implements RuntimeProvisioner
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, Object> protection(com.alibaba.qwen.code.managedagent.contracts.runtime.Receipt receipt) {
|
||||
private Map<String, Object> protection(Receipt receipt) {
|
||||
require(registration.physicalKey().equals(receipt.physicalKey()) && registration.revision() == receipt.registrationRevision());
|
||||
var pin = receipt.protection();
|
||||
return Map.of("namespaceUid", pin.namespaceUid(), "policyName", pin.policyName(), "policyUid", pin.policyUid(),
|
||||
|
||||
+4
-3
@@ -5,6 +5,7 @@ import com.alibaba.qwen.code.runtimebroker.BrokerValues;
|
||||
import com.alibaba.qwen.code.runtimebroker.CsiFilesRetirementProfile;
|
||||
import com.alibaba.qwen.code.runtimebroker.HarnessOwnership;
|
||||
import com.alibaba.qwen.code.runtimebroker.JsonCodec;
|
||||
import com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBindingRecord;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBrokerException;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeDrainReceipt;
|
||||
@@ -399,8 +400,8 @@ public final class LocalProcessRuntimeProvisioner
|
||||
if (!originalBootStopped && !neverStarted && worker == null && !registration.processAbsent()) {
|
||||
throw LocalRuntimeStore.blocked();
|
||||
}
|
||||
boolean extended = com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile.admits(binding.getRequest().getScope().getCapabilityDigest());
|
||||
String mode = extended ? com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile.mode(binding.getRequest().getScope().getCapabilityDigest()) : null;
|
||||
boolean extended = ManagedExtensionExecutionProfile.admits(binding.getRequest().getScope().getCapabilityDigest());
|
||||
String mode = extended ? ManagedExtensionExecutionProfile.mode(binding.getRequest().getScope().getCapabilityDigest()) : null;
|
||||
String proofScope = extended ? ("linux-cgroup".equals(mode) ? "process_tree" : "process_group") : null;
|
||||
if (extended && !neverStarted && !originalBootStopped) {
|
||||
if (binding.getLease() == null || worker == null) {
|
||||
@@ -673,7 +674,7 @@ public final class LocalProcessRuntimeProvisioner
|
||||
boot.put("workspaceGeneration", scope.getWorkspaceGeneration());
|
||||
boot.put("workspaceId", scope.getWorkspaceId());
|
||||
Map<String, Object> document = request.isManagedContext()
|
||||
? ManagedContextProtocol.boot(request, seed, com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile.admits(scope.getCapabilityDigest()) ? com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile.configuration(scope.getCapabilityDigest(), managedExtensionCacheDirectory, managedExtensionCgroupRoot) : null) : boot;
|
||||
? ManagedContextProtocol.boot(request, seed, ManagedExtensionExecutionProfile.admits(scope.getCapabilityDigest()) ? ManagedExtensionExecutionProfile.configuration(scope.getCapabilityDigest(), managedExtensionCacheDirectory, managedExtensionCgroupRoot) : null) : boot;
|
||||
byte[] encoded = JsonCodec.encode(document);
|
||||
if (encoded.length > READY_RECORD_LIMIT) {
|
||||
throw new IllegalArgumentException("Managed Runtime boot exceeds 32 KiB.");
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@ import com.alibaba.qwen.code.managedagent.settings.ManagedAgentSettings;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeProvisioner;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeTransport;
|
||||
import com.alibaba.qwen.code.runtimebroker.adapter.HttpRuntimeTransport;
|
||||
import com.alibaba.qwen.code.runtimebroker.host.RuntimeStateFiles;
|
||||
import com.alibaba.qwen.code.runtimebroker.spi.OperatorRuntimeRecovery;
|
||||
import com.alibaba.qwen.code.runtimebroker.spi.RuntimeProviderDependencies;
|
||||
import com.alibaba.qwen.code.runtimebroker.spi.RuntimeProviderFactory;
|
||||
@@ -73,7 +74,7 @@ public final class LocalRuntimeProviderFactory implements RuntimeProviderFactory
|
||||
}
|
||||
Path stateDirectory = Path.of(settings.getStateDirectory()).toAbsolutePath().normalize();
|
||||
try {
|
||||
com.alibaba.qwen.code.runtimebroker.host.RuntimeStateFiles.validateDirectory(stateDirectory);
|
||||
RuntimeStateFiles.validateDirectory(stateDirectory);
|
||||
} catch (IOException error) {
|
||||
throw new IllegalStateException("Original Runtime state directory is unavailable", error);
|
||||
}
|
||||
@@ -111,7 +112,7 @@ public final class LocalRuntimeProviderFactory implements RuntimeProviderFactory
|
||||
private static void requireRecoveryDirectoryOutsideWorkspaces(ManagedAgentSettings.RuntimeBroker broker,
|
||||
Path directory) {
|
||||
try {
|
||||
Path candidate = java.nio.file.Files.exists(directory) ? directory.toRealPath()
|
||||
Path candidate = Files.exists(directory) ? directory.toRealPath()
|
||||
: directory.getParent().toRealPath().resolve(directory.getFileName());
|
||||
if (candidate.startsWith(Path.of(broker.getWorkspaceCwd()).toRealPath())) {
|
||||
throw new IllegalStateException(recoveryDirectoryOutsideRootsMessage());
|
||||
|
||||
+14
-9
@@ -9,6 +9,7 @@ import com.alibaba.qwen.code.runtimebroker.RuntimeResourceHandle;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeScope;
|
||||
import com.alibaba.qwen.code.runtimebroker.host.MacOsHostIdentity;
|
||||
import com.alibaba.qwen.code.runtimebroker.host.RuntimeStateFiles;
|
||||
import com.alibaba.qwen.code.runtimebroker.protocol.RuntimeProviderKinds;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -17,19 +18,23 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.nio.file.attribute.PosixFilePermissions;
|
||||
import java.nio.file.attribute.UserPrincipal;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@@ -156,7 +161,7 @@ final class LocalRuntimeStore {
|
||||
}
|
||||
char state = text.substring(text.lastIndexOf(')') + 1).strip().charAt(0);
|
||||
return state == 'Z' || state == 'X' || state == 'x';
|
||||
} catch (java.nio.file.NoSuchFileException absent) {
|
||||
} catch (NoSuchFileException absent) {
|
||||
return true;
|
||||
} catch (IOException | IllegalArgumentException uncertain) {
|
||||
return false;
|
||||
@@ -200,7 +205,7 @@ final class LocalRuntimeStore {
|
||||
Files.createDirectory(this.directory, PosixFilePermissions.asFileAttribute(
|
||||
PosixFilePermissions.fromString("rwx------")));
|
||||
syncDirectory(this.directory.getParent());
|
||||
} catch (java.nio.file.FileAlreadyExistsException ignored) {
|
||||
} catch (FileAlreadyExistsException ignored) {
|
||||
// A second Broker initialized the directory; validate it below.
|
||||
}
|
||||
}
|
||||
@@ -215,7 +220,7 @@ final class LocalRuntimeStore {
|
||||
}
|
||||
|
||||
static boolean supported(RuntimeResourceHandle handle) {
|
||||
return handle != null && com.alibaba.qwen.code.runtimebroker.protocol.RuntimeProviderKinds.LOCAL_PROCESS.equals(handle.getKind())
|
||||
return handle != null && RuntimeProviderKinds.LOCAL_PROCESS.equals(handle.getKind())
|
||||
&& handle.getVersion() == 2;
|
||||
}
|
||||
|
||||
@@ -240,7 +245,7 @@ final class LocalRuntimeStore {
|
||||
PosixFilePermissions.fromString("rw-------")));
|
||||
syncDirectory(directory);
|
||||
createdLock = true;
|
||||
} catch (java.nio.file.FileAlreadyExistsException ignored) {
|
||||
} catch (FileAlreadyExistsException ignored) {
|
||||
// Another Broker created the permanent lock inode.
|
||||
}
|
||||
}
|
||||
@@ -319,7 +324,7 @@ final class LocalRuntimeStore {
|
||||
byte[] bytes = readBounded(ready);
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
if (bytes[i] == '\n') {
|
||||
return java.util.Arrays.copyOf(bytes, i);
|
||||
return Arrays.copyOf(bytes, i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -332,11 +337,11 @@ final class LocalRuntimeStore {
|
||||
validate(record, false);
|
||||
try {
|
||||
Map<String, Object> value = JsonCodec.parseObject(readBounded(record), "local Runtime registration");
|
||||
if (!value.keySet().equals(java.util.Set.of("version", "handle", "state", "pid", "started", "endpoint"))
|
||||
if (!value.keySet().equals(Set.of("version", "handle", "state", "pid", "started", "endpoint"))
|
||||
|| !Objects.equals(value.get("version"), 1)) {
|
||||
throw blocked();
|
||||
}
|
||||
return new Registration(RuntimeResourceHandle.fromJson(com.alibaba.qwen.code.runtimebroker.protocol.RuntimeProviderKinds.LOCAL_PROCESS, 2,
|
||||
return new Registration(RuntimeResourceHandle.fromJson(RuntimeProviderKinds.LOCAL_PROCESS, 2,
|
||||
(String) value.get("handle")), State.valueOf((String) value.get("state")),
|
||||
((Number) value.get("pid")).longValue(),
|
||||
"".equals(value.get("started")) ? null : (String) value.get("started"),
|
||||
@@ -389,7 +394,7 @@ final class LocalRuntimeStore {
|
||||
if (bytes.position() > RECORD_LIMIT) {
|
||||
throw new IOException("Recovery record exceeds its size limit");
|
||||
}
|
||||
return java.util.Arrays.copyOf(bytes.array(), bytes.position());
|
||||
return Arrays.copyOf(bytes.array(), bytes.position());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,7 +412,7 @@ final class LocalRuntimeStore {
|
||||
scope.getTenantId(), scope.getWorkspaceId(), scope.getWorkspaceGeneration(), scope.getCanonicalCwd(),
|
||||
scope.getCapabilityDigest(), scope.getIsolationClass(), request.getProvisionerKind(),
|
||||
Objects.toString(request.getIsolationKey(), ""), Objects.toString(request.getStorageId(), "")))));
|
||||
return new RuntimeResourceHandle(com.alibaba.qwen.code.runtimebroker.protocol.RuntimeProviderKinds.LOCAL_PROCESS, 2, values);
|
||||
return new RuntimeResourceHandle(RuntimeProviderKinds.LOCAL_PROCESS, 2, values);
|
||||
}
|
||||
|
||||
private static String digest(byte[] bytes) {
|
||||
|
||||
+4
-2
@@ -7,6 +7,7 @@ import com.alibaba.qwen.code.runtimebroker.RuntimeLease;
|
||||
import com.alibaba.qwen.code.runtimebroker.host.HostCommandRunner;
|
||||
import com.alibaba.qwen.code.runtimebroker.host.HostCommandRunner.Result;
|
||||
import com.alibaba.qwen.code.runtimebroker.host.WorkspaceFileProcess;
|
||||
import com.alibaba.qwen.code.runtimebroker.spi.SshConnections;
|
||||
import com.alibaba.qwen.code.runtimebroker.spi.SshRuntimeNode;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -31,6 +32,7 @@ import java.nio.file.StandardOpenOption;
|
||||
import java.nio.file.attribute.PosixFilePermissions;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -40,7 +42,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/** Owns SSH control sockets and ephemeral forwarding addresses, never remote workers. */
|
||||
public final class SshConnectionManager implements com.alibaba.qwen.code.runtimebroker.spi.SshConnections {
|
||||
public final class SshConnectionManager implements SshConnections {
|
||||
private static final System.Logger LOG = System.getLogger(SshConnectionManager.class.getName());
|
||||
private static final int RECORD_LIMIT = 64 * 1024;
|
||||
private static final Duration COMMAND_TIMEOUT = Duration.ofSeconds(60);
|
||||
@@ -353,7 +355,7 @@ public final class SshConnectionManager implements com.alibaba.qwen.code.runtime
|
||||
throw conflict();
|
||||
}
|
||||
Map<URI, Forward> forwards = new ConcurrentHashMap<>();
|
||||
Set<URI> local = new java.util.HashSet<>();
|
||||
Set<URI> local = new HashSet<>();
|
||||
for (Object entry : entries) {
|
||||
if (!(entry instanceof Map<?, ?> fields) || fields.size() != 3
|
||||
|| !(fields.get("remote") instanceof String remote) || !(fields.get("local") instanceof String address)
|
||||
|
||||
+14
-10
@@ -1,6 +1,7 @@
|
||||
package com.alibaba.qwen.code.runtimebroker.provisioning.ssh;
|
||||
|
||||
import com.alibaba.qwen.code.runtimebroker.BrokerValues;
|
||||
import com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBindingRecord;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeBrokerException;
|
||||
import com.alibaba.qwen.code.runtimebroker.RuntimeDrainReceipt;
|
||||
@@ -20,11 +21,14 @@ import com.alibaba.qwen.code.runtimebroker.spi.SshRuntimeStorage;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
@@ -59,14 +63,14 @@ public final class SshRuntimeProvisioner implements RuntimeProvisioner {
|
||||
public SshRuntimeProvisioner(Function<String, SshRuntimeNode> nodes,
|
||||
Function<RuntimeScope, SshRuntimeStorage> storages, SshConnections connections,
|
||||
HttpRuntimeTransport transport) {
|
||||
this.nodes = java.util.Objects.requireNonNull(nodes, "nodes");
|
||||
this.storages = java.util.Objects.requireNonNull(storages, "storages");
|
||||
this.connections = java.util.Objects.requireNonNull(connections, "connections");
|
||||
this.transport = java.util.Objects.requireNonNull(transport, "transport");
|
||||
this.nodes = Objects.requireNonNull(nodes, "nodes");
|
||||
this.storages = Objects.requireNonNull(storages, "storages");
|
||||
this.connections = Objects.requireNonNull(connections, "connections");
|
||||
this.transport = Objects.requireNonNull(transport, "transport");
|
||||
}
|
||||
|
||||
public SshRuntimeProvisioner withManagedExtensionCacheDirectory(String directory, String cgroupRoot) {
|
||||
if (directory == null || !java.nio.file.Path.of(directory).isAbsolute()) {
|
||||
if (directory == null || !Path.of(directory).isAbsolute()) {
|
||||
throw new IllegalArgumentException("Extension cache must be absolute");
|
||||
}
|
||||
this.managedExtensionCacheDirectory = directory;
|
||||
@@ -217,13 +221,13 @@ public final class SshRuntimeProvisioner implements RuntimeProvisioner {
|
||||
throw stopUnconfirmed();
|
||||
}
|
||||
RuntimeProvisionSeed seed = binding.getProvisionSeed();
|
||||
boolean extended = com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile.admits(binding.getRequest().getScope().getCapabilityDigest());
|
||||
Set<String> proofFields = new java.util.HashSet<>(PROOF_FIELDS);
|
||||
boolean extended = ManagedExtensionExecutionProfile.admits(binding.getRequest().getScope().getCapabilityDigest());
|
||||
Set<String> proofFields = new HashSet<>(PROOF_FIELDS);
|
||||
if (extended) {
|
||||
proofFields.add("executionMode");
|
||||
proofFields.add("scope");
|
||||
}
|
||||
String mode = extended ? com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile.mode(binding.getRequest().getScope().getCapabilityDigest()) : null;
|
||||
String mode = extended ? ManagedExtensionExecutionProfile.mode(binding.getRequest().getScope().getCapabilityDigest()) : null;
|
||||
String proofScope = extended ? ("linux-cgroup".equals(mode) ? "process_tree" : "process_group") : null;
|
||||
if (!proof.keySet().equals(proofFields)
|
||||
|| !number(proof.get("version"), extended ? 2 : 1)
|
||||
@@ -275,8 +279,8 @@ public final class SshRuntimeProvisioner implements RuntimeProvisioner {
|
||||
private Map<String, Object> contextBoot(RuntimeProvisionRequest request, RuntimeProvisionSeed seed) {
|
||||
String digest = request.getScope().getCapabilityDigest();
|
||||
return ManagedContextProtocol.boot(request, seed,
|
||||
com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile.admits(digest)
|
||||
? com.alibaba.qwen.code.runtimebroker.ManagedExtensionExecutionProfile.configuration(digest,
|
||||
ManagedExtensionExecutionProfile.admits(digest)
|
||||
? ManagedExtensionExecutionProfile.configuration(digest,
|
||||
managedExtensionCacheDirectory, managedExtensionCgroupRoot) : null);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user