reload_test.go 11 KB

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