From 55cd4ae2546971f762713e6af16c1bbfcff8b1bb Mon Sep 17 00:00:00 2001
From: Ainar Garipov <a.garipov@adguard.com>
Date: Tue, 20 Apr 2021 18:56:15 +0300
Subject: [PATCH] Pull request: home: fix 8 to 9 migration

Updates #2988.

Squashed commit of the following:

commit 1b9f145be0dbcca9848e02942cea294315baa9cc
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Apr 20 18:41:05 2021 +0300

    home: fix 8 to 9 migration
---
 internal/home/upgrade.go      | 11 ++++++-
 internal/home/upgrade_test.go | 58 +++++++++++++++++++++++++----------
 2 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/internal/home/upgrade.go b/internal/home/upgrade.go
index e3441ffc..137d6ef5 100644
--- a/internal/home/upgrade.go
+++ b/internal/home/upgrade.go
@@ -490,7 +490,16 @@ func upgradeSchema8to9(diskConf yobj) (err error) {
 		return fmt.Errorf("unexpected type of dns: %T", dnsVal)
 	}
 
-	autohostTLDVal := dns["autohost_tld"]
+	autohostTLDVal, ok := dns["autohost_tld"]
+	if !ok {
+		// This happens when upgrading directly from v0.105.2, because
+		// dns.autohost_tld was never set to any value.  Go on and leave
+		// it that way.
+		//
+		// See https://github.com/AdguardTeam/AdGuardHome/issues/2988.
+		return nil
+	}
+
 	autohostTLD, ok := autohostTLDVal.(string)
 	if !ok {
 		return fmt.Errorf("undexpected type of dns.autohost_tld: %T", autohostTLDVal)
diff --git a/internal/home/upgrade_test.go b/internal/home/upgrade_test.go
index 2d56cddb..9a3785be 100644
--- a/internal/home/upgrade_test.go
+++ b/internal/home/upgrade_test.go
@@ -92,28 +92,54 @@ func TestUpgradeSchema7to8(t *testing.T) {
 
 func TestUpgradeSchema8to9(t *testing.T) {
 	const tld = "foo"
-	oldConf := yobj{
-		"dns": yobj{
-			"autohost_tld": tld,
-		},
-		"schema_version": 8,
-	}
 
-	err := upgradeSchema8to9(oldConf)
-	require.NoError(t, err)
+	t.Run("with_autohost_tld", func(t *testing.T) {
+		oldConf := yobj{
+			"dns": yobj{
+				"autohost_tld": tld,
+			},
+			"schema_version": 8,
+		}
 
-	require.Equal(t, oldConf["schema_version"], 9)
+		err := upgradeSchema8to9(oldConf)
+		require.NoError(t, err)
 
-	dnsVal, ok := oldConf["dns"]
-	require.True(t, ok)
+		require.Equal(t, oldConf["schema_version"], 9)
 
-	newDNSConf, ok := dnsVal.(yobj)
-	require.True(t, ok)
+		dnsVal, ok := oldConf["dns"]
+		require.True(t, ok)
 
-	localDomainName, ok := newDNSConf["local_domain_name"].(string)
-	require.True(t, ok)
+		newDNSConf, ok := dnsVal.(yobj)
+		require.True(t, ok)
 
-	assert.Equal(t, tld, localDomainName)
+		localDomainName, ok := newDNSConf["local_domain_name"].(string)
+		require.True(t, ok)
+
+		assert.Equal(t, tld, localDomainName)
+	})
+
+	t.Run("without_autohost_tld", func(t *testing.T) {
+		oldConf := yobj{
+			"dns":            yobj{},
+			"schema_version": 8,
+		}
+
+		err := upgradeSchema8to9(oldConf)
+		require.NoError(t, err)
+
+		require.Equal(t, oldConf["schema_version"], 9)
+
+		dnsVal, ok := oldConf["dns"]
+		require.True(t, ok)
+
+		newDNSConf, ok := dnsVal.(yobj)
+		require.True(t, ok)
+
+		// Should be nil in order to be set to the default value by the
+		// following config rewrite.
+		_, ok = newDNSConf["local_domain_name"]
+		require.False(t, ok)
+	})
 }
 
 // assertEqualExcept removes entries from configs and compares them.