Skip to content

Commit

Permalink
NAS-132920 / 24.10.2 / New cloud backup option: absolute_paths (by …
Browse files Browse the repository at this point in the history
…AlexKarpov98) (#11168)

* Empty commit to create PR on github.

You should reset it

* NAS-132920: PR Update

---------

Co-authored-by: Alex Karpov <[email protected]>
  • Loading branch information
bugclerk and AlexKarpov98 authored Dec 13, 2024
1 parent 0d8c575 commit 41a20f6
Show file tree
Hide file tree
Showing 92 changed files with 275 additions and 55 deletions.
3 changes: 3 additions & 0 deletions src/app/helptext/data-protection/cloud-backup/cloud-backup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export const helptextCloudBackup = {
snapshot_placeholder: T('Take Snapshot'),
snapshot_tooltip: T('Set to take a snapshot of the dataset before a <i>PUSH</i>.'),

absolute_paths_placeholder: T('Use Absolute Paths'),
absolute_paths_tooltip: T('Determines whether restic backup will contain absolute or relative paths'),

transfers_placeholder: T('Transfers'),
transfers_tooltip: T('Number of simultaneous file transfers. Enter a\
number based on the available bandwidth and destination system\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@
[label]="helptext.snapshot_placeholder | translate"
[tooltip]="helptext.snapshot_tooltip | translate"
></ix-checkbox>
<ix-checkbox
formControlName="absolute_paths"
[label]="helptext.absolute_paths_placeholder | translate"
[tooltip]="helptext.absolute_paths_tooltip | translate"
></ix-checkbox>
<ix-textarea
formControlName="pre_script"
[label]="helptext.pre_script_placeholder | translate"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ describe('CloudBackupFormComponent', () => {
pre_script: '',
post_script: '',
snapshot: false,
absolute_paths: true,
include: [],
exclude: [],
transfer_setting: CloudsyncTransferSetting.Performance,
Expand Down Expand Up @@ -127,6 +128,22 @@ describe('CloudBackupFormComponent', () => {
loader = TestbedHarnessEnvironment.loader(spectator.fixture);
});

it('disables absolute paths when snapshot is enabled and resets to false', async () => {
const form = await loader.getHarness(IxFormHarness);
await form.fillForm({
'Use Absolute Paths': true,
});

await form.fillForm({
'Take Snapshot': true,
});

const useAbsolutePathsControl = await form.getControl('Use Absolute Paths');

expect(await useAbsolutePathsControl.isDisabled()).toBe(true);
expect(await useAbsolutePathsControl.getValue()).toBe(false);
});

it('adds a new cloud backup task and creates a new bucket', async () => {
const form = await loader.getHarness(IxFormHarness);
await form.fillForm({
Expand Down Expand Up @@ -169,13 +186,15 @@ describe('CloudBackupFormComponent', () => {
month: '*',
},
snapshot: false,
absolute_paths: false,
transfer_setting: CloudsyncTransferSetting.Default,
}]);
expect(chainedComponentRef.close).toHaveBeenCalledWith({ response: existingTask, error: null });
});

it('adds a new cloud backup task when new form is saved', async () => {
const form = await loader.getHarness(IxFormHarness);

await form.fillForm({
'Source Path': '/mnt/my pool 2',
Name: 'New Cloud Backup Task',
Expand All @@ -185,7 +204,8 @@ describe('CloudBackupFormComponent', () => {
Folder: '/',
Enabled: false,
Bucket: 'bucket1',
'Take Snapshot': true,
'Take Snapshot': false,
'Use Absolute Paths': true,
Exclude: ['/test'],
'Transfer Setting': 'Fast Storage',
});
Expand Down Expand Up @@ -213,7 +233,8 @@ describe('CloudBackupFormComponent', () => {
minute: '0',
month: '*',
},
snapshot: true,
snapshot: false,
absolute_paths: true,
transfer_setting: CloudsyncTransferSetting.FastStorage,
}]);
expect(chainedComponentRef.close).toHaveBeenCalledWith({ response: existingTask, error: null });
Expand Down Expand Up @@ -249,6 +270,7 @@ describe('CloudBackupFormComponent', () => {
Schedule: 'Weekly (0 0 * * sun)  On Sundays at 00:00 (12:00 AM)',
'Source Path': '/mnt/my pool',
'Take Snapshot': false,
'Use Absolute Paths': true,
'Transfer Setting': 'Performance',
});
});
Expand All @@ -262,6 +284,11 @@ describe('CloudBackupFormComponent', () => {
'Source Path': '/mnt/path1',
});

const useAbsolutePathsControl = await form.getControl('Use Absolute Paths');

expect(await useAbsolutePathsControl.isDisabled()).toBe(true);
expect(await useAbsolutePathsControl.getValue()).toBe(true);

const saveButton = await loader.getHarness(MatButtonHarness.with({ text: 'Save' }));
await saveButton.click();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export class CloudBackupFormComponent implements OnInit {
post_script: [''],
description: ['', [Validators.required]],
snapshot: [false],
absolute_paths: [false],
transfer_setting: [CloudsyncTransferSetting.Default],
args: [''],
enabled: [true],
Expand Down Expand Up @@ -117,49 +118,15 @@ export class CloudBackupFormComponent implements OnInit {
this.setFileNodeProvider();
this.setBucketNodeProvider();

this.form.controls.credentials.valueChanges
.pipe(untilDestroyed(this))
.subscribe((credentialId) => {
if (credentialId !== this.editingTask?.credentials?.id) {
this.form.controls.bucket.patchValue('');
}

this.form.controls.bucket_input.disable();

if (credentialId) {
this.form.controls.folder.enable();
this.form.controls.bucket.enable();
this.loadBucketOptions(credentialId);
} else {
this.form.controls.folder.disable();
this.form.controls.bucket.disable();
}
});

this.form.controls.bucket.valueChanges
.pipe(untilDestroyed(this))
.subscribe((value) => {
if (value === newOption) {
this.form.controls.bucket_input.patchValue('');
this.form.controls.bucket_input.enable();
} else {
this.form.controls.bucket_input.disable();
}
this.setBucketNodeProvider();
});

this.form.controls.bucket_input.valueChanges
.pipe(
debounceTime(300),
distinctUntilChanged(),
untilDestroyed(this),
)
.subscribe(() => {
this.setBucketNodeProvider();
});
this.listenForCredentialsChanges();
this.listenForBucketChanges();
this.listenForBucketInputChanges();

if (this.editingTask) {
this.setTaskForEdit();
this.form.controls.absolute_paths.disable();
} else {
this.listenForTakeSnapshotChanges();
}
}

Expand All @@ -181,7 +148,8 @@ export class CloudBackupFormComponent implements OnInit {
this.form.controls.bucket_input.disable();
this.cdr.markForCheck();
},
error: () => {
error: (error: unknown) => {
console.error(error);
this.isLoading = false;
this.bucketOptions$ = of([this.newBucketOption]);
this.cdr.markForCheck();
Expand Down Expand Up @@ -280,6 +248,66 @@ export class CloudBackupFormComponent implements OnInit {
});
}

private listenForCredentialsChanges(): void {
this.form.controls.credentials.valueChanges
.pipe(untilDestroyed(this))
.subscribe((credentialId) => {
if (credentialId !== this.editingTask?.credentials?.id) {
this.form.controls.bucket.patchValue('');
}

this.form.controls.bucket_input.disable();

if (credentialId) {
this.form.controls.folder.enable();
this.form.controls.bucket.enable();
this.loadBucketOptions(credentialId);
} else {
this.form.controls.folder.disable();
this.form.controls.bucket.disable();
}
});
}

private listenForBucketChanges(): void {
this.form.controls.bucket.valueChanges
.pipe(untilDestroyed(this))
.subscribe((value) => {
if (value === newOption) {
this.form.controls.bucket_input.patchValue('');
this.form.controls.bucket_input.enable();
} else {
this.form.controls.bucket_input.disable();
}
this.setBucketNodeProvider();
});
}

private listenForBucketInputChanges(): void {
this.form.controls.bucket_input.valueChanges
.pipe(
debounceTime(300),
distinctUntilChanged(),
untilDestroyed(this),
)
.subscribe(() => {
this.setBucketNodeProvider();
});
}

private listenForTakeSnapshotChanges(): void {
this.form.controls.snapshot.valueChanges
.pipe(untilDestroyed(this))
.subscribe((takeSnapshot) => {
if (takeSnapshot) {
this.form.controls.absolute_paths.setValue(false);
this.form.controls.absolute_paths.disable();
} else {
this.form.controls.absolute_paths.enable();
}
});
}

private prepareData(formValue: FormValue): CloudBackupUpdate {
const attributes: CloudBackupUpdate['attributes'] = {
folder: formValue.folder,
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/af.json
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@
"Determine how <a href=\"https://man7.org/linux/man-pages/man1/chmod.1.html\" target=\"_blank\">chmod</a> behaves when adjusting file ACLs. See the <a href=\"https://linux.die.net/man/8/zfs\" target=\"_blank\">zfs(8)</a> aclmode property. <br><br><i>Passthrough</i> only updates ACL entries that are related to the file or directory mode. <br><br><i>Restricted</i> does not allow chmod to make changes to files or directories with a non-trivial ACL. An ACL is trivial if it can be fully expressed as a file mode without losing any access rules. Setting the ACL Mode to Restricted is typically used to optimize a dataset for SMB sharing, but can require further optimizations. For example, configuring an rsync task with this dataset could require adding <i>--no-perms</i> in the task <i>Auxiliary Parameters</i> field.": "",
"Determine whether this share name is included when browsing shares. Home shares are only visible to the owner regardless of this setting.": "",
"Determines the outgoing and incoming traffic ports.<br> <i>LACP</i> is the recommended protocol if the network switch is capable of active LACP.<br><i>Failover</i> is the default protocol choice and should only be used if the network switch does not support active LACP.": "",
"Determines whether restic backup will contain absolute or relative paths": "",
"Device": "",
"Device Attached": "",
"Device Busy": "",
Expand Down Expand Up @@ -4657,6 +4658,7 @@
"Usage collection": "",
"Usages": "",
"Use --fast-list": "",
"Use Absolute Paths": "",
"Use Apple-style Character Encoding": "",
"Use Custom ACME Server Directory URI": "",
"Use DHCP. Unset to manually configure a static IPv4 connection.": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@
"Determine how <a href=\"https://man7.org/linux/man-pages/man1/chmod.1.html\" target=\"_blank\">chmod</a> behaves when adjusting file ACLs. See the <a href=\"https://linux.die.net/man/8/zfs\" target=\"_blank\">zfs(8)</a> aclmode property. <br><br><i>Passthrough</i> only updates ACL entries that are related to the file or directory mode. <br><br><i>Restricted</i> does not allow chmod to make changes to files or directories with a non-trivial ACL. An ACL is trivial if it can be fully expressed as a file mode without losing any access rules. Setting the ACL Mode to Restricted is typically used to optimize a dataset for SMB sharing, but can require further optimizations. For example, configuring an rsync task with this dataset could require adding <i>--no-perms</i> in the task <i>Auxiliary Parameters</i> field.": "",
"Determine whether this share name is included when browsing shares. Home shares are only visible to the owner regardless of this setting.": "",
"Determines the outgoing and incoming traffic ports.<br> <i>LACP</i> is the recommended protocol if the network switch is capable of active LACP.<br><i>Failover</i> is the default protocol choice and should only be used if the network switch does not support active LACP.": "",
"Determines whether restic backup will contain absolute or relative paths": "",
"Device": "",
"Device Attached": "",
"Device Busy": "",
Expand Down Expand Up @@ -4657,6 +4658,7 @@
"Usage collection": "",
"Usages": "",
"Use --fast-list": "",
"Use Absolute Paths": "",
"Use Apple-style Character Encoding": "",
"Use Custom ACME Server Directory URI": "",
"Use DHCP. Unset to manually configure a static IPv4 connection.": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/ast.json
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@
"Determine how <a href=\"https://man7.org/linux/man-pages/man1/chmod.1.html\" target=\"_blank\">chmod</a> behaves when adjusting file ACLs. See the <a href=\"https://linux.die.net/man/8/zfs\" target=\"_blank\">zfs(8)</a> aclmode property. <br><br><i>Passthrough</i> only updates ACL entries that are related to the file or directory mode. <br><br><i>Restricted</i> does not allow chmod to make changes to files or directories with a non-trivial ACL. An ACL is trivial if it can be fully expressed as a file mode without losing any access rules. Setting the ACL Mode to Restricted is typically used to optimize a dataset for SMB sharing, but can require further optimizations. For example, configuring an rsync task with this dataset could require adding <i>--no-perms</i> in the task <i>Auxiliary Parameters</i> field.": "",
"Determine whether this share name is included when browsing shares. Home shares are only visible to the owner regardless of this setting.": "",
"Determines the outgoing and incoming traffic ports.<br> <i>LACP</i> is the recommended protocol if the network switch is capable of active LACP.<br><i>Failover</i> is the default protocol choice and should only be used if the network switch does not support active LACP.": "",
"Determines whether restic backup will contain absolute or relative paths": "",
"Device": "",
"Device Attached": "",
"Device Busy": "",
Expand Down Expand Up @@ -4657,6 +4658,7 @@
"Usage collection": "",
"Usages": "",
"Use --fast-list": "",
"Use Absolute Paths": "",
"Use Apple-style Character Encoding": "",
"Use Custom ACME Server Directory URI": "",
"Use DHCP. Unset to manually configure a static IPv4 connection.": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/az.json
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@
"Determine how <a href=\"https://man7.org/linux/man-pages/man1/chmod.1.html\" target=\"_blank\">chmod</a> behaves when adjusting file ACLs. See the <a href=\"https://linux.die.net/man/8/zfs\" target=\"_blank\">zfs(8)</a> aclmode property. <br><br><i>Passthrough</i> only updates ACL entries that are related to the file or directory mode. <br><br><i>Restricted</i> does not allow chmod to make changes to files or directories with a non-trivial ACL. An ACL is trivial if it can be fully expressed as a file mode without losing any access rules. Setting the ACL Mode to Restricted is typically used to optimize a dataset for SMB sharing, but can require further optimizations. For example, configuring an rsync task with this dataset could require adding <i>--no-perms</i> in the task <i>Auxiliary Parameters</i> field.": "",
"Determine whether this share name is included when browsing shares. Home shares are only visible to the owner regardless of this setting.": "",
"Determines the outgoing and incoming traffic ports.<br> <i>LACP</i> is the recommended protocol if the network switch is capable of active LACP.<br><i>Failover</i> is the default protocol choice and should only be used if the network switch does not support active LACP.": "",
"Determines whether restic backup will contain absolute or relative paths": "",
"Device": "",
"Device Attached": "",
"Device Busy": "",
Expand Down Expand Up @@ -4657,6 +4658,7 @@
"Usage collection": "",
"Usages": "",
"Use --fast-list": "",
"Use Absolute Paths": "",
"Use Apple-style Character Encoding": "",
"Use Custom ACME Server Directory URI": "",
"Use DHCP. Unset to manually configure a static IPv4 connection.": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/be.json
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@
"Determine how <a href=\"https://man7.org/linux/man-pages/man1/chmod.1.html\" target=\"_blank\">chmod</a> behaves when adjusting file ACLs. See the <a href=\"https://linux.die.net/man/8/zfs\" target=\"_blank\">zfs(8)</a> aclmode property. <br><br><i>Passthrough</i> only updates ACL entries that are related to the file or directory mode. <br><br><i>Restricted</i> does not allow chmod to make changes to files or directories with a non-trivial ACL. An ACL is trivial if it can be fully expressed as a file mode without losing any access rules. Setting the ACL Mode to Restricted is typically used to optimize a dataset for SMB sharing, but can require further optimizations. For example, configuring an rsync task with this dataset could require adding <i>--no-perms</i> in the task <i>Auxiliary Parameters</i> field.": "",
"Determine whether this share name is included when browsing shares. Home shares are only visible to the owner regardless of this setting.": "",
"Determines the outgoing and incoming traffic ports.<br> <i>LACP</i> is the recommended protocol if the network switch is capable of active LACP.<br><i>Failover</i> is the default protocol choice and should only be used if the network switch does not support active LACP.": "",
"Determines whether restic backup will contain absolute or relative paths": "",
"Device": "",
"Device Attached": "",
"Device Busy": "",
Expand Down Expand Up @@ -4657,6 +4658,7 @@
"Usage collection": "",
"Usages": "",
"Use --fast-list": "",
"Use Absolute Paths": "",
"Use Apple-style Character Encoding": "",
"Use Custom ACME Server Directory URI": "",
"Use DHCP. Unset to manually configure a static IPv4 connection.": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@
"Determine how <a href=\"https://man7.org/linux/man-pages/man1/chmod.1.html\" target=\"_blank\">chmod</a> behaves when adjusting file ACLs. See the <a href=\"https://linux.die.net/man/8/zfs\" target=\"_blank\">zfs(8)</a> aclmode property. <br><br><i>Passthrough</i> only updates ACL entries that are related to the file or directory mode. <br><br><i>Restricted</i> does not allow chmod to make changes to files or directories with a non-trivial ACL. An ACL is trivial if it can be fully expressed as a file mode without losing any access rules. Setting the ACL Mode to Restricted is typically used to optimize a dataset for SMB sharing, but can require further optimizations. For example, configuring an rsync task with this dataset could require adding <i>--no-perms</i> in the task <i>Auxiliary Parameters</i> field.": "",
"Determine whether this share name is included when browsing shares. Home shares are only visible to the owner regardless of this setting.": "",
"Determines the outgoing and incoming traffic ports.<br> <i>LACP</i> is the recommended protocol if the network switch is capable of active LACP.<br><i>Failover</i> is the default protocol choice and should only be used if the network switch does not support active LACP.": "",
"Determines whether restic backup will contain absolute or relative paths": "",
"Device": "",
"Device Attached": "",
"Device Busy": "",
Expand Down Expand Up @@ -4657,6 +4658,7 @@
"Usage collection": "",
"Usages": "",
"Use --fast-list": "",
"Use Absolute Paths": "",
"Use Apple-style Character Encoding": "",
"Use Custom ACME Server Directory URI": "",
"Use DHCP. Unset to manually configure a static IPv4 connection.": "",
Expand Down
Loading

0 comments on commit 41a20f6

Please sign in to comment.