Skip to content

Commit e9a8f71

Browse files
nickandersonQwen CodeGemini
committed
Added support for move_obstructions in files promises using the content attribute
Ticket: CFE-4591 Changelog: Title Co-authored-by: Qwen Code <qwen-code@alibaba.com> Co-authored-by: Gemini <gemini-copilot@google.com>
1 parent 7547f2e commit e9a8f71

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

cf-agent/verify_files.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,20 @@ static PromiseResult VerifyFilePromise(EvalContext *ctx, char *path, const Promi
587587
result = PromiseResultUpdate(result, ScheduleLinkOperation(ctx, path, a.link.source, &a, pp));
588588
}
589589

590+
if (a.haveedit || a.content)
591+
{
592+
if (exists || link)
593+
{
594+
if (!HandleFileObstruction(ctx, changes_path, &oslb, &a, pp, &result))
595+
{
596+
goto exit;
597+
}
598+
// After moving, it no longer exists at the original path
599+
exists = (lstat(changes_path, &oslb) != -1);
600+
link = false;
601+
}
602+
}
603+
590604
/* Phase 3a - direct content */
591605

592606
if (a.content)

cf-agent/verify_files_utils.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2775,6 +2775,60 @@ static PromiseResult VerifyFileAttributes(EvalContext *ctx, const char *file, co
27752775
return result;
27762776
}
27772777

2778+
bool HandleFileObstruction(EvalContext *ctx, const char *path, const struct stat *sb, const Attributes *attr, const Promise *pp, PromiseResult *result)
2779+
{
2780+
if (!sb)
2781+
{
2782+
return true;
2783+
}
2784+
if (!attr)
2785+
{
2786+
return false;
2787+
}
2788+
2789+
// Use local variables to help static analysis tools understand that
2790+
// the pointers have been checked for NULL before dereferencing
2791+
const struct stat *const safe_sb = sb; // Explicit alias after null check
2792+
const Attributes *const safe_attr = attr; // Explicit alias after null check
2793+
2794+
const mode_t st_mode = safe_sb->st_mode;
2795+
const bool move_obstructions = safe_attr->move_obstructions;
2796+
2797+
// If path exists, but is not a regular file, it's an obstruction
2798+
if (!S_ISREG(st_mode))
2799+
{
2800+
if (move_obstructions)
2801+
{
2802+
if (MakingChanges(ctx, pp, safe_attr, result, "move obstruction '%s'", path))
2803+
{
2804+
char backup[CF_BUFSIZE];
2805+
snprintf(backup, sizeof(backup), "%s.cf-moved", path);
2806+
2807+
if (rename(path, backup) == -1)
2808+
{
2809+
RecordFailure(ctx, pp, safe_attr, "Could not move obstruction '%s' to '%s'. (rename: %s)",
2810+
path, backup, GetErrorStr());
2811+
*result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
2812+
return false;
2813+
}
2814+
else
2815+
{
2816+
RecordChange(ctx, pp, safe_attr, "Moved obstructing path '%s' to '%s'", path, backup);
2817+
*result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE);
2818+
return true;
2819+
}
2820+
}
2821+
}
2822+
else if (!S_ISLNK(st_mode))
2823+
{
2824+
RecordFailure(ctx, pp, safe_attr, "Path '%s' is not a regular file and move_obstructions is not set", path);
2825+
*result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
2826+
return false;
2827+
}
2828+
}
2829+
return true;
2830+
}
2831+
27782832
bool DepthSearch(EvalContext *ctx, char *name, const struct stat *sb, int rlevel, const Attributes *attr,
27792833
const Promise *pp, dev_t rootdevice, PromiseResult *result)
27802834
{
@@ -2798,7 +2852,7 @@ bool DepthSearch(EvalContext *ctx, char *name, const struct stat *sb, int rlevel
27982852
{
27992853
Log(LOG_LEVEL_ERR, "Failed to chdir into '%s'. (chdir: '%s')", basedir, GetErrorStr());
28002854
return false;
2801-
}
2855+
}
28022856
if (!attr->haveselect || SelectLeaf(ctx, name, sb, &(attr->select)))
28032857
{
28042858
/* Renames are handled separately. */

cf-agent/verify_files_utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ extern StringSet *SINGLE_COPY_CACHE;
3434

3535
void SetFileAutoDefineList(const Rlist *auto_define_list);
3636

37+
3738
void VerifyFileLeaf(EvalContext *ctx, char *path, const struct stat *sb, const Attributes *attr, const Promise *pp, PromiseResult *result);
39+
bool HandleFileObstruction(EvalContext *ctx, const char *path, const struct stat *sb, const Attributes *attr, const Promise *pp, PromiseResult *result);
3840
bool DepthSearch(EvalContext *ctx, char *name, const struct stat *sb, int rlevel, const Attributes *attr, const Promise *pp, dev_t rootdevice, PromiseResult *result);
3941
bool CfCreateFile(EvalContext *ctx, char *file, const Promise *pp, const Attributes *attr, PromiseResult *result_out);
4042
void SetSearchDevice(struct stat *sb, const Promise *pp);

0 commit comments

Comments
 (0)