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",
"dns_records_did_not_change": "No changes needed",
"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 {}"
},
"validations": {

View file

@ -149,6 +149,10 @@ class JobsCubit extends Cubit<JobsState> {
await getIt<ApiConnectionRepository>().api.getDnsRecords();
for (final ClientJob job in jobs) {
if (job is UpdateDnsRecordsJob) {
continue;
}
emit(
(state as JobsStateLoading)
.updateJobStatus(job.id, JobStatusEnum.running),
@ -170,48 +174,30 @@ class JobsCubit extends Cubit<JobsState> {
}
}
if (dnsUpdateRequired) {
emit(
(state as JobsStateLoading).updateJobStatus(
UpdateDnsRecordsJob.jobId,
JobStatusEnum.running,
),
);
final List<DnsRecord> newDnsRecords =
await getIt<ApiConnectionRepository>().api.getDnsRecords();
await Future<void>.delayed(Duration.zero);
if (const UnorderedIterableEquality()
.equals(oldDnsRecords, newDnsRecords)) {
// If all jobs failed, do not try to change DNS records or rebuild the server
if ((state as JobsStateLoading).clientJobList.every(
(final job) =>
(job.status == JobStatusEnum.error) ||
(job is UpdateDnsRecordsJob),
)) {
if (dnsUpdateRequired) {
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(),
JobStatusEnum.error,
message: 'jobs.ignored_due_to_failures'.tr(),
),
);
await Future.delayed(Duration.zero);
}
emit((state as JobsStateLoading).finished());
return;
}
if (dnsUpdateRequired) {
await updateDnsRecords(oldDnsRecords);
}
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 {
if (state is JobsStateEmpty) {
emit(

View file

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

View file

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