|
1 | 1 | // SPDX-License-Identifier: Apache-2.0
|
2 |
| -// Copyright (C) 2023 The Falco Authors |
| 2 | +// Copyright (C) 2025 The Falco Authors |
3 | 3 | //
|
4 | 4 | // Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | // you may not use this file except in compliance with the License.
|
@@ -203,52 +203,83 @@ func (f *Follower) follow(ctx context.Context) {
|
203 | 203 | return
|
204 | 204 | }
|
205 | 205 |
|
| 206 | + // Move files to their destination |
| 207 | + if err := f.moveFiles(filePaths, dstDir); err != nil { |
| 208 | + return |
| 209 | + } |
| 210 | + |
| 211 | + f.logger.Info("Artifact correctly installed", |
| 212 | + f.logger.Args("followerName", f.ref, "artifactName", f.ref, "type", res.Type, "digest", res.Digest, "directory", dstDir)) |
| 213 | + f.currentDigest = desc.Digest.String() |
| 214 | +} |
| 215 | + |
| 216 | +// moveFiles moves files from their temporary location to the destination directory. |
| 217 | +// It preserves the directory structure relative to the temporary directory. |
| 218 | +// For example, if a file is at "tmpDir/subdir/file.yaml", it will be moved to |
| 219 | +// "dstDir/subdir/file.yaml". This ensures that files in subdirectories are moved |
| 220 | +// correctly as individual files, not as entire directories. |
| 221 | +func (f *Follower) moveFiles(filePaths []string, dstDir string) error { |
206 | 222 | // Install the artifacts if necessary.
|
207 | 223 | for _, path := range filePaths {
|
208 |
| - baseName := filepath.Base(path) |
209 |
| - f.logger.Debug("Installing file", f.logger.Args("followerName", f.ref, "fileName", baseName)) |
210 |
| - dstPath := filepath.Join(dstDir, baseName) |
| 224 | + // Get the relative path from the temporary directory to preserve directory structure |
| 225 | + relPath, err := filepath.Rel(f.tmpDir, path) |
| 226 | + if err != nil { |
| 227 | + f.logger.Error("Unable to get relative path", f.logger.Args("followerName", f.ref, "path", path, "reason", err.Error())) |
| 228 | + return err |
| 229 | + } |
| 230 | + |
| 231 | + dstPath := filepath.Join(dstDir, relPath) |
| 232 | + // Ensure the parent directory exists |
| 233 | + if err := os.MkdirAll(filepath.Dir(dstPath), 0o750); err != nil { |
| 234 | + f.logger.Error("Unable to create destination directory", f.logger.Args( |
| 235 | + "followerName", f.ref, |
| 236 | + "directory", filepath.Dir(dstPath), |
| 237 | + "reason", err.Error(), |
| 238 | + )) |
| 239 | + return err |
| 240 | + } |
| 241 | + |
| 242 | + f.logger.Debug("Installing file", f.logger.Args("followerName", f.ref, "path", relPath)) |
211 | 243 | // Check if the file exists.
|
212 |
| - f.logger.Debug("Checking if file already exists", f.logger.Args("followerName", f.ref, "fileName", baseName, "directory", dstDir)) |
| 244 | + f.logger.Debug("Checking if file already exists", f.logger.Args("followerName", f.ref, "path", relPath, "directory", dstDir)) |
213 | 245 | exists, err := utils.FileExists(dstPath)
|
214 | 246 | if err != nil {
|
215 |
| - f.logger.Error("Unable to check existence for file", f.logger.Args("followerName", f.ref, "fileName", baseName, "reason", err.Error())) |
216 |
| - return |
| 247 | + f.logger.Error("Unable to check existence for file", f.logger.Args("followerName", f.ref, "path", relPath, "reason", err.Error())) |
| 248 | + return err |
217 | 249 | }
|
218 | 250 |
|
219 | 251 | if !exists {
|
220 |
| - f.logger.Debug("Moving file", f.logger.Args("followerName", f.ref, "fileName", baseName, "destDirectory", dstDir)) |
| 252 | + f.logger.Debug("Moving file", f.logger.Args("followerName", f.ref, "path", relPath, "destDirectory", dstDir)) |
221 | 253 | if err = utils.Move(path, dstPath); err != nil {
|
222 |
| - f.logger.Error("Unable to move file", f.logger.Args("followerName", f.ref, "fileName", baseName, "destDirectory", dstDir, "reason", err.Error())) |
223 |
| - return |
| 254 | + f.logger.Error("Unable to move file", f.logger.Args("followerName", f.ref, "path", relPath, "destDirectory", dstDir, "reason", err.Error())) |
| 255 | + return err |
224 | 256 | }
|
225 | 257 | f.logger.Debug("File correctly installed", f.logger.Args("followerName", f.ref, "path", path))
|
226 | 258 | // It's done, move to the next file.
|
227 | 259 | continue
|
228 | 260 | }
|
229 |
| - f.logger.Debug(fmt.Sprintf("file %q already exists in %q, checking if it is equal to the existing one", baseName, dstDir), |
| 261 | + |
| 262 | + f.logger.Debug(fmt.Sprintf("file %q already exists in %q, checking if it is equal to the existing one", relPath, dstDir), |
230 | 263 | f.logger.Args("followerName", f.ref))
|
| 264 | + |
231 | 265 | // Check if the files are equal.
|
232 | 266 | eq, err := equal([]string{path, dstPath})
|
233 | 267 | if err != nil {
|
234 |
| - f.logger.Error("Unable to compare files", f.logger.Args("followerName", f.ref, "newFile", path, "existingFile", dstPath, "reason", err.Error())) |
235 |
| - return |
| 268 | + f.logger.Error("Unable to compare files", f.logger.Args("followerName", f.ref, "existingFile", dstPath, "reason", err.Error())) |
| 269 | + return err |
236 | 270 | }
|
237 | 271 |
|
238 | 272 | if !eq {
|
239 | 273 | f.logger.Debug(fmt.Sprintf("Overwriting file %q with file %q", dstPath, path), f.logger.Args("followerName", f.ref))
|
240 | 274 | if err = utils.Move(path, dstPath); err != nil {
|
241 | 275 | f.logger.Error("Unable to overwrite file", f.logger.Args("followerName", f.ref, "existingFile", dstPath, "reason", err.Error()))
|
242 |
| - return |
| 276 | + return err |
243 | 277 | }
|
244 | 278 | } else {
|
245 | 279 | f.logger.Debug("The two file are equal, nothing to be done")
|
246 | 280 | }
|
247 | 281 | }
|
248 |
| - |
249 |
| - f.logger.Info("Artifact correctly installed", |
250 |
| - f.logger.Args("followerName", f.ref, "artifactName", f.ref, "type", res.Type, "digest", res.Digest, "directory", dstDir)) |
251 |
| - f.currentDigest = desc.Digest.String() |
| 282 | + return nil |
252 | 283 | }
|
253 | 284 |
|
254 | 285 | // pull downloads, extracts, and installs the artifact.
|
|
0 commit comments