docker.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. package main
  2. /*
  3. docker.go
  4. Top-level wiring for the optional Docker management feature. Mirrors the
  5. shape of disk.go's RAIDServiceInit: build the manager, and only when it
  6. constructs successfully (Docker is actually usable on this host) register the
  7. settings page, the admin-only HTTP endpoints and the desktop app. When Docker
  8. is absent / the daemon is unreachable, the whole feature stays invisible and
  9. the server boots normally.
  10. Gated additionally by the -enable_docker flag (default true) so an admin can
  11. hard-disable the feature even on a host that has Docker installed.
  12. */
  13. import (
  14. "net/http"
  15. "imuslab.com/arozos/mod/docker"
  16. module "imuslab.com/arozos/mod/modules"
  17. prout "imuslab.com/arozos/mod/prouter"
  18. "imuslab.com/arozos/mod/utils"
  19. )
  20. func DockerServiceInit() {
  21. //Respect the admin kill-switch first, before probing the host.
  22. if !*allow_docker_management {
  23. return
  24. }
  25. dm, err := docker.NewDockerManager(docker.Options{
  26. Logger: systemWideLogger,
  27. StackBaseDir: "./system/docker/stacks",
  28. })
  29. if err != nil {
  30. //Docker not usable on this host. Log once and leave the feature off.
  31. systemWideLogger.PrintAndLog("Docker", "Docker management unavailable on this host: "+err.Error(), nil)
  32. return
  33. }
  34. dockerManager = dm
  35. //Register the "Containers" settings group tabs in display order:
  36. //Docker Daemon -> Docker Engine -> Docker List.
  37. registerSetting(settingModule{
  38. Name: "Docker Daemon",
  39. Desc: "Start, stop and configure the Docker daemon service",
  40. IconPath: "SystemAO/docker/img/small_icon.svg",
  41. Group: "Container",
  42. StartDir: "SystemAO/docker/daemon.html",
  43. RequireAdmin: true,
  44. })
  45. registerSetting(settingModule{
  46. Name: "Docker Engine",
  47. Desc: "Docker version, daemon status, disk usage and cleanup",
  48. IconPath: "SystemAO/docker/img/small_icon.svg",
  49. Group: "Container",
  50. StartDir: "SystemAO/docker/index.html",
  51. RequireAdmin: true,
  52. })
  53. registerSetting(settingModule{
  54. Name: "Docker List",
  55. Desc: "Running containers overview and quick access to Docker Manager",
  56. IconPath: "SystemAO/docker/img/small_icon.svg",
  57. Group: "Container",
  58. StartDir: "SystemAO/docker/list.html",
  59. RequireAdmin: true,
  60. })
  61. //Admin-only router. Docker access is effectively root on the host, so every
  62. //endpoint is restricted to administrators.
  63. adminRouter := prout.NewModuleRouter(prout.RouterOption{
  64. ModuleName: "System Setting",
  65. AdminOnly: true,
  66. UserHandler: userHandler,
  67. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  68. utils.SendErrorResponse(w, "Permission Denied")
  69. },
  70. })
  71. //Engine status / info endpoints (more endpoints added in later phases).
  72. adminRouter.HandleFunc("/system/docker/engine/status", dm.HandleEngineStatus)
  73. //Container lifecycle endpoints.
  74. adminRouter.HandleFunc("/system/docker/containers/list", dm.HandleContainerList)
  75. adminRouter.HandleFunc("/system/docker/containers/inspect", dm.HandleContainerInspect)
  76. adminRouter.HandleFunc("/system/docker/containers/start", dm.HandleContainerStart)
  77. adminRouter.HandleFunc("/system/docker/containers/stop", dm.HandleContainerStop)
  78. adminRouter.HandleFunc("/system/docker/containers/restart", dm.HandleContainerRestart)
  79. adminRouter.HandleFunc("/system/docker/containers/remove", dm.HandleContainerRemove)
  80. adminRouter.HandleFunc("/system/docker/containers/logs", dm.HandleContainerLogs)
  81. //Image endpoints.
  82. adminRouter.HandleFunc("/system/docker/images/list", dm.HandleImageList)
  83. adminRouter.HandleFunc("/system/docker/images/remove", dm.HandleImageRemove)
  84. adminRouter.HandleFunc("/system/docker/images/pull", dm.HandleImagePull)
  85. //Registry endpoints.
  86. adminRouter.HandleFunc("/system/docker/registry/list", dm.HandleRegistryList)
  87. adminRouter.HandleFunc("/system/docker/registry/login", dm.HandleRegistryLogin)
  88. adminRouter.HandleFunc("/system/docker/registry/logout", dm.HandleRegistryLogout)
  89. adminRouter.HandleFunc("/system/docker/registry/search", dm.HandleRegistrySearch)
  90. //Direct run + container config endpoints.
  91. adminRouter.HandleFunc("/system/docker/containers/run", dm.HandleContainerRun)
  92. adminRouter.HandleFunc("/system/docker/containers/create", dm.HandleContainerCreate)
  93. adminRouter.HandleFunc("/system/docker/containers/update", dm.HandleContainerUpdate)
  94. adminRouter.HandleFunc("/system/docker/containers/rename", dm.HandleContainerRename)
  95. adminRouter.HandleFunc("/system/docker/containers/recreate", dm.HandleContainerRecreate)
  96. //Compose stack endpoints.
  97. adminRouter.HandleFunc("/system/docker/compose/list", dm.HandleComposeList)
  98. adminRouter.HandleFunc("/system/docker/compose/get", dm.HandleComposeGet)
  99. adminRouter.HandleFunc("/system/docker/compose/save", dm.HandleComposeSave)
  100. adminRouter.HandleFunc("/system/docker/compose/deploy", dm.HandleComposeDeploy)
  101. adminRouter.HandleFunc("/system/docker/compose/down", dm.HandleComposeDown)
  102. adminRouter.HandleFunc("/system/docker/compose/delete", dm.HandleComposeDelete)
  103. adminRouter.HandleFunc("/system/docker/compose/disable", dm.HandleComposeDisable)
  104. adminRouter.HandleFunc("/system/docker/compose/status", dm.HandleComposeStatus)
  105. adminRouter.HandleFunc("/system/docker/compose/logs", dm.HandleComposeLogs)
  106. //Interactive exec console (websocket; PTY-backed on Linux/macOS).
  107. adminRouter.HandleFunc("/system/docker/console/exec", dm.HandleExecConsole)
  108. //Host resource overview (CPU/RAM/storage/load) for the manager dashboard.
  109. adminRouter.HandleFunc("/system/docker/host/stats", dm.HandleHostStats)
  110. //Engine maintenance: disk usage + prune, daemon.json view/edit.
  111. adminRouter.HandleFunc("/system/docker/engine/df", dm.HandleDiskUsage)
  112. adminRouter.HandleFunc("/system/docker/engine/prune", dm.HandlePrune)
  113. adminRouter.HandleFunc("/system/docker/daemon/get", dm.HandleDaemonGet)
  114. adminRouter.HandleFunc("/system/docker/daemon/save", dm.HandleDaemonSave)
  115. //Daemon service lifecycle control (systemd on Linux).
  116. adminRouter.HandleFunc("/system/docker/service/status", dm.HandleServiceStatus)
  117. adminRouter.HandleFunc("/system/docker/service/action", dm.HandleServiceAction)
  118. //Register the desktop app. Deliberately NOT group "Utilities"/"System Tools"
  119. //(those would make it visible to every user via UniversalModules); group
  120. //"Development" falls through to the normal IsAdmin permission check, so only
  121. //admins see it by default.
  122. moduleHandler.RegisterModule(module.ModuleInfo{
  123. Name: "Docker Manager",
  124. Desc: "Manage Docker containers, images and Compose stacks",
  125. Group: "Development",
  126. IconPath: "DockerManager/img/icon.svg",
  127. Version: "1.0",
  128. StartDir: "DockerManager/index.html",
  129. SupportFW: true,
  130. LaunchFWDir: "DockerManager/index.html",
  131. InitFWSize: []int{1100, 680},
  132. SupportEmb: false,
  133. })
  134. //Bring up any compose stack that is not marked .disabled (mirrors how
  135. //SubserviceInit auto-starts non-suspended subservices at boot).
  136. dm.AutoStartStacks()
  137. systemWideLogger.PrintAndLog("Docker", "Docker management enabled (engine "+dm.GetEngineStatus().ServerVersion+")", nil)
  138. }