diff --git a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/ExnConnector.java b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/ExnConnector.java index 745aa84..3b804df 100644 --- a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/ExnConnector.java +++ b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/ExnConnector.java @@ -403,27 +403,24 @@ public class ExnConnector { * } * } * - *

Each value for {@code nodeName} has to be unique, and should be - * either the name of the master node or the name of a node that will - * subsequently be referenced in the affinity trait of the modified + *

Each value for {@code nodeName} has to be globally unique, and + * should be either the name of the master node or the name of a node that + * will subsequently be referenced in the affinity trait of the modified * kubevela file (see {@link NebulousAppDeployer#addNodeAffinities()}). * *

The values for {@code nodeCandidateId} and {@code cloudId} come from * the return value of a call to {@link #findNodeCandidates()}. * - *

Note that this method could be rewritten to accept the nodes as a - * {@code List} instead, if that is - * more convenient. - * - * @param appID The application's id, used to name the cluster. + * @param appID The application's id, used only for logging. + * @param clusterName The cluster name. * @param masterNodeName The name of the master node. - * @param nodes A JSON array containing the node definitions. + * @param nodes A JSON array containing the node definitions, including the master node. * @return true if the cluster was successfully defined, false otherwise. */ - public boolean defineCluster(String appID, String masterNodeName, ArrayNode nodes) { + public boolean defineCluster(String appID, String clusterName, String masterNodeName, ArrayNode nodes) { // https://openproject.nebulouscloud.eu/projects/nebulous-collaboration-hub/wiki/deployment-manager-sal-1#specification-of-endpoints-being-developed ObjectNode body = mapper.createObjectNode() - .put("name", appID) + .put("name", clusterName) .put("master-node", masterNodeName); body.putArray("nodes").addAll(nodes); Map msg; @@ -438,11 +435,6 @@ public class ExnConnector { Map response = defineCluster.sendSync(msg, appID, null, false); JsonNode payload = extractPayloadFromExnResponse(response, appID); return payload.asBoolean(); - // TODO: check if we still need to unwrap this; see - // `AbstractProcessor.groovy#normalizeResponse` and bug 2055053 - // https://opendev.org/nebulous/exn-middleware/src/commit/ffc2ca7bdf657b3831d2b803ff2b84d5e8e1bdcd/exn-middleware-core/src/main/groovy/eu/nebulouscloud/exn/modules/sal/processors/AbstractProcessor.groovy#L111 - // https://bugs.launchpad.net/nebulous/+bug/2055053 - // return payload.at("/success").asBoolean(); } /** @@ -483,62 +475,48 @@ public class ExnConnector { /** * Deploy a cluster created by {@link #defineCluster}. * - * @param appID The application's id, used to name the cluster. + * @param appID The application's id, used for logging only. + * @param clusterName The name of the cluster. * @return true if the cluster was successfully deployed, false otherwise. */ - public boolean deployCluster(String appID) { + public boolean deployCluster(String appID, String clusterName) { // https://openproject.nebulouscloud.eu/projects/nebulous-collaboration-hub/wiki/deployment-manager-sal-1#specification-of-endpoints-being-developed - ObjectNode body = mapper.createObjectNode() - .put("applicationId", appID); - Map msg; - try { - msg = Map.of("metaData", Map.of("user", "admin"), - "body", mapper.writeValueAsString(body)); - } catch (JsonProcessingException e) { - log.error("Could not convert JSON to string (this should never happen)", - keyValue("appId", appID), e); - return false; - } + Map msg = Map.of("metaData", + Map.of("user", "admin", "clusterName", clusterName)); Map response = deployCluster.sendSync(msg, appID, null, false); JsonNode payload = extractPayloadFromExnResponse(response, appID); return payload.asBoolean(); - // TODO: check if we still need to unwrap this; see - // `AbstractProcessor.groovy#normalizeResponse` and bug 2055053 - // https://opendev.org/nebulous/exn-middleware/src/commit/ffc2ca7bdf657b3831d2b803ff2b84d5e8e1bdcd/exn-middleware-core/src/main/groovy/eu/nebulouscloud/exn/modules/sal/processors/AbstractProcessor.groovy#L111 - // https://bugs.launchpad.net/nebulous/+bug/2055053 - // return payload.at("/success").asBoolean(); } /** * Submit a KubeVela file to a deployed cluster. * * @param appID The application's id. + * @param clusterName The name of the cluster. + * @param appName The name of the application. * @param kubevela The KubeVela file, with node affinity traits - * corresponding to the cluster definintion. - * @return true if the application was successfully deployed, false otherwise. + * corresponding to the cluster definintion, serialized into a string. + * @return the ProActive job ID, or -1 in case of failure. */ - public boolean deployApplication(String appID, String kubevela) { - // https://openproject.nebulouscloud.eu/projects/nebulous-collaboration-hub/wiki/deployment-manager-sal-1#specification-of-endpoints-being-developed + public long deployApplication(String appID, String clusterName, String appName, String kubevela) { ObjectNode body = mapper.createObjectNode() - .put("applicationId", appID) - .put("KubevelaYaml", kubevela); + .put("appFile", kubevela) + .put("packageManager", "kubevela") + .put("appName", appName) + .put("action", "apply") + .put("flags", ""); Map msg; try { - msg = Map.of("metaData", Map.of("user", "admin"), + msg = Map.of("metaData", Map.of("user", "admin", "clusterName", clusterName), "body", mapper.writeValueAsString(body)); } catch (JsonProcessingException e) { log.error("Could not convert JSON to string (this should never happen)", keyValue("appId", appID), e); - return false; + return -1; } Map response = deployApplication.sendSync(msg, appID, null, false); JsonNode payload = extractPayloadFromExnResponse(response, appID); - return payload.asBoolean(); - // TODO: check if we still need to unwrap this; see - // `AbstractProcessor.groovy#normalizeResponse` and bug 2055053 - // https://opendev.org/nebulous/exn-middleware/src/commit/ffc2ca7bdf657b3831d2b803ff2b84d5e8e1bdcd/exn-middleware-core/src/main/groovy/eu/nebulouscloud/exn/modules/sal/processors/AbstractProcessor.groovy#L111 - // https://bugs.launchpad.net/nebulous/+bug/2055053 - // return payload.at("/success").asBoolean(); + return payload.asLong(); } /** diff --git a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/LocalExecution.java b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/LocalExecution.java index 8354c08..548f148 100644 --- a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/LocalExecution.java +++ b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/LocalExecution.java @@ -12,6 +12,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import picocli.CommandLine.Command; +import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; import picocli.CommandLine.ParentCommand; @@ -30,6 +31,18 @@ public class LocalExecution implements Callable { @Parameters(description = "The file containing a JSON app creation message") private Path app_creation_msg; + @Option(names = { "--deploy" }, + description = "Deploy application (default true).", + defaultValue = "true", fallbackValue = "true", + negatable = true) + private boolean deploy; + + @Option(names = { "--ampl" }, + description = "Send AMPL file to solver (default true).", + defaultValue = "true", fallbackValue = "true", + negatable = true) + private boolean sendAMPL; + @Override public Integer call() { ObjectMapper mapper = new ObjectMapper(); CountDownLatch exn_synchronizer = new CountDownLatch(1); @@ -46,13 +59,16 @@ public class LocalExecution implements Callable { } NebulousApp app = NebulousApp.newFromAppMessage(msg, connector); if (connector != null) { - log.debug("Sending AMPL to channel {}", connector.getAmplMessagePublisher()); - app.sendAMPL(); - // skip for now until the endpoints are ready and the exn middleware is running - // app.deployUnmodifiedApplication(); + if (sendAMPL) { + log.debug("Sending AMPL to channel {}", connector.getAmplMessagePublisher()); + app.sendAMPL(); + System.out.println(AMPLGenerator.generateAMPL(app)); + } + if (deploy) { + log.debug("Deploying application", connector.getAmplMessagePublisher()); + app.deployUnmodifiedApplication(); + } } - System.out.println(AMPLGenerator.generateAMPL(app)); - // TODO: wait for solver reply here? if (connector != null) { connector.stop(); } diff --git a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousAppDeployer.java b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousAppDeployer.java index 4e20373..7a1d844 100644 --- a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousAppDeployer.java +++ b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousAppDeployer.java @@ -255,7 +255,7 @@ public class NebulousAppDeployer { // 4. Create cluster ObjectNode cluster = mapper.createObjectNode(); - cluster.put("name", appUUID) + cluster.put("name", clusterName) .put("master-node", masterNodeName); ArrayNode nodes = cluster.withArray("nodes"); if (masterNodeCandidate != null) { @@ -270,13 +270,13 @@ public class NebulousAppDeployer { .put("nodeCandidateId", candidate.getId()) .put("cloudId", candidate.getCloud().getId()); }); - boolean defineClusterSuccess = conn.defineCluster(clusterName, masterNodeName, nodes); + boolean defineClusterSuccess = conn.defineCluster(appUUID, clusterName, masterNodeName, nodes); boolean labelClusterSuccess = conn.labelNodes(appUUID, clusterName, nodeLabels); // ------------------------------------------------------------ // 5. Deploy cluster - boolean deployClusterSuccess = conn.deployCluster(clusterName); + boolean deployClusterSuccess = conn.deployCluster(appUUID, clusterName); // ------------------------------------------------------------ // 6. Rewrite KubeVela @@ -292,7 +292,7 @@ public class NebulousAppDeployer { // ------------------------------------------------------------ // 7. Deploy application - // TODO: call deployApplication endpoint + long proActiveJobID = conn.deployApplication(appUUID, clusterName, app.getName(), rewritten_kubevela); // ------------------------------------------------------------ // 8. Update NebulousApp state