service.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. package service
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/codegangsta/cli"
  6. dockerApp "github.com/docker/libcompose/cli/docker/app"
  7. "github.com/docker/libcompose/project"
  8. "github.com/rancher/os/cmd/control/service/command"
  9. "github.com/rancher/os/compose"
  10. "github.com/rancher/os/config"
  11. "github.com/rancher/os/log"
  12. "github.com/rancher/os/util"
  13. "github.com/rancher/os/util/network"
  14. )
  15. type projectFactory struct {
  16. }
  17. func (p *projectFactory) Create(c *cli.Context) (project.APIProject, error) {
  18. cfg := config.LoadConfig()
  19. return compose.GetProject(cfg, true, false)
  20. }
  21. func beforeApp(c *cli.Context) error {
  22. if c.GlobalBool("verbose") {
  23. log.SetLevel(log.DebugLevel)
  24. }
  25. return nil
  26. }
  27. func Commands() cli.Command {
  28. factory := &projectFactory{}
  29. app := cli.Command{}
  30. app.Name = "service"
  31. app.ShortName = "s"
  32. app.Before = beforeApp
  33. app.Flags = append(dockerApp.DockerClientFlags(), cli.BoolFlag{
  34. Name: "verbose,debug",
  35. })
  36. app.Subcommands = append(serviceSubCommands(),
  37. command.BuildCommand(factory),
  38. command.CreateCommand(factory),
  39. command.UpCommand(factory),
  40. command.StartCommand(factory),
  41. command.LogsCommand(factory),
  42. command.RestartCommand(factory),
  43. command.StopCommand(factory),
  44. command.RmCommand(factory),
  45. command.PullCommand(factory),
  46. command.KillCommand(factory),
  47. command.PsCommand(factory),
  48. )
  49. return app
  50. }
  51. func serviceSubCommands() []cli.Command {
  52. return []cli.Command{
  53. {
  54. Name: "enable",
  55. Usage: "turn on an service",
  56. Action: enable,
  57. },
  58. {
  59. Name: "disable",
  60. Usage: "turn off an service",
  61. Action: disable,
  62. },
  63. {
  64. Name: "list",
  65. Usage: "list services and state",
  66. Action: list,
  67. },
  68. {
  69. Name: "delete",
  70. Usage: "delete a service",
  71. Action: del,
  72. },
  73. }
  74. }
  75. func updateIncludedServices(cfg *config.CloudConfig) error {
  76. return config.Set("rancher.services_include", cfg.Rancher.ServicesInclude)
  77. }
  78. func disable(c *cli.Context) error {
  79. changed := false
  80. cfg := config.LoadConfig()
  81. for _, service := range c.Args() {
  82. validateService(service, cfg)
  83. if _, ok := cfg.Rancher.ServicesInclude[service]; !ok {
  84. continue
  85. }
  86. cfg.Rancher.ServicesInclude[service] = false
  87. changed = true
  88. }
  89. if changed {
  90. if err := updateIncludedServices(cfg); err != nil {
  91. log.Fatal(err)
  92. }
  93. }
  94. return nil
  95. }
  96. func del(c *cli.Context) error {
  97. changed := false
  98. cfg := config.LoadConfig()
  99. for _, service := range c.Args() {
  100. validateService(service, cfg)
  101. if _, ok := cfg.Rancher.ServicesInclude[service]; !ok {
  102. continue
  103. }
  104. delete(cfg.Rancher.ServicesInclude, service)
  105. changed = true
  106. }
  107. if changed {
  108. if err := updateIncludedServices(cfg); err != nil {
  109. log.Fatal(err)
  110. }
  111. }
  112. return nil
  113. }
  114. func enable(c *cli.Context) error {
  115. cfg := config.LoadConfig()
  116. var enabledServices []string
  117. for _, service := range c.Args() {
  118. validateService(service, cfg)
  119. if val, ok := cfg.Rancher.ServicesInclude[service]; !ok || !val {
  120. if isLocal(service) && !strings.HasPrefix(service, "/var/lib/rancher/conf") {
  121. log.Fatalf("ERROR: Service should be in path /var/lib/rancher/conf")
  122. }
  123. cfg.Rancher.ServicesInclude[service] = true
  124. enabledServices = append(enabledServices, service)
  125. }
  126. }
  127. if len(enabledServices) > 0 {
  128. if err := compose.StageServices(cfg, enabledServices...); err != nil {
  129. log.Fatal(err)
  130. }
  131. if err := updateIncludedServices(cfg); err != nil {
  132. log.Fatal(err)
  133. }
  134. }
  135. return nil
  136. }
  137. func list(c *cli.Context) error {
  138. cfg := config.LoadConfig()
  139. clone := make(map[string]bool)
  140. for service, enabled := range cfg.Rancher.ServicesInclude {
  141. clone[service] = enabled
  142. }
  143. services := availableService(cfg)
  144. for _, service := range services {
  145. if enabled, ok := clone[service]; ok {
  146. delete(clone, service)
  147. if enabled {
  148. fmt.Printf("enabled %s\n", service)
  149. } else {
  150. fmt.Printf("disabled %s\n", service)
  151. }
  152. } else {
  153. fmt.Printf("disabled %s\n", service)
  154. }
  155. }
  156. for service, enabled := range clone {
  157. if enabled {
  158. fmt.Printf("enabled %s\n", service)
  159. } else {
  160. fmt.Printf("disabled %s\n", service)
  161. }
  162. }
  163. return nil
  164. }
  165. func isLocal(service string) bool {
  166. return strings.HasPrefix(service, "/")
  167. }
  168. func IsLocalOrURL(service string) bool {
  169. return isLocal(service) || strings.HasPrefix(service, "http:/") || strings.HasPrefix(service, "https:/")
  170. }
  171. func validateService(service string, cfg *config.CloudConfig) {
  172. services := availableService(cfg)
  173. if !IsLocalOrURL(service) && !util.Contains(services, service) {
  174. log.Fatalf("%s is not a valid service", service)
  175. }
  176. }
  177. func availableService(cfg *config.CloudConfig) []string {
  178. services, err := network.GetServices(cfg.Rancher.Repositories.ToArray())
  179. if err != nil {
  180. log.Fatalf("Failed to get services: %v", err)
  181. }
  182. return services
  183. }