diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..008434d --- /dev/null +++ b/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + + com.cameleer + cameleer-deploy-demo + 0.1.0-SNAPSHOT + Cameleer Deploy Demo + Demo: upload Camel JARs, build containers with agent injection, deploy to K8s + + + 21 + + + + + org.springframework.boot + spring-boot-starter-web + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/src/main/java/com/cameleer/deploy/DeployDemoApplication.java b/src/main/java/com/cameleer/deploy/DeployDemoApplication.java new file mode 100644 index 0000000..d6e6871 --- /dev/null +++ b/src/main/java/com/cameleer/deploy/DeployDemoApplication.java @@ -0,0 +1,11 @@ +package com.cameleer.deploy; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DeployDemoApplication { + public static void main(String[] args) { + SpringApplication.run(DeployDemoApplication.class, args); + } +} diff --git a/src/main/java/com/cameleer/deploy/config/DeployProperties.java b/src/main/java/com/cameleer/deploy/config/DeployProperties.java new file mode 100644 index 0000000..34e9e94 --- /dev/null +++ b/src/main/java/com/cameleer/deploy/config/DeployProperties.java @@ -0,0 +1,33 @@ +package com.cameleer.deploy.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "cameleer.deploy") +public class DeployProperties { + private String serverUrl = "http://cameleer3-server.cameleer.svc:8081"; + private String bootstrapToken = "changeme"; + private String registry = "gitea.siegeln.net/cameleer/demo-apps"; + private String agentMavenUrl; + private String demoNamespace = "cameleer-demo"; + private String cameleerServerUi = "http://localhost:8081"; + + public String getServerUrl() { return serverUrl; } + public void setServerUrl(String serverUrl) { this.serverUrl = serverUrl; } + + public String getBootstrapToken() { return bootstrapToken; } + public void setBootstrapToken(String bootstrapToken) { this.bootstrapToken = bootstrapToken; } + + public String getRegistry() { return registry; } + public void setRegistry(String registry) { this.registry = registry; } + + public String getAgentMavenUrl() { return agentMavenUrl; } + public void setAgentMavenUrl(String agentMavenUrl) { this.agentMavenUrl = agentMavenUrl; } + + public String getDemoNamespace() { return demoNamespace; } + public void setDemoNamespace(String demoNamespace) { this.demoNamespace = demoNamespace; } + + public String getCameleerServerUi() { return cameleerServerUi; } + public void setCameleerServerUi(String cameleerServerUi) { this.cameleerServerUi = cameleerServerUi; } +} diff --git a/src/main/java/com/cameleer/deploy/config/WebConfig.java b/src/main/java/com/cameleer/deploy/config/WebConfig.java new file mode 100644 index 0000000..f89cbc8 --- /dev/null +++ b/src/main/java/com/cameleer/deploy/config/WebConfig.java @@ -0,0 +1,16 @@ +package com.cameleer.deploy.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/api/**") + .allowedOriginPatterns("*") + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .allowedHeaders("*"); + } +} diff --git a/src/main/java/com/cameleer/deploy/controller/DeployController.java b/src/main/java/com/cameleer/deploy/controller/DeployController.java new file mode 100644 index 0000000..eae6413 --- /dev/null +++ b/src/main/java/com/cameleer/deploy/controller/DeployController.java @@ -0,0 +1,94 @@ +package com.cameleer.deploy.controller; + +import com.cameleer.deploy.config.DeployProperties; +import com.cameleer.deploy.model.DeployRequest; +import com.cameleer.deploy.model.DeployedApp; +import com.cameleer.deploy.service.DeployService; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/api/apps") +public class DeployController { + + private final DeployService deployService; + private final DeployProperties props; + private final ObjectMapper objectMapper; + + public DeployController(DeployService deployService, DeployProperties props, ObjectMapper objectMapper) { + this.deployService = deployService; + this.props = props; + this.objectMapper = objectMapper; + } + + @GetMapping + public List list() { + return deployService.listApps(); + } + + @GetMapping("/{name}") + public ResponseEntity get(@PathVariable String name) { + return deployService.getApp(name) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/{name}/logs") + public List logs(@PathVariable String name) { + return deployService.getBuildLog(name); + } + + @PostMapping + public ResponseEntity deploy( + @RequestParam("name") String name, + @RequestParam("jar") MultipartFile jar, + @RequestParam(value = "cpuRequest", required = false) String cpuRequest, + @RequestParam(value = "memoryRequest", required = false) String memoryRequest, + @RequestParam(value = "cpuLimit", required = false) String cpuLimit, + @RequestParam(value = "memoryLimit", required = false) String memoryLimit, + @RequestParam(value = "envVars", required = false) String envVarsJson + ) { + try { + if (!name.matches("^[a-z0-9]([a-z0-9-]*[a-z0-9])?$")) { + return ResponseEntity.badRequest().build(); + } + if (jar.isEmpty() || !jar.getOriginalFilename().endsWith(".jar")) { + return ResponseEntity.badRequest().build(); + } + + Map envVars = Map.of(); + if (envVarsJson != null && !envVarsJson.isBlank()) { + envVars = objectMapper.readValue(envVarsJson, new TypeReference<>() {}); + } + + var request = new DeployRequest(name, cpuRequest, memoryRequest, cpuLimit, memoryLimit, envVars); + var app = deployService.deploy(name, jar, request); + return ResponseEntity.accepted().body(app); + } catch (IllegalArgumentException e) { + return ResponseEntity.badRequest().build(); + } catch (Exception e) { + return ResponseEntity.internalServerError().build(); + } + } + + @DeleteMapping("/{name}") + public ResponseEntity undeploy(@PathVariable String name) { + try { + deployService.undeploy(name); + return ResponseEntity.noContent().build(); + } catch (IllegalArgumentException e) { + return ResponseEntity.notFound().build(); + } + } + + @GetMapping("/config") + public Map config() { + return Map.of("cameleerServerUi", props.getCameleerServerUi()); + } +} diff --git a/src/main/java/com/cameleer/deploy/model/DeployRequest.java b/src/main/java/com/cameleer/deploy/model/DeployRequest.java new file mode 100644 index 0000000..e2a4a54 --- /dev/null +++ b/src/main/java/com/cameleer/deploy/model/DeployRequest.java @@ -0,0 +1,12 @@ +package com.cameleer.deploy.model; + +import java.util.Map; + +public record DeployRequest( + String name, + String cpuRequest, + String memoryRequest, + String cpuLimit, + String memoryLimit, + Map envVars +) {} diff --git a/src/main/java/com/cameleer/deploy/model/DeployStatus.java b/src/main/java/com/cameleer/deploy/model/DeployStatus.java new file mode 100644 index 0000000..4afaade --- /dev/null +++ b/src/main/java/com/cameleer/deploy/model/DeployStatus.java @@ -0,0 +1,11 @@ +package com.cameleer.deploy.model; + +public enum DeployStatus { + BUILDING, + PUSHING, + DEPLOYING, + RUNNING, + PENDING, + FAILED, + DELETED +} diff --git a/src/main/java/com/cameleer/deploy/model/DeployedApp.java b/src/main/java/com/cameleer/deploy/model/DeployedApp.java new file mode 100644 index 0000000..1e87580 --- /dev/null +++ b/src/main/java/com/cameleer/deploy/model/DeployedApp.java @@ -0,0 +1,23 @@ +package com.cameleer.deploy.model; + +import java.time.Instant; +import java.util.Map; + +public record DeployedApp( + String name, + String imageName, + String imageTag, + DeployStatus status, + String statusMessage, + ResourceConfig resources, + Map envVars, + Instant createdAt +) { + public DeployedApp withStatus(DeployStatus status, String message) { + return new DeployedApp(name, imageName, imageTag, status, message, resources, envVars, createdAt); + } + + public DeployedApp withImage(String imageName, String imageTag) { + return new DeployedApp(name, imageName, imageTag, status, statusMessage, resources, envVars, createdAt); + } +} diff --git a/src/main/java/com/cameleer/deploy/model/ResourceConfig.java b/src/main/java/com/cameleer/deploy/model/ResourceConfig.java new file mode 100644 index 0000000..14e1e36 --- /dev/null +++ b/src/main/java/com/cameleer/deploy/model/ResourceConfig.java @@ -0,0 +1,12 @@ +package com.cameleer.deploy.model; + +public record ResourceConfig( + String cpuRequest, + String memoryRequest, + String cpuLimit, + String memoryLimit +) { + public static ResourceConfig defaults() { + return new ResourceConfig("250m", "256Mi", "500m", "512Mi"); + } +} diff --git a/src/main/java/com/cameleer/deploy/service/DeployService.java b/src/main/java/com/cameleer/deploy/service/DeployService.java new file mode 100644 index 0000000..e5a22bf --- /dev/null +++ b/src/main/java/com/cameleer/deploy/service/DeployService.java @@ -0,0 +1,312 @@ +package com.cameleer.deploy.service; + +import com.cameleer.deploy.config.DeployProperties; +import com.cameleer.deploy.model.*; +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +@Service +public class DeployService { + + private static final Logger log = LoggerFactory.getLogger(DeployService.class); + + private final ConcurrentHashMap apps = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> buildLogs = new ConcurrentHashMap<>(); + private final DeployProperties props; + private final ShellExecutor shell; + + public DeployService(DeployProperties props, ShellExecutor shell) { + this.props = props; + this.shell = shell; + } + + @PostConstruct + public void rediscoverApps() { + try { + String output = shell.exec("kubectl", "get", "deployments", + "-n", props.getDemoNamespace(), + "-l", "app.kubernetes.io/managed-by=cameleer-deploy", + "-o", "jsonpath={range .items[*]}{.metadata.name}|{.spec.template.spec.containers[0].image}|{.metadata.creationTimestamp}{\"\\n\"}{end}"); + + for (String line : output.split("\n")) { + line = line.trim(); + if (line.isEmpty()) continue; + String[] parts = line.split("\\|"); + if (parts.length < 3) continue; + + String name = parts[0]; + String fullImage = parts[1]; + String created = parts[2]; + + String imageName = fullImage.contains(":") ? fullImage.substring(0, fullImage.lastIndexOf(':')) : fullImage; + String imageTag = fullImage.contains(":") ? fullImage.substring(fullImage.lastIndexOf(':') + 1) : "latest"; + + apps.put(name, new DeployedApp( + name, imageName, imageTag, + DeployStatus.RUNNING, null, + ResourceConfig.defaults(), + Map.of(), + Instant.parse(created) + )); + log.info("Rediscovered app: {}", name); + } + } catch (Exception e) { + log.warn("Could not rediscover apps from namespace {}: {}", props.getDemoNamespace(), e.getMessage()); + } + } + + public List listApps() { + reconcileStatuses(); + return apps.values().stream() + .filter(a -> a.status() != DeployStatus.DELETED) + .sorted(Comparator.comparing(DeployedApp::createdAt).reversed()) + .toList(); + } + + public Optional getApp(String name) { + return Optional.ofNullable(apps.get(name)); + } + + public List getBuildLog(String name) { + return buildLogs.getOrDefault(name, List.of()); + } + + public DeployedApp deploy(String name, MultipartFile jarFile, DeployRequest request) throws IOException { + if (apps.containsKey(name) && apps.get(name).status() != DeployStatus.DELETED) { + throw new IllegalArgumentException("App '" + name + "' already exists"); + } + + var resources = new ResourceConfig( + request.cpuRequest() != null ? request.cpuRequest() : "250m", + request.memoryRequest() != null ? request.memoryRequest() : "256Mi", + request.cpuLimit() != null ? request.cpuLimit() : "500m", + request.memoryLimit() != null ? request.memoryLimit() : "512Mi" + ); + + var envVars = request.envVars() != null ? request.envVars() : Map.of(); + String imageTag = String.valueOf(System.currentTimeMillis()); + String imageName = props.getRegistry() + "/" + name; + + var app = new DeployedApp(name, imageName, imageTag, + DeployStatus.BUILDING, null, resources, envVars, Instant.now()); + apps.put(name, app); + buildLogs.put(name, Collections.synchronizedList(new ArrayList<>())); + + // Run pipeline async + Thread.ofVirtual().name("deploy-" + name).start(() -> { + try { + runPipeline(name, jarFile.getBytes(), imageName, imageTag, resources, envVars); + } catch (Exception e) { + log.error("Deploy pipeline failed for {}", name, e); + appendLog(name, "FATAL: " + e.getMessage()); + apps.computeIfPresent(name, (k, v) -> v.withStatus(DeployStatus.FAILED, e.getMessage())); + } + }); + + return app; + } + + public void undeploy(String name) { + var app = apps.get(name); + if (app == null) throw new IllegalArgumentException("App '" + name + "' not found"); + + try { + appendLog(name, "Deleting deployment..."); + shell.exec("kubectl", "delete", "deployment", name, + "-n", props.getDemoNamespace(), "--ignore-not-found=true"); + appendLog(name, "Deployment deleted."); + + apps.computeIfPresent(name, (k, v) -> v.withStatus(DeployStatus.DELETED, "Undeployed")); + } catch (Exception e) { + log.error("Failed to undeploy {}", name, e); + throw new RuntimeException("Failed to undeploy: " + e.getMessage()); + } + } + + private void runPipeline(String name, byte[] jarBytes, String imageName, + String imageTag, ResourceConfig resources, + Map envVars) throws Exception { + Path buildDir = Files.createTempDirectory("cameleer-build-" + name); + try { + // 1. Write JAR + appendLog(name, "Saving JAR file..."); + Path jarPath = buildDir.resolve("app.jar"); + Files.write(jarPath, jarBytes); + appendLog(name, "JAR saved (" + jarBytes.length / 1024 + " KB)"); + + // 2. Generate Dockerfile + appendLog(name, "Generating Dockerfile..."); + String dockerfile = generateDockerfile(name); + Files.writeString(buildDir.resolve("Dockerfile"), dockerfile); + appendLog(name, "Dockerfile generated"); + + // 3. Build image + String fullTag = imageName + ":" + imageTag; + appendLog(name, "Building image: " + fullTag); + apps.computeIfPresent(name, (k, v) -> v.withStatus(DeployStatus.BUILDING, "docker build")); + + String buildOutput = shell.exec("docker", "build", "-t", fullTag, buildDir.toString()); + for (String line : buildOutput.split("\n")) { + appendLog(name, "[build] " + line); + } + appendLog(name, "Image built successfully"); + + // 4. Push image + appendLog(name, "Pushing image to registry..."); + apps.computeIfPresent(name, (k, v) -> v.withStatus(DeployStatus.PUSHING, "docker push")); + + String pushOutput = shell.exec("docker", "push", fullTag); + for (String line : pushOutput.split("\n")) { + if (!line.isBlank()) appendLog(name, "[push] " + line); + } + appendLog(name, "Image pushed successfully"); + + // 5. Deploy to K8s + appendLog(name, "Deploying to Kubernetes..."); + apps.computeIfPresent(name, (k, v) -> v.withStatus(DeployStatus.DEPLOYING, "kubectl apply")); + + String manifest = generateManifest(name, fullTag, resources, envVars); + Path manifestPath = buildDir.resolve("deployment.yaml"); + Files.writeString(manifestPath, manifest); + + String applyOutput = shell.exec("kubectl", "apply", "-f", manifestPath.toString()); + appendLog(name, "[kubectl] " + applyOutput.trim()); + + apps.computeIfPresent(name, (k, v) -> v + .withImage(imageName, imageTag) + .withStatus(DeployStatus.PENDING, "Waiting for pod to start")); + appendLog(name, "Deployment applied. Waiting for pod..."); + + } finally { + // Cleanup + try { + Files.walk(buildDir) + .sorted(Comparator.reverseOrder()) + .forEach(p -> { try { Files.delete(p); } catch (IOException ignored) {} }); + } catch (IOException ignored) {} + } + } + + private String generateDockerfile(String appName) { + return """ + FROM eclipse-temurin:21-jre-alpine + + ADD %s /opt/cameleer/agent.jar + + COPY app.jar /opt/app/app.jar + + ENV CAMELEER_SERVER_URL=%s + ENV CAMELEER_APP_NAME=%s + ENV CAMELEER_AUTH_TOKEN=%s + + ENTRYPOINT ["java", "-javaagent:/opt/cameleer/agent.jar", "-jar", "/opt/app/app.jar"] + """.formatted( + props.getAgentMavenUrl(), + props.getServerUrl(), + appName, + props.getBootstrapToken() + ); + } + + private String generateManifest(String name, String image, + ResourceConfig resources, + Map envVars) { + var envLines = new StringBuilder(); + // Standard cameleer env vars are baked into the image, add user-provided ones + for (var entry : envVars.entrySet()) { + envLines.append(""" + - name: %s + value: "%s" + """.formatted(entry.getKey(), entry.getValue().replace("\"", "\\\""))); + } + + return """ + apiVersion: apps/v1 + kind: Deployment + metadata: + name: %s + namespace: %s + labels: + app.kubernetes.io/managed-by: cameleer-deploy + cameleer/app-name: %s + spec: + replicas: 1 + selector: + matchLabels: + app: %s + template: + metadata: + labels: + app: %s + cameleer/app-name: %s + spec: + containers: + - name: app + image: %s + resources: + requests: + cpu: %s + memory: %s + limits: + cpu: %s + memory: %s + env: + %s ports: + - containerPort: 8080 + """.formatted( + name, props.getDemoNamespace(), name, + name, name, name, + image, + resources.cpuRequest(), resources.memoryRequest(), + resources.cpuLimit(), resources.memoryLimit(), + envLines.toString() + ); + } + + private void reconcileStatuses() { + for (var entry : apps.entrySet()) { + var app = entry.getValue(); + if (app.status() == DeployStatus.DELETED || app.status() == DeployStatus.BUILDING + || app.status() == DeployStatus.PUSHING) { + continue; + } + try { + String phase = shell.exec("kubectl", "get", "pods", + "-n", props.getDemoNamespace(), + "-l", "app=" + app.name(), + "-o", "jsonpath={.items[0].status.phase}").trim(); + + DeployStatus newStatus = switch (phase) { + case "Running" -> DeployStatus.RUNNING; + case "Pending" -> DeployStatus.PENDING; + case "Failed", "Unknown" -> DeployStatus.FAILED; + default -> app.status(); + }; + + if (newStatus != app.status()) { + apps.computeIfPresent(entry.getKey(), + (k, v) -> v.withStatus(newStatus, phase)); + } + } catch (Exception e) { + // Pod might not exist yet + } + } + } + + private void appendLog(String name, String line) { + var logList = buildLogs.get(name); + if (logList != null) { + logList.add("[" + Instant.now() + "] " + line); + } + } +} diff --git a/src/main/java/com/cameleer/deploy/service/ShellExecutor.java b/src/main/java/com/cameleer/deploy/service/ShellExecutor.java new file mode 100644 index 0000000..14d2e9e --- /dev/null +++ b/src/main/java/com/cameleer/deploy/service/ShellExecutor.java @@ -0,0 +1,32 @@ +package com.cameleer.deploy.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.TimeUnit; + +@Component +public class ShellExecutor { + + private static final Logger log = LoggerFactory.getLogger(ShellExecutor.class); + + public String exec(String... command) throws IOException, InterruptedException { + log.debug("Executing: {}", String.join(" ", command)); + var pb = new ProcessBuilder(command) + .redirectErrorStream(true); + var process = pb.start(); + String output = new String(process.getInputStream().readAllBytes(), StandardCharsets.UTF_8); + boolean finished = process.waitFor(5, TimeUnit.MINUTES); + if (!finished) { + process.destroyForcibly(); + throw new RuntimeException("Command timed out: " + String.join(" ", command)); + } + if (process.exitValue() != 0) { + throw new RuntimeException("Command failed (exit " + process.exitValue() + "): " + output); + } + return output; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..a6b5e5f --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,17 @@ +server: + port: 8082 + +spring: + servlet: + multipart: + max-file-size: 200MB + max-request-size: 200MB + +cameleer: + deploy: + server-url: ${CAMELEER_SERVER_URL:http://cameleer3-server.cameleer.svc:8081} + bootstrap-token: ${CAMELEER_BOOTSTRAP_TOKEN:changeme} + registry: ${CAMELEER_REGISTRY:gitea.siegeln.net/cameleer/demo-apps} + agent-maven-url: ${CAMELEER_AGENT_MAVEN_URL:https://gitea.siegeln.net/api/packages/cameleer/maven/com/cameleer3/cameleer3-agent/1.0-SNAPSHOT/cameleer3-agent-1.0-SNAPSHOT.jar} + demo-namespace: ${CAMELEER_DEMO_NAMESPACE:cameleer-demo} + cameleer-server-ui: ${CAMELEER_SERVER_UI:http://localhost:8081} diff --git a/target/classes/application.yml b/target/classes/application.yml new file mode 100644 index 0000000..a6b5e5f --- /dev/null +++ b/target/classes/application.yml @@ -0,0 +1,17 @@ +server: + port: 8082 + +spring: + servlet: + multipart: + max-file-size: 200MB + max-request-size: 200MB + +cameleer: + deploy: + server-url: ${CAMELEER_SERVER_URL:http://cameleer3-server.cameleer.svc:8081} + bootstrap-token: ${CAMELEER_BOOTSTRAP_TOKEN:changeme} + registry: ${CAMELEER_REGISTRY:gitea.siegeln.net/cameleer/demo-apps} + agent-maven-url: ${CAMELEER_AGENT_MAVEN_URL:https://gitea.siegeln.net/api/packages/cameleer/maven/com/cameleer3/cameleer3-agent/1.0-SNAPSHOT/cameleer3-agent-1.0-SNAPSHOT.jar} + demo-namespace: ${CAMELEER_DEMO_NAMESPACE:cameleer-demo} + cameleer-server-ui: ${CAMELEER_SERVER_UI:http://localhost:8081} diff --git a/target/classes/com/cameleer/deploy/DeployDemoApplication.class b/target/classes/com/cameleer/deploy/DeployDemoApplication.class new file mode 100644 index 0000000..eeaf070 Binary files /dev/null and b/target/classes/com/cameleer/deploy/DeployDemoApplication.class differ diff --git a/target/classes/com/cameleer/deploy/config/DeployProperties.class b/target/classes/com/cameleer/deploy/config/DeployProperties.class new file mode 100644 index 0000000..5558bf6 Binary files /dev/null and b/target/classes/com/cameleer/deploy/config/DeployProperties.class differ diff --git a/target/classes/com/cameleer/deploy/config/WebConfig.class b/target/classes/com/cameleer/deploy/config/WebConfig.class new file mode 100644 index 0000000..c59aa8e Binary files /dev/null and b/target/classes/com/cameleer/deploy/config/WebConfig.class differ diff --git a/target/classes/com/cameleer/deploy/controller/DeployController$1.class b/target/classes/com/cameleer/deploy/controller/DeployController$1.class new file mode 100644 index 0000000..0cccb82 Binary files /dev/null and b/target/classes/com/cameleer/deploy/controller/DeployController$1.class differ diff --git a/target/classes/com/cameleer/deploy/controller/DeployController.class b/target/classes/com/cameleer/deploy/controller/DeployController.class new file mode 100644 index 0000000..583bab1 Binary files /dev/null and b/target/classes/com/cameleer/deploy/controller/DeployController.class differ diff --git a/target/classes/com/cameleer/deploy/model/DeployRequest.class b/target/classes/com/cameleer/deploy/model/DeployRequest.class new file mode 100644 index 0000000..f393136 Binary files /dev/null and b/target/classes/com/cameleer/deploy/model/DeployRequest.class differ diff --git a/target/classes/com/cameleer/deploy/model/DeployStatus.class b/target/classes/com/cameleer/deploy/model/DeployStatus.class new file mode 100644 index 0000000..646e7c8 Binary files /dev/null and b/target/classes/com/cameleer/deploy/model/DeployStatus.class differ diff --git a/target/classes/com/cameleer/deploy/model/DeployedApp.class b/target/classes/com/cameleer/deploy/model/DeployedApp.class new file mode 100644 index 0000000..0cc9ad2 Binary files /dev/null and b/target/classes/com/cameleer/deploy/model/DeployedApp.class differ diff --git a/target/classes/com/cameleer/deploy/model/ResourceConfig.class b/target/classes/com/cameleer/deploy/model/ResourceConfig.class new file mode 100644 index 0000000..b328a8c Binary files /dev/null and b/target/classes/com/cameleer/deploy/model/ResourceConfig.class differ diff --git a/target/classes/com/cameleer/deploy/service/DeployService.class b/target/classes/com/cameleer/deploy/service/DeployService.class new file mode 100644 index 0000000..239352f Binary files /dev/null and b/target/classes/com/cameleer/deploy/service/DeployService.class differ diff --git a/target/classes/com/cameleer/deploy/service/ShellExecutor.class b/target/classes/com/cameleer/deploy/service/ShellExecutor.class new file mode 100644 index 0000000..817fd3f Binary files /dev/null and b/target/classes/com/cameleer/deploy/service/ShellExecutor.class differ diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..05869aa --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,11 @@ +com\cameleer\deploy\config\WebConfig.class +com\cameleer\deploy\controller\DeployController$1.class +com\cameleer\deploy\controller\DeployController.class +com\cameleer\deploy\DeployDemoApplication.class +com\cameleer\deploy\model\DeployedApp.class +com\cameleer\deploy\service\DeployService.class +com\cameleer\deploy\config\DeployProperties.class +com\cameleer\deploy\model\DeployStatus.class +com\cameleer\deploy\service\ShellExecutor.class +com\cameleer\deploy\model\ResourceConfig.class +com\cameleer\deploy\model\DeployRequest.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..130c48e --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,10 @@ +C:\Users\Hendrik\Documents\projects\cameleer-deploy-demo\src\main\java\com\cameleer\deploy\config\DeployProperties.java +C:\Users\Hendrik\Documents\projects\cameleer-deploy-demo\src\main\java\com\cameleer\deploy\config\WebConfig.java +C:\Users\Hendrik\Documents\projects\cameleer-deploy-demo\src\main\java\com\cameleer\deploy\controller\DeployController.java +C:\Users\Hendrik\Documents\projects\cameleer-deploy-demo\src\main\java\com\cameleer\deploy\DeployDemoApplication.java +C:\Users\Hendrik\Documents\projects\cameleer-deploy-demo\src\main\java\com\cameleer\deploy\model\DeployedApp.java +C:\Users\Hendrik\Documents\projects\cameleer-deploy-demo\src\main\java\com\cameleer\deploy\model\DeployRequest.java +C:\Users\Hendrik\Documents\projects\cameleer-deploy-demo\src\main\java\com\cameleer\deploy\model\DeployStatus.java +C:\Users\Hendrik\Documents\projects\cameleer-deploy-demo\src\main\java\com\cameleer\deploy\model\ResourceConfig.java +C:\Users\Hendrik\Documents\projects\cameleer-deploy-demo\src\main\java\com\cameleer\deploy\service\DeployService.java +C:\Users\Hendrik\Documents\projects\cameleer-deploy-demo\src\main\java\com\cameleer\deploy\service\ShellExecutor.java