← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~chad.smith/cloud-init:clean-unlink-symlinks into cloud-init:master

 

Chad Smith has proposed merging ~chad.smith/cloud-init:clean-unlink-symlinks into cloud-init:master.

Requested reviews:
  cloud-init commiters (cloud-init-dev)

For more details, see:
https://code.launchpad.net/~chad.smith/cloud-init/+git/cloud-init/+merge/335671

cli: cloud-init clean handles symlinks

Fix cloud-init clean subcommand to unlink symlinks instead of calling
del_dir.

LP: #1741093
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~chad.smith/cloud-init:clean-unlink-symlinks into cloud-init:master.
diff --git a/cloudinit/cmd/clean.py b/cloudinit/cmd/clean.py
index 81797b1..de22f7f 100644
--- a/cloudinit/cmd/clean.py
+++ b/cloudinit/cmd/clean.py
@@ -10,7 +10,8 @@ import sys
 
 from cloudinit.stages import Init
 from cloudinit.util import (
-    ProcessExecutionError, chdir, del_dir, del_file, get_config_logfiles, subp)
+    ProcessExecutionError, chdir, del_dir, del_file, get_config_logfiles,
+    is_link, subp)
 
 
 def error(msg):
@@ -65,7 +66,7 @@ def remove_artifacts(remove_logs, remove_seed=False):
             if path == 'seed' and not remove_seed:
                 continue
             try:
-                if os.path.isdir(path):
+                if os.path.isdir(path) and not is_link(path):
                     del_dir(path)
                 else:
                     del_file(path)
diff --git a/cloudinit/cmd/tests/test_clean.py b/cloudinit/cmd/tests/test_clean.py
index 1379740..6713af4 100644
--- a/cloudinit/cmd/tests/test_clean.py
+++ b/cloudinit/cmd/tests/test_clean.py
@@ -1,7 +1,7 @@
 # This file is part of cloud-init. See LICENSE file for license information.
 
 from cloudinit.cmd import clean
-from cloudinit.util import ensure_dir, write_file
+from cloudinit.util import ensure_dir, sym_link, write_file
 from cloudinit.tests.helpers import CiTestCase, wrap_and_call, mock
 from collections import namedtuple
 import os
@@ -60,6 +60,23 @@ class TestClean(CiTestCase):
         self.assertTrue(os.path.exists(self.log2), 'Missing expected file')
         self.assertEqual(0, retcode)
 
+    def test_remove_artifacts_removes_unlinks_symlinks(self):
+        """remove_artifacts cleans artifacts dir unlinking any symlinks."""
+        dir1 = os.path.join(self.artifact_dir, 'dir1')
+        ensure_dir(dir1)
+        symlink = os.path.join(self.artifact_dir, 'mylink')
+        sym_link(dir1, symlink)
+
+        retcode = wrap_and_call(
+            'cloudinit.cmd.clean',
+            {'Init': {'side_effect': self.init_class}},
+            clean.remove_artifacts, remove_logs=False)
+        self.assertEqual(0, retcode)
+        for path in (dir1, symlink):
+            self.assertFalse(
+                os.path.exists(path),
+                'Unexpected {0} dir'.format(path))
+
     def test_remove_artifacts_removes_artifacts_skipping_seed(self):
         """remove_artifacts cleans artifacts dir with exception of seed dir."""
         dirs = [