feat(backups): Implement restore backup strategy

pull/274/head
NaiJi ✨ 2023-08-07 09:23:48 -03:00
parent dce33b2d4c
commit 75b8a7b9ac
9 changed files with 129 additions and 18 deletions

View File

@ -81,9 +81,9 @@ mutation InitializeRepository($repository: InitializeRepositoryInput!) {
} }
} }
mutation RestoreBackup($snapshotId: String!) { mutation RestoreBackup($snapshotId: String!, $strategy: RestoreStrategy! = DOWNLOAD_VERIFY_OVERWRITE) {
backup { backup {
restoreBackup(snapshotId: $snapshotId) { restoreBackup(snapshotId: $snapshotId, strategy: $strategy) {
...basicMutationReturnFields ...basicMutationReturnFields
job { job {
...basicApiJobsFields ...basicApiJobsFields

View File

@ -4982,9 +4982,13 @@ class _CopyWithStubImpl$Mutation$InitializeRepository$backup<TRes>
} }
class Variables$Mutation$RestoreBackup { class Variables$Mutation$RestoreBackup {
factory Variables$Mutation$RestoreBackup({required String snapshotId}) => factory Variables$Mutation$RestoreBackup({
required String snapshotId,
required Enum$RestoreStrategy strategy,
}) =>
Variables$Mutation$RestoreBackup._({ Variables$Mutation$RestoreBackup._({
r'snapshotId': snapshotId, r'snapshotId': snapshotId,
r'strategy': strategy,
}); });
Variables$Mutation$RestoreBackup._(this._$data); Variables$Mutation$RestoreBackup._(this._$data);
@ -4993,16 +4997,23 @@ class Variables$Mutation$RestoreBackup {
final result$data = <String, dynamic>{}; final result$data = <String, dynamic>{};
final l$snapshotId = data['snapshotId']; final l$snapshotId = data['snapshotId'];
result$data['snapshotId'] = (l$snapshotId as String); result$data['snapshotId'] = (l$snapshotId as String);
final l$strategy = data['strategy'];
result$data['strategy'] =
fromJson$Enum$RestoreStrategy((l$strategy as String));
return Variables$Mutation$RestoreBackup._(result$data); return Variables$Mutation$RestoreBackup._(result$data);
} }
Map<String, dynamic> _$data; Map<String, dynamic> _$data;
String get snapshotId => (_$data['snapshotId'] as String); String get snapshotId => (_$data['snapshotId'] as String);
Enum$RestoreStrategy get strategy =>
(_$data['strategy'] as Enum$RestoreStrategy);
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final result$data = <String, dynamic>{}; final result$data = <String, dynamic>{};
final l$snapshotId = snapshotId; final l$snapshotId = snapshotId;
result$data['snapshotId'] = l$snapshotId; result$data['snapshotId'] = l$snapshotId;
final l$strategy = strategy;
result$data['strategy'] = toJson$Enum$RestoreStrategy(l$strategy);
return result$data; return result$data;
} }
@ -5025,13 +5036,22 @@ class Variables$Mutation$RestoreBackup {
if (l$snapshotId != lOther$snapshotId) { if (l$snapshotId != lOther$snapshotId) {
return false; return false;
} }
final l$strategy = strategy;
final lOther$strategy = other.strategy;
if (l$strategy != lOther$strategy) {
return false;
}
return true; return true;
} }
@override @override
int get hashCode { int get hashCode {
final l$snapshotId = snapshotId; final l$snapshotId = snapshotId;
return Object.hashAll([l$snapshotId]); final l$strategy = strategy;
return Object.hashAll([
l$snapshotId,
l$strategy,
]);
} }
} }
@ -5044,7 +5064,10 @@ abstract class CopyWith$Variables$Mutation$RestoreBackup<TRes> {
factory CopyWith$Variables$Mutation$RestoreBackup.stub(TRes res) = factory CopyWith$Variables$Mutation$RestoreBackup.stub(TRes res) =
_CopyWithStubImpl$Variables$Mutation$RestoreBackup; _CopyWithStubImpl$Variables$Mutation$RestoreBackup;
TRes call({String? snapshotId}); TRes call({
String? snapshotId,
Enum$RestoreStrategy? strategy,
});
} }
class _CopyWithImpl$Variables$Mutation$RestoreBackup<TRes> class _CopyWithImpl$Variables$Mutation$RestoreBackup<TRes>
@ -5060,11 +5083,16 @@ class _CopyWithImpl$Variables$Mutation$RestoreBackup<TRes>
static const _undefined = <dynamic, dynamic>{}; static const _undefined = <dynamic, dynamic>{};
TRes call({Object? snapshotId = _undefined}) => TRes call({
Object? snapshotId = _undefined,
Object? strategy = _undefined,
}) =>
_then(Variables$Mutation$RestoreBackup._({ _then(Variables$Mutation$RestoreBackup._({
..._instance._$data, ..._instance._$data,
if (snapshotId != _undefined && snapshotId != null) if (snapshotId != _undefined && snapshotId != null)
'snapshotId': (snapshotId as String), 'snapshotId': (snapshotId as String),
if (strategy != _undefined && strategy != null)
'strategy': (strategy as Enum$RestoreStrategy),
})); }));
} }
@ -5074,7 +5102,11 @@ class _CopyWithStubImpl$Variables$Mutation$RestoreBackup<TRes>
TRes _res; TRes _res;
call({String? snapshotId}) => _res; call({
String? snapshotId,
Enum$RestoreStrategy? strategy,
}) =>
_res;
} }
class Mutation$RestoreBackup { class Mutation$RestoreBackup {
@ -5223,7 +5255,18 @@ const documentNodeMutationRestoreBackup = DocumentNode(definitions: [
), ),
defaultValue: DefaultValueNode(value: null), defaultValue: DefaultValueNode(value: null),
directives: [], directives: [],
) ),
VariableDefinitionNode(
variable: VariableNode(name: NameNode(value: 'strategy')),
type: NamedTypeNode(
name: NameNode(value: 'RestoreStrategy'),
isNonNull: true,
),
defaultValue: DefaultValueNode(
value: EnumValueNode(
name: NameNode(value: 'DOWNLOAD_VERIFY_OVERWRITE'))),
directives: [],
),
], ],
directives: [], directives: [],
selectionSet: SelectionSetNode(selections: [ selectionSet: SelectionSetNode(selections: [
@ -5240,7 +5283,11 @@ const documentNodeMutationRestoreBackup = DocumentNode(definitions: [
ArgumentNode( ArgumentNode(
name: NameNode(value: 'snapshotId'), name: NameNode(value: 'snapshotId'),
value: VariableNode(name: NameNode(value: 'snapshotId')), value: VariableNode(name: NameNode(value: 'snapshotId')),
) ),
ArgumentNode(
name: NameNode(value: 'strategy'),
value: VariableNode(name: NameNode(value: 'strategy')),
),
], ],
directives: [], directives: [],
selectionSet: SelectionSetNode(selections: [ selectionSet: SelectionSetNode(selections: [

View File

@ -94,7 +94,8 @@ type BackupMutations {
removeRepository: GenericBackupConfigReturn! removeRepository: GenericBackupConfigReturn!
setAutobackupPeriod(period: Int = null): GenericBackupConfigReturn! setAutobackupPeriod(period: Int = null): GenericBackupConfigReturn!
startBackup(serviceId: String!): GenericJobMutationReturn! startBackup(serviceId: String!): GenericJobMutationReturn!
restoreBackup(snapshotId: String!): GenericJobMutationReturn! restoreBackup(snapshotId: String!, strategy: RestoreStrategy! = DOWNLOAD_VERIFY_OVERWRITE): GenericJobMutationReturn!
forgetSnapshot(snapshotId: String!): GenericMutationReturn!
forceSnapshotsReload: GenericMutationReturn! forceSnapshotsReload: GenericMutationReturn!
} }
@ -241,6 +242,11 @@ input RecoveryKeyLimitsInput {
uses: Int = null uses: Int = null
} }
enum RestoreStrategy {
INPLACE
DOWNLOAD_VERIFY_OVERWRITE
}
enum ServerProvider { enum ServerProvider {
HETZNER HETZNER
DIGITALOCEAN DIGITALOCEAN

View File

@ -1338,6 +1338,30 @@ Enum$DnsProvider fromJson$Enum$DnsProvider(String value) {
} }
} }
enum Enum$RestoreStrategy { INPLACE, DOWNLOAD_VERIFY_OVERWRITE, $unknown }
String toJson$Enum$RestoreStrategy(Enum$RestoreStrategy e) {
switch (e) {
case Enum$RestoreStrategy.INPLACE:
return r'INPLACE';
case Enum$RestoreStrategy.DOWNLOAD_VERIFY_OVERWRITE:
return r'DOWNLOAD_VERIFY_OVERWRITE';
case Enum$RestoreStrategy.$unknown:
return r'$unknown';
}
}
Enum$RestoreStrategy fromJson$Enum$RestoreStrategy(String value) {
switch (value) {
case r'INPLACE':
return Enum$RestoreStrategy.INPLACE;
case r'DOWNLOAD_VERIFY_OVERWRITE':
return Enum$RestoreStrategy.DOWNLOAD_VERIFY_OVERWRITE;
default:
return Enum$RestoreStrategy.$unknown;
}
}
enum Enum$ServerProvider { HETZNER, DIGITALOCEAN, $unknown } enum Enum$ServerProvider { HETZNER, DIGITALOCEAN, $unknown }
String toJson$Enum$ServerProvider(Enum$ServerProvider e) { String toJson$Enum$ServerProvider(Enum$ServerProvider e) {

View File

@ -209,14 +209,17 @@ mixin BackupsApi on GraphQLApiMap {
Future<GenericResult<ServerJob?>> restoreBackup( Future<GenericResult<ServerJob?>> restoreBackup(
final String snapshotId, final String snapshotId,
final BackupRestoreStrategy strategy,
) async { ) async {
QueryResult<Mutation$RestoreBackup> response; QueryResult<Mutation$RestoreBackup> response;
GenericResult<ServerJob?>? result; GenericResult<ServerJob?>? result;
try { try {
final GraphQLClient client = await getClient(); final GraphQLClient client = await getClient();
final variables = final variables = Variables$Mutation$RestoreBackup(
Variables$Mutation$RestoreBackup(snapshotId: snapshotId); snapshotId: snapshotId,
strategy: strategy.toGraphQL,
);
final options = Options$Mutation$RestoreBackup(variables: variables); final options = Options$Mutation$RestoreBackup(variables: variables);
response = await client.mutate$RestoreBackup(options); response = await client.mutate$RestoreBackup(options);
if (response.hasException) { if (response.hasException) {

View File

@ -185,9 +185,12 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
emit(state.copyWith(preventActions: false)); emit(state.copyWith(preventActions: false));
} }
Future<void> restoreBackup(final String backupId) async { Future<void> restoreBackup(
final String backupId,
final BackupRestoreStrategy strategy,
) async {
emit(state.copyWith(preventActions: true)); emit(state.copyWith(preventActions: true));
await api.restoreBackup(backupId); await api.restoreBackup(backupId, strategy);
emit(state.copyWith(preventActions: false)); emit(state.copyWith(preventActions: false));
} }

View File

@ -1,5 +1,6 @@
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/backups.graphql.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/backups.graphql.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart';
import 'package:selfprivacy/logic/models/hive/backups_credential.dart'; import 'package:selfprivacy/logic/models/hive/backups_credential.dart';
class Backup { class Backup {
@ -58,3 +59,26 @@ class BackupConfiguration {
final String? locationName; final String? locationName;
final BackupsProviderType provider; final BackupsProviderType provider;
} }
enum BackupRestoreStrategy {
inplace,
downloadVerifyOverwrite,
unknown;
factory BackupRestoreStrategy.fromGraphQL(
final Enum$RestoreStrategy strategy,
) =>
switch (strategy) {
Enum$RestoreStrategy.INPLACE => inplace,
Enum$RestoreStrategy.DOWNLOAD_VERIFY_OVERWRITE =>
downloadVerifyOverwrite,
Enum$RestoreStrategy.$unknown => unknown,
};
Enum$RestoreStrategy get toGraphQL => switch (this) {
inplace => Enum$RestoreStrategy.INPLACE,
downloadVerifyOverwrite =>
Enum$RestoreStrategy.DOWNLOAD_VERIFY_OVERWRITE,
unknown => Enum$RestoreStrategy.$unknown,
};
}

View File

@ -240,9 +240,10 @@ class BackupDetailsPage extends StatelessWidget {
), ),
actionButtonTitle: 'modals.yes'.tr(), actionButtonTitle: 'modals.yes'.tr(),
actionButtonOnPressed: () => { actionButtonOnPressed: () => {
context context.read<BackupsCubit>().restoreBackup(
.read<BackupsCubit>() backup.id, // TODO: inex
.restoreBackup(backup.id) BackupRestoreStrategy.unknown,
)
}, },
); );
}, },

View File

@ -54,7 +54,10 @@ class BackupsListPage extends StatelessWidget {
), ),
actionButtonTitle: 'modals.yes'.tr(), actionButtonTitle: 'modals.yes'.tr(),
actionButtonOnPressed: () => { actionButtonOnPressed: () => {
context.read<BackupsCubit>().restoreBackup(backup.id) context.read<BackupsCubit>().restoreBackup(
backup.id, // TODO: inex
BackupRestoreStrategy.unknown,
)
}, },
); );
}, },