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