reload_test.go 11 KB

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