Skip to content

Commit 88e313d

Browse files
committed
Refactored linking
Signed-off-by: Victor Moene <victor.moene@northern.tech>
1 parent e87a15d commit 88e313d

2 files changed

Lines changed: 81 additions & 51 deletions

File tree

promise-types/symlinks/symlinks.py

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def is_absolute_dir(v):
1515
if not os.path.isabs(v):
1616
raise ValidationError("must be an absolute path, not '{v}'".format(v=v))
1717
if not os.path.exists(v):
18-
raise ValidationError("dir must exists")
18+
raise ValidationError("directory must exists")
1919
if not os.path.isdir(v):
2020
raise ValidationError("must be a dir")
2121

@@ -43,56 +43,70 @@ def evaluate_promise(self, promiser, attributes, metadata):
4343
model = self.create_attribute_object(promiser, attributes)
4444
link_target = model.file if model.file else model.directory
4545

46-
if not os.path.exists(promiser):
47-
try:
48-
os.symlink(
49-
link_target, promiser, target_is_directory=bool(model.directory)
50-
)
51-
except FileExistsError:
52-
self.log_error(
53-
"Couldn't symlink '{}' to '{}'. A link already exists".format(
54-
link_target, promiser
46+
try:
47+
os.symlink(link_target, promiser, target_is_directory=bool(model.directory))
48+
self.log_info("Created symlink '{}' -> '{}'".format(promiser, link_target))
49+
return Result.REPAIRED
50+
except FileExistsError:
51+
52+
if not os.path.islink(promiser):
53+
self.log_error("Symlink '{}' is already a path".format(promiser))
54+
return Result.NOT_KEPT
55+
56+
if os.path.realpath(promiser) != link_target:
57+
self.log_warning("Symlink '{}' already exists but has wrong target '{}'".format(promiser, os.path.realpath(promiser)))
58+
try:
59+
os.unlink(promiser)
60+
except FileNotFoundError:
61+
self.log_error(
62+
"'{}' is already unlinked from its old target".format(promiser)
5563
)
64+
return Result.NOT_KEPT
65+
except Exception:
66+
self.log_error(
67+
"'{}' has wrong target but couldn't be unlinked: {}".format(
68+
promiser, e
69+
)
70+
)
71+
return Result.NOT_KEPT
72+
try:
73+
os.symlink(
74+
link_target, promiser, target_is_directory=bool(model.directory)
75+
)
76+
except FileExistsError:
77+
self.log_error(
78+
"Couldn't symlink '{}' to '{}'. A symlink already exists".format(
79+
link_target, promiser
80+
)
81+
)
82+
return Result.NOT_KEPT
83+
except FileNotFoundError:
84+
self.log_error("'{}' doesn't exist".format(link_target))
85+
return (Result.NOT_KEPT, ["symlink_no_target_error"])
86+
except Exception as e:
87+
self.log_error(
88+
"Couldn't symlink '{}' to '{}': {}".format(
89+
link_target, promiser, e
90+
)
91+
)
92+
return Result.NOT_KEPT
93+
94+
self.log_info(
95+
"Corrected symlink '{}' -> '{}'".format(promiser, link_target)
5696
)
57-
return (Result.NOT_KEPT, ["old_link"])
58-
except:
59-
self.log_error(
60-
"Couldn't symlink '{}' to '{}'".format(link_target, promiser)
61-
)
62-
return (Result.NOT_KEPT, ["unknown"])
63-
self.log_info("Created symlink '{}' -> '{}'".format(promiser, link_target))
64-
return (Result.REPAIRED, ["link_created"])
97+
return Result.REPAIRED
6598

66-
if not os.path.islink(promiser):
67-
self.log_error("Symlink '{}' is already a path".format(promiser))
68-
return (Result.NOT_KEPT, ["link_is_path"])
99+
return Result.KEPT
69100

70-
if os.path.realpath(promiser) != link_target:
71-
try:
72-
os.unlink(promiser)
73-
os.symlink(
74-
link_target, promiser, target_is_directory=bool(model.directory)
75-
)
76-
except FileExistsError:
77-
self.log_error(
78-
"Couldn't symlink '{}' to '{}'. A link already exists".format(
79-
link_target, promiser
80-
)
81-
)
82-
return (Result.NOT_KEPT, ["old_link"])
83-
except:
84-
self.log_error(
85-
"Couldn't symlink '{}' to '{}'".format(link_target, promiser)
86-
)
87-
return (Result.NOT_KEPT, ["unknown"])
88-
self.log_info(
89-
"Symlink '{}' had wrong target. Updated from '{}' to '{}'".format(
90-
promiser, os.path.realpath(promiser), link_target
91-
)
92-
)
93-
return (Result.REPAIRED, ["changed_target"])
101+
except FileNotFoundError:
102+
self.log_error("'{}' doesn't exist".format(promiser))
103+
return Result.NOT_KEPT
94104

95-
return (Result.KEPT, ["already_existing_link"])
105+
except Exception as e:
106+
self.log_error(
107+
"Couldn't symlink '{}' to '{}': {}".format(link_target, promiser, e)
108+
)
109+
return Result.NOT_KEPT
96110

97111

98112
if __name__ == "__main__":

promise-types/symlinks/test.cf

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ promise agent symlinks
3030
interpreter => "/usr/bin/python3";
3131
}
3232

33+
body classes outcome(arg)
34+
{
35+
promise_kept => { "$(arg)_kept" };
36+
promise_repaired => { "$(arg)_repaired" };
37+
}
38+
3339
bundle agent test
3440
{
3541
meta:
@@ -38,13 +44,18 @@ bundle agent test
3844

3945
symlinks:
4046
"/tmp/file-link"
41-
file => "/tmp/my-file";
47+
file => "/tmp/my-file",
48+
classes => outcome("created_file");
4249
"/tmp/dir-link"
43-
directory => "/tmp/my-dir";
50+
directory => "/tmp/my-dir",
51+
classes => outcome("created_dir");
4452
"/tmp/replaced-link"
45-
directory => "/tmp/my-dir";
53+
directory => "/tmp/my-dir",
54+
classes => outcome("corrected");
4655
"/tmp/already-existing-link"
47-
directory => "/tmp/other-dir";
56+
directory => "/tmp/other-dir",
57+
classes => outcome("didnothing");
58+
4859
}
4960

5061
#######################################################
@@ -68,14 +79,19 @@ bundle agent check
6879
strcmp("$(my_file_stat)", "/tmp/my-file"),
6980
strcmp("$(my_dir_stat)", "/tmp/my-dir"),
7081
strcmp("$(replaced_link_stat)", "/tmp/my-dir"),
71-
strcmp("$(already_existing_link_stat)", "/tmp/other-dir")
82+
strcmp("$(already_existing_link_stat)", "/tmp/other-dir"),
83+
"created_file_repaired",
84+
"created_dir_repaired",
85+
"corrected_repaired",
86+
"didnothing_kept"
7287
);
7388

7489
reports:
7590
ok::
7691
"$(this.promise_filename) Pass";
7792
!ok::
7893
"$(this.promise_filename) FAIL";
94+
7995
}
8096

8197
# #######################################################

0 commit comments

Comments
 (0)