From 52edaf4e49132298fc44bcaf3a1e87c1a9ae83a7 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Thu, 6 Jan 2022 21:22:17 +0530 Subject: [PATCH] Fix #3568: Pod upload file fails if file is directly in root path Pod file upload seems be be creating invalid exec command for upload if the file is directly in root path e.g. `/cp.log`. We create parent directory of file by creating a substring based on last index of `/`. This returns an empty string for a string like `/cp.log`. Assume directory path to be `/` when directory is returned as empty string. Signed-off-by: Rohan Kumar --- CHANGELOG.md | 1 + .../dsl/internal/uploadable/PodUpload.java | 15 ++++++----- .../internal/uploadable/PodUploadTest.java | 26 ++++++++++++++++++- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eaeae8bec1..2a531cf8ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Fix #3588: `openshift-server-mock` is not listed in dependencyManagement in main pom * Fix #3679: output additionalProperties field with correct value type for map-like fields (CRD Generator) * Fix #3648: `Serialization.unmarshal` fails to deserialize YAML with single document in presence of document delimiter(`---`) +* Fix #3568: Pod file upload fails if the path is `/` #### Improvements * Fix #3674: allows the connect and websocket timeouts to apply to watches instead of a hardcoded timeout diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/uploadable/PodUpload.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/uploadable/PodUpload.java index f8a956ea9b..b7819b0df8 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/uploadable/PodUpload.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/uploadable/PodUpload.java @@ -73,13 +73,8 @@ public static boolean upload(HttpClient client, PodOperationContext context, private static boolean uploadFile(HttpClient client, PodOperationContext context, OperationSupport operationSupport, Path pathToUpload) throws IOException, InterruptedException { - - final String file = context.getFile(); - final String directory = file.substring(0, file.lastIndexOf('/')); - final String command = String.format( - "mkdir -p %s && base64 -d - > %s", shellQuote(directory), shellQuote(file)); final PodUploadWebSocketListener podUploadWebSocketListener = initWebSocket( - buildCommandUrl(command, context, operationSupport), client); + buildCommandUrl(createExecCommandForUpload(context), context, operationSupport), client); try ( final FileInputStream fis = new FileInputStream(pathToUpload.toFile()); final Base64.InputStream b64In = new Base64.InputStream(fis, Base64.ENCODE) @@ -193,4 +188,12 @@ private static URL buildCommandUrl(String command, PodOperationContext context, return new URL( URLUtils.join(operationSupport.getResourceUrl().toString(), commandBuilder.toString())); } + + static String createExecCommandForUpload(PodOperationContext context) { + final String file = context.getFile(); + String directoryTrimmedFromFilePath = file.substring(0, file.lastIndexOf('/')); + final String directory = directoryTrimmedFromFilePath.isEmpty() ? "/" : directoryTrimmedFromFilePath; + return String.format( + "mkdir -p %s && base64 -d - > %s", shellQuote(directory), shellQuote(file)); + } } diff --git a/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/dsl/internal/uploadable/PodUploadTest.java b/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/dsl/internal/uploadable/PodUploadTest.java index 65bf7bf95e..94c341fdc0 100644 --- a/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/dsl/internal/uploadable/PodUploadTest.java +++ b/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/dsl/internal/uploadable/PodUploadTest.java @@ -80,7 +80,7 @@ void tearDown() { } @Test - void testUploadInvalidParametersShouldThrowException() throws Exception { + void testUploadInvalidParametersShouldThrowException() { final IllegalArgumentException result = assertThrows(IllegalArgumentException.class, () -> PodUpload.upload(mockClient, mockContext, operationSupport, mockPathToUpload)); @@ -171,4 +171,28 @@ void testCopy() throws Exception { PodUpload.copy(input, consumer); } + @Test + void createExecCommandForUpload_withFileInRootPath_shouldCreateValidExecCommandForUpload() { + // Given + when(mockContext.getFile()).thenReturn("/cp.log"); + + // When + String result = PodUpload.createExecCommandForUpload(mockContext); + + // Then + assertThat(result, equalTo("mkdir -p '/' && base64 -d - > '/cp.log'")); + } + + @Test + void createExecCommandForUpload_withNormalFile_shouldCreateValidExecCommandForUpload() { + // Given + when(mockContext.getFile()).thenReturn("/tmp/foo/cp.log"); + + // When + String result = PodUpload.createExecCommandForUpload(mockContext); + + // Then + assertThat(result, equalTo("mkdir -p '/tmp/foo' && base64 -d - > '/tmp/foo/cp.log'")); + } + }