reload_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  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. mirrors := []string{
  210. "https://mirror.test.example.com",
  211. }
  212. valuesSets := make(map[string]interface{})
  213. valuesSets["insecure-registries"] = insecureRegistries
  214. valuesSets["registry-mirrors"] = mirrors
  215. newConfig := &config.Config{
  216. CommonConfig: config.CommonConfig{
  217. ServiceOptions: registry.ServiceOptions{
  218. InsecureRegistries: insecureRegistries,
  219. Mirrors: mirrors,
  220. },
  221. ValuesSet: valuesSets,
  222. },
  223. }
  224. if err := daemon.Reload(newConfig); err != nil {
  225. t.Fatal(err)
  226. }
  227. // After Reload, daemon.RegistryService will be changed which is useful
  228. // for registry communication in daemon.
  229. registries := daemon.registryService.ServiceConfig()
  230. // After Reload(), newConfig has come to registries.InsecureRegistryCIDRs and registries.IndexConfigs in daemon.
  231. // Then collect registries.InsecureRegistryCIDRs in dataMap.
  232. // When collecting, we need to convert CIDRS into string as a key,
  233. // while the times of key appears as value.
  234. dataMap := map[string]int{}
  235. for _, value := range registries.InsecureRegistryCIDRs {
  236. if _, ok := dataMap[value.String()]; !ok {
  237. dataMap[value.String()] = 1
  238. } else {
  239. dataMap[value.String()]++
  240. }
  241. }
  242. for _, value := range registries.IndexConfigs {
  243. if _, ok := dataMap[value.Name]; !ok {
  244. dataMap[value.Name] = 1
  245. } else {
  246. dataMap[value.Name]++
  247. }
  248. }
  249. // Finally compare dataMap with the original insecureRegistries.
  250. // Each value in insecureRegistries should appear in daemon's insecure registries,
  251. // and each can only appear exactly ONCE.
  252. for _, r := range insecureRegistries {
  253. if value, ok := dataMap[r]; !ok {
  254. t.Fatalf("Expected daemon insecure registry %s, got none", r)
  255. } else if value != 1 {
  256. t.Fatalf("Expected only 1 daemon insecure registry %s, got %d", r, value)
  257. }
  258. }
  259. // assert if "10.10.1.22:5000" is removed when reloading
  260. if value, ok := dataMap["10.10.1.22:5000"]; ok {
  261. t.Fatalf("Expected no insecure registry of 10.10.1.22:5000, got %d", value)
  262. }
  263. // assert if "docker2.com" is removed when reloading
  264. if value, ok := dataMap["docker2.example.com"]; ok {
  265. t.Fatalf("Expected no insecure registry of docker2.com, got %d", value)
  266. }
  267. }
  268. func TestDaemonReloadNotAffectOthers(t *testing.T) {
  269. daemon := &Daemon{
  270. imageService: images.NewImageService(images.ImageServiceConfig{}),
  271. }
  272. muteLogs()
  273. daemon.configStore = &config.Config{
  274. CommonConfig: config.CommonConfig{
  275. Labels: []string{"foo:bar"},
  276. Debug: true,
  277. },
  278. }
  279. valuesSets := make(map[string]interface{})
  280. valuesSets["labels"] = "foo:baz"
  281. newConfig := &config.Config{
  282. CommonConfig: config.CommonConfig{
  283. Labels: []string{"foo:baz"},
  284. ValuesSet: valuesSets,
  285. },
  286. }
  287. if err := daemon.Reload(newConfig); err != nil {
  288. t.Fatal(err)
  289. }
  290. label := daemon.configStore.Labels[0]
  291. if label != "foo:baz" {
  292. t.Fatalf("Expected daemon label `foo:baz`, got %s", label)
  293. }
  294. debug := daemon.configStore.Debug
  295. if !debug {
  296. t.Fatal("Expected debug 'enabled', got 'disabled'")
  297. }
  298. }
  299. func TestDaemonReloadNetworkDiagnosticPort(t *testing.T) {
  300. if os.Getuid() != 0 {
  301. t.Skip("root required")
  302. }
  303. daemon := &Daemon{
  304. imageService: images.NewImageService(images.ImageServiceConfig{}),
  305. configStore: &config.Config{},
  306. }
  307. enableConfig := &config.Config{
  308. CommonConfig: config.CommonConfig{
  309. NetworkDiagnosticPort: 2000,
  310. ValuesSet: map[string]interface{}{
  311. "network-diagnostic-port": 2000,
  312. },
  313. },
  314. }
  315. netOptions, err := daemon.networkOptions(nil, nil)
  316. if err != nil {
  317. t.Fatal(err)
  318. }
  319. controller, err := libnetwork.New(netOptions...)
  320. if err != nil {
  321. t.Fatal(err)
  322. }
  323. daemon.netController = controller
  324. // Enable/Disable the server for some iterations
  325. for i := 0; i < 10; i++ {
  326. enableConfig.CommonConfig.NetworkDiagnosticPort++
  327. if err := daemon.Reload(enableConfig); err != nil {
  328. t.Fatal(err)
  329. }
  330. // Check that the diagnostic is enabled
  331. if !daemon.netController.IsDiagnosticEnabled() {
  332. t.Fatalf("diagnostic should be enabled")
  333. }
  334. // Reload
  335. if err := daemon.Reload(&config.Config{}); err != nil {
  336. t.Fatal(err)
  337. }
  338. // Check that the diagnostic is disabled
  339. if daemon.netController.IsDiagnosticEnabled() {
  340. t.Fatalf("diagnostic should be disabled")
  341. }
  342. }
  343. enableConfig.CommonConfig.NetworkDiagnosticPort++
  344. // 2 times the enable should not create problems
  345. if err := daemon.Reload(enableConfig); err != nil {
  346. t.Fatal(err)
  347. }
  348. // Check that the diagnostic is enabled
  349. if !daemon.netController.IsDiagnosticEnabled() {
  350. t.Fatalf("diagnostic should be enable")
  351. }
  352. // Check that another reload does not cause issues
  353. if err := daemon.Reload(enableConfig); err != nil {
  354. t.Fatal(err)
  355. }
  356. // Check that the diagnostic is enable
  357. if !daemon.netController.IsDiagnosticEnabled() {
  358. t.Fatalf("diagnostic should be enable")
  359. }
  360. }