Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 29 additions & 34 deletions cf-agent/simulate_mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,9 @@ static inline void ManifestFileDetails(const char *path, struct stat *st, bool c
}
}

bool ManifestFile(const char *path, bool chrooted)
/* st_orig, if not NULL, is the original file, to report a change of type. */
static bool ManifestFileInternal(const char *path, bool chrooted,
const struct stat *st_orig)
{
PrintDelimiter();
const char *real_path = path;
Expand All @@ -348,7 +350,17 @@ bool ManifestFile(const char *path, bool chrooted)
return true;
}

printf("'%s' is a %s\n", path, GetFileTypeDescription(st.st_mode));
if ((st_orig != NULL) &&
((st_orig->st_mode & S_IFMT) != (st.st_mode & S_IFMT)))
{
printf("'%s' changed type from %s to %s\n", path,
GetFileTypeDescription(st_orig->st_mode),
GetFileTypeDescription(st.st_mode));
}
else
{
printf("'%s' is a %s\n", path, GetFileTypeDescription(st.st_mode));
}
ManifestStatInfo(&st);
ManifestFileDetails(real_path, &st, chrooted);

Expand All @@ -362,6 +374,11 @@ bool ManifestRename(const char *orig_name, const char *new_name)
return true;
}

bool ManifestFile(const char *path, bool chrooted)
{
return ManifestFileInternal(path, chrooted, NULL);
}

static bool RunDiff(const char *path1, const char *path2)
{
char diff_path[PATH_MAX];
Expand Down Expand Up @@ -490,10 +507,7 @@ static void DiffStatInfo(const char *path, const struct stat *st_orig, const str

static bool DiffFile(const char *path)
{
const char *chrooted_path = ToChangesChroot(path);

struct stat st_orig;
struct stat st_chrooted;
if (lstat(path, &st_orig) == -1)
{
/* Original final doesn't exist, must be a new file in the changes
Expand All @@ -502,38 +516,19 @@ static bool DiffFile(const char *path)
return true;
}

PrintDelimiter();
if (lstat(chrooted_path, &st_chrooted) == -1)
const char *chrooted_path = ToChangesChroot(path);
struct stat st_chrooted;
if ((lstat(chrooted_path, &st_chrooted) == 0) &&
((st_orig.st_mode & S_IFMT) == (st_chrooted.st_mode & S_IFMT)) &&
(S_ISREG(st_chrooted.st_mode) || S_ISDIR(st_chrooted.st_mode)))
{
/* TODO: should this do print info about the original file? */
printf("'%s' no longer exists\n", path);
return true;
PrintDelimiter();
DiffStatInfo(path, &st_orig, &st_chrooted);
return RunDiff(path, chrooted_path);
}

if ((st_orig.st_mode & S_IFMT) != (st_chrooted.st_mode & S_IFMT))
{
/* File type changed. */
printf("'%s' changed type from %s to %s\n", path,
GetFileTypeDescription(st_orig.st_mode),
GetFileTypeDescription(st_chrooted.st_mode));
ManifestStatInfo(&st_chrooted);
ManifestFileDetails(path, &st_chrooted, true);
return true;
}
else
{
switch (st_chrooted.st_mode & S_IFMT) {
case S_IFREG:
case S_IFDIR:
DiffStatInfo(path, &st_orig, &st_chrooted);
return RunDiff(path, chrooted_path);
default:
printf("'%s' is a %s\n", path, GetFileTypeDescription(st_chrooted.st_mode));
ManifestStatInfo(&st_chrooted);
ManifestFileDetails(path, &st_chrooted, true);
return true;
}
}
/* Gone, changed type, or not something 'diff' can compare. */
return ManifestFileInternal(path, true, &st_orig);
}

bool ManifestRenamedFiles()
Expand Down
60 changes: 60 additions & 0 deletions tests/acceptance/29_simulate_mode/diff_mode_symlinks.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
body common control
{
inputs => { "../default.sub.cf" };
bundlesequence => { default("$(this.promise_filename)") };
version => "1.0";
}

bundle agent init
{
files:
"$(G.testroot)/target-old" create => "true";
"$(G.testroot)/target-new" create => "true";

"$(G.testroot)/wrong-target"
link_from => linkfrom("$(G.testroot)/target-old", "symlink");

"$(G.testroot)/obstruction"
create => "true",
content => "I am in the way";
}

bundle agent test
{
meta:
"test_soft_fail"
string => "(solaris|aix|hpux|windows)",
# ENT-6540 exotics fail to delete chroot
# ENT-10254 tests fail on Windows due to CRLF
meta => { "ENT-6540", "ENT-10254" };

"description" -> { "ENT-14713" }
string => "Test that --simulate=diff shows the new target of a symlink that replaced a wrong link or an obstructing file";
}

bundle agent check
{
vars:
"command"
string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub --simulate=diff";

"new_target" string => "\QTarget: '$(G.testroot)/target-new'\E";

# Bound the gap to one file's section (6 output lines today, +1 slack)
"same_section" string => "\n(?:[^\n]*\n){0,7}";

"wanted"
string => concat(
".*\Q'$(G.testroot)/wrong-target' is a symbolic link\E$(same_section)$(new_target)",
".*\Q'$(G.testroot)/obstruction' changed type from regular file to symbolic link\E$(same_section)$(new_target).*"
);

methods:
"check"
usebundle => dcs_passif_output(
$(wanted),
".*(Invalid target|Target: '[^/]).*",
$(command),
$(this.promise_filename)
);
}
15 changes: 15 additions & 0 deletions tests/acceptance/29_simulate_mode/diff_mode_symlinks.cf.sub
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
body common control
{
inputs => { "../default.sub.cf" };
}

bundle agent main
{
files:
"$(G.testroot)/wrong-target"
link_from => linkfrom("$(G.testroot)/target-new", "symlink"),
move_obstructions => "true";
"$(G.testroot)/obstruction"
link_from => linkfrom("$(G.testroot)/target-new", "symlink"),
move_obstructions => "true";
}
Loading