reload_test.go 11 KB

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