Skip to content

Commit 81b2208

Browse files
committed
Implement "before-copy" and "after-copy" in retention section
1 parent a7ddb09 commit 81b2208

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

config/profile.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ type RetentionSection struct {
237237
OtherFlagsSection `mapstructure:",squash"`
238238
BeforeBackup maybe.Bool `mapstructure:"before-backup" description:"Apply retention before starting the backup command"`
239239
AfterBackup maybe.Bool `mapstructure:"after-backup" description:"Apply retention after the backup command succeeded. Defaults to true in configuration format v2 if any \"keep-*\" flag is set and \"before-backup\" is unset"`
240+
BeforeCopy maybe.Bool `mapstructure:"before-copy" description:"Apply retention before starting the copy command"`
241+
AfterCopy maybe.Bool `mapstructure:"after-copy" description:"Apply retention after the copy command succeeded. Defaults to true in configuration format v2 if any \"keep-*\" flag is set and \"before-backup\" is unset"`
240242
}
241243

242244
func (r *RetentionSection) IsEmpty() bool { return r == nil }
@@ -246,20 +248,27 @@ func (r *RetentionSection) resolve(profile *Profile) {
246248

247249
// Special cases of retention
248250
isSet := func(flags OtherFlags, name string) (found bool) { _, found = flags.GetOtherFlags()[name]; return }
249-
hasBackup := !profile.Backup.IsEmpty()
251+
hasBackup := !profile.Backup.IsEmpty() && (r.BeforeBackup.IsTrue() || r.AfterBackup.IsTrue())
252+
hasCopy := !profile.Copy.IsEmpty() && (r.BeforeCopy.IsTrue() || r.AfterCopy.IsTrue())
250253

251254
// Copy "source" from "backup" as "path" if it hasn't been redefined
252255
if hasBackup && !isSet(r, constants.ParameterPath) {
253256
r.SetOtherFlag(constants.ParameterPath, true)
254257
}
255258

259+
// Copy "source" from "backup" as "path" if it hasn't been redefined
260+
if hasCopy && !isSet(r, constants.ParameterPath) {
261+
r.SetOtherFlag(constants.ParameterPath, true)
262+
}
263+
256264
// Extras, only enabled for Version >= 2 (to remain backward compatible in version 1)
257265
if profile.config != nil && profile.config.version >= Version02 {
258266
// Auto-enable "after-backup" if nothing was specified explicitly and any "keep-" was configured
259-
if r.AfterBackup.IsUndefined() && r.BeforeBackup.IsUndefined() {
267+
if r.AfterBackup.IsUndefined() && r.BeforeBackup.IsUndefined() && r.AfterCopy.IsUndefined() && r.BeforeCopy.IsUndefined() {
260268
for name := range r.OtherFlags {
261269
if strings.HasPrefix(name, "keep-") {
262270
r.AfterBackup = maybe.True()
271+
hasBackup = true
263272
break
264273
}
265274
}
@@ -274,12 +283,23 @@ func (r *RetentionSection) resolve(profile *Profile) {
274283
r.SetOtherFlag(constants.ParameterTag, true)
275284
}
276285

286+
// Copy "tag" from "copy" if it was set and hasn't been redefined here
287+
// Allow setting it at profile level when not defined in "backup" nor "retention"
288+
if hasCopy &&
289+
!isSet(r, constants.ParameterTag) &&
290+
isSet(profile.Copy, constants.ParameterTag) {
291+
292+
r.SetOtherFlag(constants.ParameterTag, true)
293+
}
294+
277295
// Copy "host" from "backup" if it was set and hasn't been redefined here
278296
// Or use os.Hostname() same as restic does for backup when not setting it, see:
279297
// https://github.com/restic/restic/blob/master/cmd/restic/cmd_backup.go#L48
280298
if !isSet(r, constants.ParameterHost) {
281299
if hasBackup && isSet(profile.Backup, constants.ParameterHost) {
282300
r.SetOtherFlag(constants.ParameterHost, profile.Backup.OtherFlags[constants.ParameterHost])
301+
} else if hasCopy && isSet(profile.Copy, constants.ParameterHost) {
302+
r.SetOtherFlag(constants.ParameterHost, profile.Copy.OtherFlags[constants.ParameterHost])
283303
} else if !isSet(profile, constants.ParameterHost) {
284304
r.SetOtherFlag(constants.ParameterHost, true) // resolved with os.Hostname()
285305
}

wrapper.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,34 @@ func (r *resticWrapper) getCommandAction(command string) func() error {
141141
func (r *resticWrapper) getCopyAction() func() error {
142142
copyAction := r.getCommandAction(constants.CommandCopy)
143143

144-
return func() error {
144+
return func() (err error) {
145145
// we might need to initialize the secondary repository (the copy target)
146146
if r.global.Initialize || (r.profile.Copy != nil && r.profile.Copy.Initialize) {
147147
_ = r.runInitializeCopy() // it's ok if the initialization returned an error
148148
}
149149

150-
return copyAction()
150+
// Retention before
151+
if r.profile.Retention != nil && r.profile.Retention.BeforeCopy.IsTrue() {
152+
err = r.runRetention()
153+
if err != nil {
154+
return
155+
}
156+
}
157+
158+
err = copyAction()
159+
if err != nil {
160+
return
161+
}
162+
163+
// Retention after
164+
if r.profile.Retention != nil && r.profile.Retention.AfterCopy.IsTrue() {
165+
err = r.runRetention()
166+
if err != nil {
167+
return
168+
}
169+
}
170+
171+
return
151172
}
152173
}
153174

0 commit comments

Comments
 (0)