service.go 4.7 KB

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