fix: Do not remove all DNS records if server connection failed

This commit is contained in:
Inex Code 2024-07-23 19:56:40 +03:00
parent 3b9cdd9819
commit da073b7454
4 changed files with 84 additions and 36 deletions

View file

@ -609,6 +609,8 @@
"update_dns_records": "Update DNS records", "update_dns_records": "Update DNS records",
"dns_records_did_not_change": "No changes needed", "dns_records_did_not_change": "No changes needed",
"dns_records_changed": "DNS records updated", "dns_records_changed": "DNS records updated",
"failed_to_load_dns_records": "Failed to load DNS records",
"ignored_due_to_failures": "Ignored due to previous failures",
"change_service_settings": "Change service settings for {}" "change_service_settings": "Change service settings for {}"
}, },
"validations": { "validations": {

View file

@ -149,6 +149,10 @@ class JobsCubit extends Cubit<JobsState> {
await getIt<ApiConnectionRepository>().api.getDnsRecords(); await getIt<ApiConnectionRepository>().api.getDnsRecords();
for (final ClientJob job in jobs) { for (final ClientJob job in jobs) {
if (job is UpdateDnsRecordsJob) {
continue;
}
emit( emit(
(state as JobsStateLoading) (state as JobsStateLoading)
.updateJobStatus(job.id, JobStatusEnum.running), .updateJobStatus(job.id, JobStatusEnum.running),
@ -170,48 +174,30 @@ class JobsCubit extends Cubit<JobsState> {
} }
} }
if (dnsUpdateRequired) { await Future<void>.delayed(Duration.zero);
emit(
(state as JobsStateLoading).updateJobStatus(
UpdateDnsRecordsJob.jobId,
JobStatusEnum.running,
),
);
final List<DnsRecord> newDnsRecords =
await getIt<ApiConnectionRepository>().api.getDnsRecords();
if (const UnorderedIterableEquality() // If all jobs failed, do not try to change DNS records or rebuild the server
.equals(oldDnsRecords, newDnsRecords)) { if ((state as JobsStateLoading).clientJobList.every(
(final job) =>
(job.status == JobStatusEnum.error) ||
(job is UpdateDnsRecordsJob),
)) {
if (dnsUpdateRequired) {
emit( emit(
(state as JobsStateLoading).updateJobStatus( (state as JobsStateLoading).updateJobStatus(
UpdateDnsRecordsJob.jobId, UpdateDnsRecordsJob.jobId,
JobStatusEnum.finished, JobStatusEnum.error,
message: 'jobs.dns_records_did_not_change'.tr(), message: 'jobs.ignored_due_to_failures'.tr(),
),
);
} else {
final ServerDomain? domain =
getIt<ApiConnectionRepository>().serverDomain;
final dnsCreateResult =
await ProvidersController.currentDnsProvider!.updateDnsRecords(
newRecords:
newDnsRecords.where((final r) => r.content != null).toList(),
oldRecords: oldDnsRecords,
domain: domain!,
);
emit(
(state as JobsStateLoading).updateJobStatus(
UpdateDnsRecordsJob.jobId,
dnsCreateResult.success
? JobStatusEnum.finished
: JobStatusEnum.error,
message:
dnsCreateResult.message ?? 'jobs.dns_records_changed'.tr(),
), ),
); );
await Future.delayed(Duration.zero);
} }
emit((state as JobsStateLoading).finished());
return;
}
if (dnsUpdateRequired) {
await updateDnsRecords(oldDnsRecords);
} }
if (!rebuildRequired) { if (!rebuildRequired) {
@ -234,6 +220,62 @@ class JobsCubit extends Cubit<JobsState> {
} }
} }
Future<void> updateDnsRecords(final List<DnsRecord> oldDnsRecords) async {
emit(
(state as JobsStateLoading).updateJobStatus(
UpdateDnsRecordsJob.jobId,
JobStatusEnum.running,
),
);
final List<DnsRecord> newDnsRecords =
await getIt<ApiConnectionRepository>().api.getDnsRecords();
// If any of the records have a null content, we don't want to update
// the DNS records
if (newDnsRecords.isEmpty || oldDnsRecords.isEmpty) {
emit(
(state as JobsStateLoading).updateJobStatus(
UpdateDnsRecordsJob.jobId,
JobStatusEnum.error,
message: 'jobs.failed_to_load_dns_records'.tr(),
),
);
return;
}
if (const UnorderedIterableEquality()
.equals(oldDnsRecords, newDnsRecords)) {
emit(
(state as JobsStateLoading).updateJobStatus(
UpdateDnsRecordsJob.jobId,
JobStatusEnum.finished,
message: 'jobs.dns_records_did_not_change'.tr(),
),
);
} else {
final ServerDomain? domain =
getIt<ApiConnectionRepository>().serverDomain;
final dnsCreateResult =
await ProvidersController.currentDnsProvider!.updateDnsRecords(
newRecords:
newDnsRecords.where((final r) => r.content != null).toList(),
oldRecords: oldDnsRecords,
domain: domain!,
);
emit(
(state as JobsStateLoading).updateJobStatus(
UpdateDnsRecordsJob.jobId,
dnsCreateResult.success
? JobStatusEnum.finished
: JobStatusEnum.error,
message: dnsCreateResult.message ?? 'jobs.dns_records_changed'.tr(),
),
);
}
}
Future<void> collectNixGarbage() async { Future<void> collectNixGarbage() async {
if (state is JobsStateEmpty) { if (state is JobsStateEmpty) {
emit( emit(

View file

@ -248,6 +248,7 @@ class ApiConnectionRepository {
) async { ) async {
final GenericResult result = final GenericResult result =
await api.setServiceConfiguration(serviceId, settings); await api.setServiceConfiguration(serviceId, settings);
_apiData.services.invalidate();
if (result.success) { if (result.success) {
return (true, result.message ?? 'basis.done'.tr()); return (true, result.message ?? 'basis.done'.tr());
} else { } else {

View file

@ -28,7 +28,10 @@ class _BasicStringConfigItemState extends State<BasicStringConfigItem> {
final String value = _controller.text; final String value = _controller.text;
final bool isValid = _validateInput(value); final bool isValid = _validateInput(value);
if (isValid) { if (isValid) {
widget.onChanged(value, isValid); setState(() {
widget.onChanged(value, isValid);
_isValid = isValid;
});
} else { } else {
setState(() { setState(() {
widget.onChanged(widget.newValue ?? widget.configItem.value, isValid); widget.onChanged(widget.newValue ?? widget.configItem.value, isValid);