diff --git a/src/main/java/com/cfdeployer/service/CfCliService.java b/src/main/java/com/cfdeployer/service/CfCliService.java index 070b2b3..dacd5ae 100644 --- a/src/main/java/com/cfdeployer/service/CfCliService.java +++ b/src/main/java/com/cfdeployer/service/CfCliService.java @@ -206,37 +206,88 @@ public class CfCliService { log.info("Detected operating system: {}", os); log.info("CF CLI executable name: {}", executable); - log.info("Java temp dir: {}", System.getProperty("java.io.tmpdir")); - log.info("User home: {}", System.getProperty("user.home")); - log.info("Current working directory: {}", System.getProperty("user.dir")); - // Use Spring's ClassPathResource for proper Spring Boot JAR support - String resourcePath = String.format("cf-cli/%s/%s", os, executable); - log.info("Looking for CF CLI binary at classpath resource: {}", resourcePath); + String userDir = System.getProperty("user.dir"); + log.info("User directory (user.dir): {}", userDir); + + // In Spring Boot fat JAR on Tanzu, the structure is: + // /home/vcap/app/BOOT-INF/classes/cf-cli/linux/cf8 + Path directPath = Path.of(userDir, "BOOT-INF", "classes", "cf-cli", os, executable); + log.info("Checking for CF CLI at direct file path: {}", directPath); + + if (Files.exists(directPath) && Files.isReadable(directPath)) { + log.info("Found CF CLI binary at direct file path: {} ({} bytes)", + directPath, Files.size(directPath)); + + File tempFile = File.createTempFile("cf-cli-", os.equals("windows") ? ".exe" : ""); + tempFile.deleteOnExit(); + log.info("Created temp file: {}", tempFile.getAbsolutePath()); + + // Copy from direct file path to temp file + long bytesCopied = Files.copy(directPath, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + log.info("Copied CF CLI to temp file: {} ({} bytes)", tempFile.getAbsolutePath(), bytesCopied); + + if (bytesCopied == 0) { + throw new IOException("CF CLI copy failed - 0 bytes copied from " + directPath); + } + + if (!os.equals("windows")) { + try { + Set perms = new HashSet<>(); + perms.add(PosixFilePermission.OWNER_READ); + perms.add(PosixFilePermission.OWNER_WRITE); + perms.add(PosixFilePermission.OWNER_EXECUTE); + Files.setPosixFilePermissions(tempFile.toPath(), perms); + log.info("Set executable permissions on CF CLI binary using Java NIO"); + } catch (Exception e) { + log.warn("Failed to set permissions using Java NIO, trying chmod: {}", e.getMessage()); + try { + ProcessBuilder pb = new ProcessBuilder("chmod", "+x", tempFile.getAbsolutePath()); + Process p = pb.start(); + int exitCode = p.waitFor(); + if (exitCode == 0) { + log.info("Successfully set executable permissions using chmod"); + } else { + log.error("chmod failed with exit code: {}", exitCode); + } + } catch (Exception ex) { + log.error("Failed to set executable permissions: {}", ex.getMessage(), ex); + } + } + } + + log.info("Successfully prepared CF CLI executable: {}", tempFile.getAbsolutePath()); + log.info("File exists: {}, Can read: {}, Can execute: {}", + tempFile.exists(), tempFile.canRead(), tempFile.canExecute()); + + return tempFile.getAbsolutePath(); + } + + // Fallback to classpath resource loading (for local development) + log.info("Direct file path not found, falling back to classpath resource loading"); + String resourcePath = "cf-cli/" + os + "/" + executable; + log.info("Looking for CF CLI at classpath resource: {}", resourcePath); ClassPathResource resource = new ClassPathResource(resourcePath); if (!resource.exists()) { - log.error("CF CLI binary not found in classpath for OS: {}. Resource path: {}", os, resourcePath); - log.error("Resource exists: {}, isReadable: {}", resource.exists(), resource.isReadable()); - throw new IOException("CF CLI binary not found for OS: " + os + " at classpath: " + resourcePath); + log.error("CF CLI binary not found at direct path: {}", directPath); + log.error("CF CLI binary not found in classpath: {}", resourcePath); + throw new IOException("CF CLI binary not found for OS: " + os); } - log.info("CF CLI resource found - exists: {}, isReadable: {}, contentLength: {} bytes", - resource.exists(), resource.isReadable(), resource.contentLength()); + log.info("Found CF CLI in classpath, extracting..."); File tempFile = File.createTempFile("cf-cli-", os.equals("windows") ? ".exe" : ""); tempFile.deleteOnExit(); log.info("Created temp file: {}", tempFile.getAbsolutePath()); - log.info("Extracting CF CLI from classpath resource: {}", resourcePath); - try (InputStream inputStream = resource.getInputStream()) { long bytesCopied = Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - log.info("CF CLI extracted to temporary file: {} ({} bytes)", tempFile.getAbsolutePath(), bytesCopied); + log.info("CF CLI extracted to temp file: {} ({} bytes)", tempFile.getAbsolutePath(), bytesCopied); if (bytesCopied == 0) { - throw new IOException("CF CLI extraction failed - 0 bytes copied from " + resourcePath); + throw new IOException("CF CLI extraction failed - 0 bytes copied"); } } @@ -247,29 +298,13 @@ public class CfCliService { perms.add(PosixFilePermission.OWNER_WRITE); perms.add(PosixFilePermission.OWNER_EXECUTE); Files.setPosixFilePermissions(tempFile.toPath(), perms); - log.info("Set executable permissions on CF CLI binary using Java NIO"); + log.info("Set executable permissions on CF CLI binary"); } catch (Exception e) { - log.warn("Failed to set permissions using Java NIO, trying chmod command: {}", e.getMessage()); - try { - ProcessBuilder pb = new ProcessBuilder("chmod", "+x", tempFile.getAbsolutePath()); - Process p = pb.start(); - int exitCode = p.waitFor(); - if (exitCode == 0) { - log.info("Successfully set executable permissions using chmod command"); - } else { - log.error("chmod command failed with exit code: {}", exitCode); - } - } catch (Exception ex) { - log.error("Failed to set executable permissions: {}", ex.getMessage(), ex); - throw new IOException("Unable to set executable permissions on CF CLI binary", ex); - } + log.warn("Failed to set permissions: {}", e.getMessage()); } } log.info("Successfully prepared CF CLI executable: {}", tempFile.getAbsolutePath()); - log.info("File exists: {}, Can read: {}, Can execute: {}", - tempFile.exists(), tempFile.canRead(), tempFile.canExecute()); - return tempFile.getAbsolutePath(); }