-
Notifications
You must be signed in to change notification settings - Fork 1.3k
kubernetes: clean up temporary provisioning scripts on the management server #13592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -761,6 +761,25 @@ protected void copyScriptFile(String nodeAddress, final int sshPort, File file, | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Deletes the local temporary copies of the scripts created by {@link #retrieveScriptFiles()} | ||
| * once they have been copied to the cluster node(s). Without this, every deploy/autoscale/PV-cleanup | ||
| * action leaks a *.sh file in the management server's tmp directory. | ||
| */ | ||
| protected void cleanupScriptFiles() { | ||
| deleteScriptFileQuietly(deploySecretsScriptFile); | ||
| deleteScriptFileQuietly(deployProviderScriptFile); | ||
| deleteScriptFileQuietly(deployCsiDriverScriptFile); | ||
| deleteScriptFileQuietly(deletePvScriptFile); | ||
| deleteScriptFileQuietly(autoscaleScriptFile); | ||
| } | ||
|
|
||
| protected void deleteScriptFileQuietly(File file) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the field be set to null after deleting? Right now it still points to a file that no longer exists. If it's used again before |
||
| if (file != null && file.exists() && !file.delete()) { | ||
| logger.debug("Failed to delete temporary Kubernetes cluster script file: {}", file.getAbsolutePath()); | ||
| } | ||
| } | ||
|
|
||
| protected boolean taintControlNodes() { | ||
| StringBuilder commands = new StringBuilder(); | ||
| List<KubernetesClusterVmMapVO> vmMapVOList = getKubernetesClusterVMMaps(); | ||
|
|
@@ -820,7 +839,11 @@ protected boolean deployProvider() { | |
| if (!result.first()) { | ||
| logMessage(Level.INFO, "Provider files missing. Adding them now", null); | ||
| retrieveScriptFiles(); | ||
| copyScripts(publicIpAddress, sshPort); | ||
| try { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This same |
||
| copyScripts(publicIpAddress, sshPort); | ||
| } finally { | ||
| cleanupScriptFiles(); | ||
| } | ||
|
|
||
| if (!createCloudStackSecret(keys)) { | ||
| logTransitStateAndThrow(Level.ERROR, String.format("Failed to setup keys for Kubernetes cluster %s", | ||
|
|
@@ -857,7 +880,11 @@ protected boolean deployCsiDriver() { | |
| if (!result.first()) { | ||
| logMessage(Level.INFO, "CSI files missing. Adding them now", null); | ||
| retrieveScriptFiles(); | ||
| copyScripts(publicIpAddress, sshPort); | ||
| try { | ||
| copyScripts(publicIpAddress, sshPort); | ||
| } finally { | ||
| cleanupScriptFiles(); | ||
| } | ||
|
|
||
| if (!createCloudStackSecret(keys)) { | ||
| logTransitStateAndThrow(Level.ERROR, String.format("Failed to setup keys for Kubernetes cluster %s", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,6 +63,12 @@ protected void retrieveScriptFiles() { | |
| upgradeScriptFile = retrieveScriptFile(upgradeScriptFilename); | ||
| } | ||
|
|
||
| @Override | ||
| protected void cleanupScriptFiles() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this delete |
||
| super.cleanupScriptFiles(); | ||
| deleteScriptFileQuietly(upgradeScriptFile); | ||
| } | ||
|
|
||
| private Pair<Boolean, String> runInstallScriptOnVM(final UserVm vm, final int index) throws Exception { | ||
| int nodeSshPort = sshPort == 22 ? sshPort : sshPort + index; | ||
| String nodeAddress = (index > 0 && sshPort == 22) ? vm.getPrivateIpAddress() : publicIpAddress; | ||
|
|
@@ -176,7 +182,11 @@ public boolean upgradeCluster() throws CloudRuntimeException { | |
| retrieveScriptFiles(); | ||
| stateTransitTo(kubernetesCluster.getId(), KubernetesCluster.Event.UpgradeRequested); | ||
| attachIsoKubernetesVMs(clusterVMs, upgradeVersion); | ||
| upgradeKubernetesClusterNodes(); | ||
| try { | ||
| upgradeKubernetesClusterNodes(); | ||
| } finally { | ||
| cleanupScriptFiles(); | ||
| } | ||
| detachIsoKubernetesVMs(clusterVMs); | ||
| KubernetesClusterVO kubernetesClusterVO = kubernetesClusterDao.findById(kubernetesCluster.getId()); | ||
| kubernetesClusterVO.setKubernetesVersionId(upgradeVersion.getId()); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |
| // under the License. | ||
| package com.cloud.kubernetes.cluster.actionworkers; | ||
|
|
||
| import java.io.File; | ||
| import java.util.ArrayList; | ||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
|
|
@@ -229,4 +230,48 @@ public void testGetMergedAffinityGroupIdsExplicitDedicationAlreadyInList() { | |
| Assert.assertTrue(result.contains(99L)); | ||
| Assert.assertTrue(result.contains(2L)); | ||
| } | ||
|
|
||
| @Test | ||
| public void testCleanupScriptFilesDeletesAllTempFiles() throws Exception { | ||
| actionWorker.deploySecretsScriptFile = File.createTempFile("deploy-cloudstack-secret", ".sh"); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: these strings duplicate |
||
| actionWorker.deployProviderScriptFile = File.createTempFile("deploy-provider", ".sh"); | ||
| actionWorker.deployCsiDriverScriptFile = File.createTempFile("deploy-csi-driver", ".sh"); | ||
| actionWorker.deletePvScriptFile = File.createTempFile("delete-pv-reclaimpolicy-delete", ".sh"); | ||
| actionWorker.autoscaleScriptFile = File.createTempFile("autoscale-kube-cluster", ".sh"); | ||
|
|
||
| List<File> files = Arrays.asList(actionWorker.deploySecretsScriptFile, actionWorker.deployProviderScriptFile, | ||
| actionWorker.deployCsiDriverScriptFile, actionWorker.deletePvScriptFile, actionWorker.autoscaleScriptFile); | ||
| for (File f : files) { | ||
| Assert.assertTrue(f.exists()); | ||
| } | ||
|
|
||
| actionWorker.cleanupScriptFiles(); | ||
|
|
||
| for (File f : files) { | ||
| Assert.assertFalse("Temporary script file should have been deleted: " + f.getAbsolutePath(), f.exists()); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void testDeleteScriptFileQuietlyHandlesNullAndMissingFiles() throws Exception { | ||
| // null must not throw | ||
| actionWorker.deleteScriptFileQuietly(null); | ||
|
|
||
| // a File that does not exist must not throw | ||
| File missing = new File(System.getProperty("java.io.tmpdir"), "cks-nonexistent-" + UUID.randomUUID() + ".sh"); | ||
| Assert.assertFalse(missing.exists()); | ||
| actionWorker.deleteScriptFileQuietly(missing); | ||
|
|
||
| // an existing file is deleted | ||
| File present = File.createTempFile("cks-present", ".sh"); | ||
| Assert.assertTrue(present.exists()); | ||
| actionWorker.deleteScriptFileQuietly(present); | ||
| Assert.assertFalse(present.exists()); | ||
| } | ||
|
|
||
| @Test | ||
| public void testCleanupScriptFilesWithNullFieldsDoesNotThrow() { | ||
| // No retrieveScriptFiles() was called, so all file fields are null. | ||
| actionWorker.cleanupScriptFiles(); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: could this loop over a list of the 5 fields instead of calling
deleteScriptFileQuietly5 times by hand? Would be one line instead of five, and less to update if a new script field gets added later.