Skip to content

Commit

Permalink
confmigrate: imp code, split files
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneOne1 committed Sep 4, 2023
1 parent f075a14 commit cd29729
Show file tree
Hide file tree
Showing 32 changed files with 1,388 additions and 1,274 deletions.
1,262 changes: 0 additions & 1,262 deletions internal/confmigrate/migrate.go

This file was deleted.

File renamed without changes.
19 changes: 11 additions & 8 deletions internal/confmigrate/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

// LastSchemaVersion is the most recent schema version.
const LastSchemaVersion = 26
const LastSchemaVersion uint = 26

// Config is a the configuration for initializing a [Migrator].
type Config struct {
Expand All @@ -35,18 +35,20 @@ func New(cfg *Config) (m *Migrator) {
// schema version, if needed. It returns the body of the upgraded config file,
// whether the file was upgraded, and an error, if any. If upgraded is false,
// the body is the same as the input.
func (m *Migrator) Migrate(body []byte, target int) (newBody []byte, upgraded bool, err error) {
func (m *Migrator) Migrate(body []byte, target uint) (newBody []byte, upgraded bool, err error) {
diskConf := yobj{}
err = yaml.Unmarshal(body, &diskConf)
if err != nil {
return body, false, fmt.Errorf("parsing config file for upgrade: %w", err)
}

current, _, err := fieldVal[int](diskConf, "schema_version")
currentInt, _, err := fieldVal[int](diskConf, "schema_version")
if err != nil {
// Don't wrap the error, since it's informative enough as is.
return body, false, err
}

current := uint(currentInt)
log.Debug("got schema version %v", current)

if err = validateVersion(current, target); err != nil {
Expand All @@ -73,11 +75,11 @@ func (m *Migrator) Migrate(body []byte, target int) (newBody []byte, upgraded bo
}

// validateVersion validates the current and desired schema versions.
func validateVersion(current, target int) (err error) {
func validateVersion(current, target uint) (err error) {
switch {
case current < 0, current > target:
case current > target:
return fmt.Errorf("unknown current schema version %d", current)
case target < 0, target > LastSchemaVersion:
case target > LastSchemaVersion:
return fmt.Errorf("unknown target schema version %d", target)
case target < current:
return fmt.Errorf("target schema version %d lower than current %d", target, current)
Expand All @@ -92,7 +94,7 @@ type migrateFunc = func(diskConf yobj) (err error)
// upgradeConfigSchema upgrades the configuration schema in diskConf from
// current to target version. current must be less than target, and both must
// be non-negative and less or equal to [LastSchemaVersion].
func (m *Migrator) upgradeConfigSchema(current, target int, diskConf yobj) (err error) {
func (m *Migrator) upgradeConfigSchema(current, target uint, diskConf yobj) (err error) {
upgrades := [LastSchemaVersion]migrateFunc{
0: m.migrateTo1,
1: m.migrateTo2,
Expand Down Expand Up @@ -122,10 +124,11 @@ func (m *Migrator) upgradeConfigSchema(current, target int, diskConf yobj) (err
25: migrateTo26,
}

cur := int(current)
for i, migrate := range upgrades[current:target] {
err = migrate(diskConf)
if err != nil {
return fmt.Errorf("migrating schema %d to %d: %w", current+i, current+i+1, err)
return fmt.Errorf("migrating schema %d to %d: %w", cur+i, cur+i+1, err)
}
}

Expand Down
2 changes: 1 addition & 1 deletion internal/confmigrate/migrator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestMigrateConfig_Migrate(t *testing.T) {
testCases := []struct {
yamlEqFunc func(t require.TestingT, expected, actual string, msgAndArgs ...any)
name string
targetVersion int
targetVersion uint
}{{
yamlEqFunc: require.YAMLEq,
name: "v1",
Expand Down
35 changes: 35 additions & 0 deletions internal/confmigrate/v1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package confmigrate

import (
"os"
"path/filepath"

"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
)

// migrateTo1 performs the following changes:
//
// # BEFORE:
// # …
//
// # AFTER:
// 'schema_version': 1
//
// It also deletes the unused dnsfilter.txt file, since the following versions
// store filters in data/filters/.
func (m *Migrator) migrateTo1(diskConf yobj) (err error) {
log.Printf("Upgrade yaml: 0 to 1")
diskConf["schema_version"] = 1

dnsFilterPath := filepath.Join(m.workingDir, "dnsfilter.txt")
log.Printf("deleting %s as we don't need it anymore", dnsFilterPath)
err = os.Remove(dnsFilterPath)
if err != nil && !errors.Is(err, os.ErrNotExist) {
log.Info("warning: %s", err)

// Go on.
}

return nil
}
105 changes: 105 additions & 0 deletions internal/confmigrate/v10.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package confmigrate

import (
"fmt"
"net/url"
"strconv"
"strings"

"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
)

// addQUICPort inserts a port into QUIC upstream's hostname if it is missing.
func addQUICPort(ups string, port int) (withPort string) {
if ups == "" || ups[0] == '#' {
return ups
}

var doms string
withPort = ups
if strings.HasPrefix(ups, "[/") {
domsAndUps := strings.Split(strings.TrimPrefix(ups, "[/"), "/]")
if len(domsAndUps) != 2 {
return ups
}

doms, withPort = "[/"+domsAndUps[0]+"/]", domsAndUps[1]
}

if !strings.Contains(withPort, ":https://") {
return ups
}

upsURL, err := url.Parse(withPort)
if err != nil || upsURL.Scheme != "quic" {
return ups
}

var host string
host, err = netutil.SplitHost(upsURL.Host)
if err != nil || host != upsURL.Host {
return ups
}

upsURL.Host = strings.Join([]string{host, strconv.Itoa(port)}, ":")

return doms + upsURL.String()
}

// migrateTo10 performs the following changes:
//
// # BEFORE:
// 'schema_version': 9
// 'dns':
// 'upstream_dns':
// - 'quic:https://some-upstream.com'
// 'local_ptr_upstreams':
// - 'quic:https://some-upstream.com'
//
// # AFTER:
// 'schema_version': 10
// 'dns':
// 'upstream_dns':
// - 'quic:https://some-upstream.com:784'
// 'local_ptr_upstreams':
// - 'quic:https://some-upstream.com:784'
func migrateTo10(diskConf yobj) (err error) {
log.Printf("Upgrade yaml: 9 to 10")
diskConf["schema_version"] = 10

dns, ok, err := fieldVal[yobj](diskConf, "dns")
if err != nil {
return err
} else if !ok {
return nil
}

const quicPort = 784

for _, upsField := range []string{
"upstream_dns",
"local_ptr_upstreams",
} {
var ups yarr
ups, ok, err = fieldVal[yarr](dns, upsField)
if err != nil {
return err
} else if !ok {
continue
}

var u string
for i, uVal := range ups {
u, ok = uVal.(string)
if !ok {
return fmt.Errorf("unexpected type of upstream field: %T", uVal)
}

ups[i] = addQUICPort(u, quicPort)
}
dns[upsField] = ups
}

return nil
}
34 changes: 34 additions & 0 deletions internal/confmigrate/v11.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package confmigrate

import "github.com/AdguardTeam/golibs/log"

// migrateTo11 performs the following changes:
//
// # BEFORE:
// 'schema_version': 10
// 'rlimit_nofile': 42
//
// # AFTER:
// 'schema_version': 11
// 'os':
// 'group': ''
// 'rlimit_nofile': 42
// 'user': ''
func migrateTo11(diskConf yobj) (err error) {
log.Printf("Upgrade yaml: 10 to 11")
diskConf["schema_version"] = 11

rlimit, _, err := fieldVal[int](diskConf, "rlimit_nofile")
if err != nil {
return err
}

delete(diskConf, "rlimit_nofile")
diskConf["os"] = yobj{
"group": "",
"rlimit_nofile": rlimit,
"user": "",
}

return nil
}
43 changes: 43 additions & 0 deletions internal/confmigrate/v12.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package confmigrate

import (
"time"

"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/timeutil"
)

// migrateTo12 performs the following changes:
//
// # BEFORE:
// 'schema_version': 11
// 'querylog_interval': 90
//
// # AFTER:
// 'schema_version': 12
// 'querylog_interval': '2160h'
func migrateTo12(diskConf yobj) (err error) {
log.Printf("Upgrade yaml: 11 to 12")
diskConf["schema_version"] = 12

dns, ok, err := fieldVal[yobj](diskConf, "dns")
if err != nil {
return err
} else if !ok {
return nil
}

const field = "querylog_interval"

qlogIvl, ok, err := fieldVal[int](dns, field)
if err != nil {
return err
} else if !ok {
// Set the initial value from home.initConfig function.
qlogIvl = 90
}

dns[field] = timeutil.Duration{Duration: time.Duration(qlogIvl) * timeutil.Day}

return nil
}
37 changes: 37 additions & 0 deletions internal/confmigrate/v13.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package confmigrate

import "github.com/AdguardTeam/golibs/log"

// migrateTo13 performs the following changes:
//
// # BEFORE:
// 'schema_version': 12
// 'dns':
// # …
// 'local_domain_name': 'lan'
//
// # AFTER:
// 'schema_version': 13
// 'dhcp':
// # …
// 'local_domain_name': 'lan'
func migrateTo13(diskConf yobj) (err error) {
log.Printf("Upgrade yaml: 12 to 13")
diskConf["schema_version"] = 13

dns, ok, err := fieldVal[yobj](diskConf, "dns")
if err != nil {
return err
} else if !ok {
return nil
}

dhcp, ok, err := fieldVal[yobj](diskConf, "dhcp")
if err != nil {
return err
} else if !ok {
return nil
}

return moveSameVal[string](dns, dhcp, "local_domain_name")
}
61 changes: 61 additions & 0 deletions internal/confmigrate/v14.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package confmigrate

import "github.com/AdguardTeam/golibs/log"

// migrateTo14 performs the following changes:
//
// # BEFORE:
// 'schema_version': 13
// 'clients':
// - 'name': 'client-name'
// # …
//
// # AFTER:
// 'schema_version': 14
// 'clients':
// 'persistent':
// - 'name': 'client-name'
// # …
// 'runtime_sources':
// 'whois': true
// 'arp': true
// 'rdns': true
// 'dhcp': true
// 'hosts': true
func migrateTo14(diskConf yobj) (err error) {
log.Printf("Upgrade yaml: 13 to 14")
diskConf["schema_version"] = 14

persistent, ok, err := fieldVal[yarr](diskConf, "clients")
if err != nil {
return err
} else if !ok {
persistent = yarr{}
}

var rdnsSrc bool
dns, ok, err := fieldVal[yobj](diskConf, "dns")
if err != nil {
return err
} else if ok {
rdnsSrc, ok, err = fieldVal[bool](dns, "resolve_clients")
if err != nil {
return err
} else if ok {
delete(dns, "resolve_clients")
}
}

diskConf["clients"] = yobj{
"persistent": persistent,
"runtime_sources": yobj{
"whois": true,
"arp": true,
"rdns": rdnsSrc,
"dhcp": true,
"hosts": true,
},
}

return nil
}
Loading

0 comments on commit cd29729

Please sign in to comment.