github.com/rawahars/moby@v24.0.4+incompatible/daemon/reload_test.go (about)

     1  package daemon // import "github.com/docker/docker/daemon"
     2  
     3  import (
     4  	"os"
     5  	"sort"
     6  	"testing"
     7  
     8  	"github.com/docker/docker/daemon/config"
     9  	"github.com/docker/docker/daemon/images"
    10  	"github.com/docker/docker/libnetwork"
    11  	"github.com/docker/docker/registry"
    12  	"github.com/sirupsen/logrus"
    13  	"gotest.tools/v3/assert"
    14  	is "gotest.tools/v3/assert/cmp"
    15  )
    16  
    17  // muteLogs suppresses logs that are generated during the test
    18  func muteLogs() {
    19  	logrus.SetLevel(logrus.ErrorLevel)
    20  }
    21  
    22  func TestDaemonReloadLabels(t *testing.T) {
    23  	daemon := &Daemon{
    24  		configStore: &config.Config{
    25  			CommonConfig: config.CommonConfig{
    26  				Labels: []string{"foo:bar"},
    27  			},
    28  		},
    29  		imageService: images.NewImageService(images.ImageServiceConfig{}),
    30  	}
    31  	muteLogs()
    32  
    33  	valuesSets := make(map[string]interface{})
    34  	valuesSets["labels"] = "foo:baz"
    35  	newConfig := &config.Config{
    36  		CommonConfig: config.CommonConfig{
    37  			Labels:    []string{"foo:baz"},
    38  			ValuesSet: valuesSets,
    39  		},
    40  	}
    41  
    42  	if err := daemon.Reload(newConfig); err != nil {
    43  		t.Fatal(err)
    44  	}
    45  
    46  	label := daemon.configStore.Labels[0]
    47  	if label != "foo:baz" {
    48  		t.Fatalf("Expected daemon label `foo:baz`, got %s", label)
    49  	}
    50  }
    51  
    52  func TestDaemonReloadAllowNondistributableArtifacts(t *testing.T) {
    53  	daemon := &Daemon{
    54  		configStore:  &config.Config{},
    55  		imageService: images.NewImageService(images.ImageServiceConfig{}),
    56  	}
    57  	muteLogs()
    58  
    59  	var err error
    60  	// Initialize daemon with some registries.
    61  	daemon.registryService, err = registry.NewService(registry.ServiceOptions{
    62  		AllowNondistributableArtifacts: []string{
    63  			"127.0.0.0/8",
    64  			"10.10.1.11:5000",
    65  			"10.10.1.22:5000", // This will be removed during reload.
    66  			"docker1.com",
    67  			"docker2.com", // This will be removed during reload.
    68  		},
    69  	})
    70  	if err != nil {
    71  		t.Fatal(err)
    72  	}
    73  
    74  	registries := []string{
    75  		"127.0.0.0/8",
    76  		"10.10.1.11:5000",
    77  		"10.10.1.33:5000", // This will be added during reload.
    78  		"docker1.com",
    79  		"docker3.com", // This will be added during reload.
    80  	}
    81  
    82  	newConfig := &config.Config{
    83  		CommonConfig: config.CommonConfig{
    84  			ServiceOptions: registry.ServiceOptions{
    85  				AllowNondistributableArtifacts: registries,
    86  			},
    87  			ValuesSet: map[string]interface{}{
    88  				"allow-nondistributable-artifacts": registries,
    89  			},
    90  		},
    91  	}
    92  
    93  	if err := daemon.Reload(newConfig); err != nil {
    94  		t.Fatal(err)
    95  	}
    96  
    97  	var actual []string
    98  	serviceConfig := daemon.registryService.ServiceConfig()
    99  	for _, value := range serviceConfig.AllowNondistributableArtifactsCIDRs {
   100  		actual = append(actual, value.String())
   101  	}
   102  	actual = append(actual, serviceConfig.AllowNondistributableArtifactsHostnames...)
   103  
   104  	sort.Strings(registries)
   105  	sort.Strings(actual)
   106  	assert.Check(t, is.DeepEqual(registries, actual))
   107  }
   108  
   109  func TestDaemonReloadMirrors(t *testing.T) {
   110  	daemon := &Daemon{
   111  		imageService: images.NewImageService(images.ImageServiceConfig{}),
   112  	}
   113  	muteLogs()
   114  
   115  	var err error
   116  	daemon.registryService, err = registry.NewService(registry.ServiceOptions{
   117  		InsecureRegistries: []string{},
   118  		Mirrors: []string{
   119  			"https://mirror.test1.example.com",
   120  			"https://mirror.test2.example.com", // this will be removed when reloading
   121  			"https://mirror.test3.example.com", // this will be removed when reloading
   122  		},
   123  	})
   124  	if err != nil {
   125  		t.Fatal(err)
   126  	}
   127  
   128  	daemon.configStore = &config.Config{}
   129  
   130  	type pair struct {
   131  		valid   bool
   132  		mirrors []string
   133  		after   []string
   134  	}
   135  
   136  	loadMirrors := []pair{
   137  		{
   138  			valid:   false,
   139  			mirrors: []string{"10.10.1.11:5000"}, // this mirror is invalid
   140  			after:   []string{},
   141  		},
   142  		{
   143  			valid:   false,
   144  			mirrors: []string{"mirror.test1.com"}, // this mirror is invalid
   145  			after:   []string{},
   146  		},
   147  		{
   148  			valid:   false,
   149  			mirrors: []string{"10.10.1.11:5000", "mirror.test1.example.com"}, // mirrors are invalid
   150  			after:   []string{},
   151  		},
   152  		{
   153  			valid:   true,
   154  			mirrors: []string{"https://mirror.test1.example.com", "https://mirror.test4.example.com"},
   155  			after:   []string{"https://mirror.test1.example.com/", "https://mirror.test4.example.com/"},
   156  		},
   157  	}
   158  
   159  	for _, value := range loadMirrors {
   160  		valuesSets := make(map[string]interface{})
   161  		valuesSets["registry-mirrors"] = value.mirrors
   162  
   163  		newConfig := &config.Config{
   164  			CommonConfig: config.CommonConfig{
   165  				ServiceOptions: registry.ServiceOptions{
   166  					Mirrors: value.mirrors,
   167  				},
   168  				ValuesSet: valuesSets,
   169  			},
   170  		}
   171  
   172  		err := daemon.Reload(newConfig)
   173  		if !value.valid && err == nil {
   174  			// mirrors should be invalid, should be a non-nil error
   175  			t.Fatalf("Expected daemon reload error with invalid mirrors: %s, while get nil", value.mirrors)
   176  		}
   177  
   178  		if value.valid {
   179  			if err != nil {
   180  				// mirrors should be valid, should be no error
   181  				t.Fatal(err)
   182  			}
   183  			registryService := daemon.registryService.ServiceConfig()
   184  
   185  			if len(registryService.Mirrors) != len(value.after) {
   186  				t.Fatalf("Expected %d daemon mirrors %s while get %d with %s",
   187  					len(value.after),
   188  					value.after,
   189  					len(registryService.Mirrors),
   190  					registryService.Mirrors)
   191  			}
   192  
   193  			dataMap := map[string]struct{}{}
   194  
   195  			for _, mirror := range registryService.Mirrors {
   196  				if _, exist := dataMap[mirror]; !exist {
   197  					dataMap[mirror] = struct{}{}
   198  				}
   199  			}
   200  
   201  			for _, address := range value.after {
   202  				if _, exist := dataMap[address]; !exist {
   203  					t.Fatalf("Expected %s in daemon mirrors, while get none", address)
   204  				}
   205  			}
   206  		}
   207  	}
   208  }
   209  
   210  func TestDaemonReloadInsecureRegistries(t *testing.T) {
   211  	daemon := &Daemon{
   212  		imageService: images.NewImageService(images.ImageServiceConfig{}),
   213  	}
   214  	muteLogs()
   215  
   216  	var err error
   217  	// initialize daemon with existing insecure registries: "127.0.0.0/8", "10.10.1.11:5000", "10.10.1.22:5000"
   218  	daemon.registryService, err = registry.NewService(registry.ServiceOptions{
   219  		InsecureRegistries: []string{
   220  			"127.0.0.0/8",
   221  			"10.10.1.11:5000",
   222  			"10.10.1.22:5000", // this will be removed when reloading
   223  			"docker1.example.com",
   224  			"docker2.example.com", // this will be removed when reloading
   225  		},
   226  	})
   227  	if err != nil {
   228  		t.Fatal(err)
   229  	}
   230  
   231  	daemon.configStore = &config.Config{}
   232  
   233  	insecureRegistries := []string{
   234  		"127.0.0.0/8",         // this will be kept
   235  		"10.10.1.11:5000",     // this will be kept
   236  		"10.10.1.33:5000",     // this will be newly added
   237  		"docker1.example.com", // this will be kept
   238  		"docker3.example.com", // this will be newly added
   239  	}
   240  
   241  	mirrors := []string{
   242  		"https://mirror.test.example.com",
   243  	}
   244  
   245  	valuesSets := make(map[string]interface{})
   246  	valuesSets["insecure-registries"] = insecureRegistries
   247  	valuesSets["registry-mirrors"] = mirrors
   248  
   249  	newConfig := &config.Config{
   250  		CommonConfig: config.CommonConfig{
   251  			ServiceOptions: registry.ServiceOptions{
   252  				InsecureRegistries: insecureRegistries,
   253  				Mirrors:            mirrors,
   254  			},
   255  			ValuesSet: valuesSets,
   256  		},
   257  	}
   258  
   259  	if err := daemon.Reload(newConfig); err != nil {
   260  		t.Fatal(err)
   261  	}
   262  
   263  	// After Reload, daemon.RegistryService will be changed which is useful
   264  	// for registry communication in daemon.
   265  	registries := daemon.registryService.ServiceConfig()
   266  
   267  	// After Reload(), newConfig has come to registries.InsecureRegistryCIDRs and registries.IndexConfigs in daemon.
   268  	// Then collect registries.InsecureRegistryCIDRs in dataMap.
   269  	// When collecting, we need to convert CIDRS into string as a key,
   270  	// while the times of key appears as value.
   271  	dataMap := map[string]int{}
   272  	for _, value := range registries.InsecureRegistryCIDRs {
   273  		if _, ok := dataMap[value.String()]; !ok {
   274  			dataMap[value.String()] = 1
   275  		} else {
   276  			dataMap[value.String()]++
   277  		}
   278  	}
   279  
   280  	for _, value := range registries.IndexConfigs {
   281  		if _, ok := dataMap[value.Name]; !ok {
   282  			dataMap[value.Name] = 1
   283  		} else {
   284  			dataMap[value.Name]++
   285  		}
   286  	}
   287  
   288  	// Finally compare dataMap with the original insecureRegistries.
   289  	// Each value in insecureRegistries should appear in daemon's insecure registries,
   290  	// and each can only appear exactly ONCE.
   291  	for _, r := range insecureRegistries {
   292  		if value, ok := dataMap[r]; !ok {
   293  			t.Fatalf("Expected daemon insecure registry %s, got none", r)
   294  		} else if value != 1 {
   295  			t.Fatalf("Expected only 1 daemon insecure registry %s, got %d", r, value)
   296  		}
   297  	}
   298  
   299  	// assert if "10.10.1.22:5000" is removed when reloading
   300  	if value, ok := dataMap["10.10.1.22:5000"]; ok {
   301  		t.Fatalf("Expected no insecure registry of 10.10.1.22:5000, got %d", value)
   302  	}
   303  
   304  	// assert if "docker2.com" is removed when reloading
   305  	if value, ok := dataMap["docker2.example.com"]; ok {
   306  		t.Fatalf("Expected no insecure registry of docker2.com, got %d", value)
   307  	}
   308  }
   309  
   310  func TestDaemonReloadNotAffectOthers(t *testing.T) {
   311  	daemon := &Daemon{
   312  		imageService: images.NewImageService(images.ImageServiceConfig{}),
   313  	}
   314  	muteLogs()
   315  
   316  	daemon.configStore = &config.Config{
   317  		CommonConfig: config.CommonConfig{
   318  			Labels: []string{"foo:bar"},
   319  			Debug:  true,
   320  		},
   321  	}
   322  
   323  	valuesSets := make(map[string]interface{})
   324  	valuesSets["labels"] = "foo:baz"
   325  	newConfig := &config.Config{
   326  		CommonConfig: config.CommonConfig{
   327  			Labels:    []string{"foo:baz"},
   328  			ValuesSet: valuesSets,
   329  		},
   330  	}
   331  
   332  	if err := daemon.Reload(newConfig); err != nil {
   333  		t.Fatal(err)
   334  	}
   335  
   336  	label := daemon.configStore.Labels[0]
   337  	if label != "foo:baz" {
   338  		t.Fatalf("Expected daemon label `foo:baz`, got %s", label)
   339  	}
   340  	debug := daemon.configStore.Debug
   341  	if !debug {
   342  		t.Fatal("Expected debug 'enabled', got 'disabled'")
   343  	}
   344  }
   345  
   346  func TestDaemonReloadNetworkDiagnosticPort(t *testing.T) {
   347  	if os.Getuid() != 0 {
   348  		t.Skip("root required")
   349  	}
   350  	daemon := &Daemon{
   351  		imageService: images.NewImageService(images.ImageServiceConfig{}),
   352  		configStore:  &config.Config{},
   353  	}
   354  
   355  	enableConfig := &config.Config{
   356  		CommonConfig: config.CommonConfig{
   357  			NetworkDiagnosticPort: 2000,
   358  			ValuesSet: map[string]interface{}{
   359  				"network-diagnostic-port": 2000,
   360  			},
   361  		},
   362  	}
   363  
   364  	netOptions, err := daemon.networkOptions(nil, nil)
   365  	if err != nil {
   366  		t.Fatal(err)
   367  	}
   368  	controller, err := libnetwork.New(netOptions...)
   369  	if err != nil {
   370  		t.Fatal(err)
   371  	}
   372  	daemon.netController = controller
   373  
   374  	// Enable/Disable the server for some iterations
   375  	for i := 0; i < 10; i++ {
   376  		enableConfig.CommonConfig.NetworkDiagnosticPort++
   377  		if err := daemon.Reload(enableConfig); err != nil {
   378  			t.Fatal(err)
   379  		}
   380  		// Check that the diagnostic is enabled
   381  		if !daemon.netController.IsDiagnosticEnabled() {
   382  			t.Fatalf("diagnostic should be enabled")
   383  		}
   384  
   385  		// Reload
   386  		if err := daemon.Reload(&config.Config{}); err != nil {
   387  			t.Fatal(err)
   388  		}
   389  		// Check that the diagnostic is disabled
   390  		if daemon.netController.IsDiagnosticEnabled() {
   391  			t.Fatalf("diagnostic should be disabled")
   392  		}
   393  	}
   394  
   395  	enableConfig.CommonConfig.NetworkDiagnosticPort++
   396  	// 2 times the enable should not create problems
   397  	if err := daemon.Reload(enableConfig); err != nil {
   398  		t.Fatal(err)
   399  	}
   400  	// Check that the diagnostic is enabled
   401  	if !daemon.netController.IsDiagnosticEnabled() {
   402  		t.Fatalf("diagnostic should be enable")
   403  	}
   404  
   405  	// Check that another reload does not cause issues
   406  	if err := daemon.Reload(enableConfig); err != nil {
   407  		t.Fatal(err)
   408  	}
   409  	// Check that the diagnostic is enable
   410  	if !daemon.netController.IsDiagnosticEnabled() {
   411  		t.Fatalf("diagnostic should be enable")
   412  	}
   413  }