service.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package service
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/rancher/os/cmd/control/service/command"
  6. "github.com/rancher/os/config"
  7. "github.com/rancher/os/pkg/compose"
  8. "github.com/rancher/os/pkg/log"
  9. "github.com/rancher/os/pkg/util"
  10. "github.com/rancher/os/pkg/util/network"
  11. "github.com/codegangsta/cli"
  12. dockerApp "github.com/docker/libcompose/cli/docker/app"
  13. "github.com/docker/libcompose/project"
  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. Flags: []cli.Flag{
  67. cli.BoolFlag{
  68. Name: "all, a",
  69. Usage: "list all services and state",
  70. },
  71. },
  72. Action: list,
  73. },
  74. {
  75. Name: "delete",
  76. Usage: "delete a service",
  77. Action: del,
  78. },
  79. }
  80. }
  81. func updateIncludedServices(cfg *config.CloudConfig) error {
  82. return config.Set("rancher.services_include", cfg.Rancher.ServicesInclude)
  83. }
  84. func disable(c *cli.Context) error {
  85. changed := false
  86. cfg := config.LoadConfig()
  87. for _, service := range c.Args() {
  88. validateService(service, cfg)
  89. if _, ok := cfg.Rancher.ServicesInclude[service]; !ok {
  90. continue
  91. }
  92. cfg.Rancher.ServicesInclude[service] = false
  93. changed = true
  94. }
  95. if changed {
  96. if err := updateIncludedServices(cfg); err != nil {
  97. log.Fatal(err)
  98. }
  99. }
  100. return nil
  101. }
  102. func del(c *cli.Context) error {
  103. changed := false
  104. cfg := config.LoadConfig()
  105. for _, service := range c.Args() {
  106. validateService(service, cfg)
  107. if _, ok := cfg.Rancher.ServicesInclude[service]; !ok {
  108. continue
  109. }
  110. delete(cfg.Rancher.ServicesInclude, service)
  111. changed = true
  112. }
  113. if changed {
  114. if err := updateIncludedServices(cfg); err != nil {
  115. log.Fatal(err)
  116. }
  117. }
  118. return nil
  119. }
  120. func enable(c *cli.Context) error {
  121. cfg := config.LoadConfig()
  122. var enabledServices []string
  123. for _, service := range c.Args() {
  124. validateService(service, cfg)
  125. if val, ok := cfg.Rancher.ServicesInclude[service]; !ok || !val {
  126. if isLocal(service) && !strings.HasPrefix(service, "/var/lib/rancher/conf") {
  127. log.Fatalf("ERROR: Service should be in path /var/lib/rancher/conf")
  128. }
  129. cfg.Rancher.ServicesInclude[service] = true
  130. enabledServices = append(enabledServices, service)
  131. }
  132. }
  133. if len(enabledServices) > 0 {
  134. if err := compose.StageServices(cfg, enabledServices...); err != nil {
  135. log.Fatal(err)
  136. }
  137. if err := updateIncludedServices(cfg); err != nil {
  138. log.Fatal(err)
  139. }
  140. }
  141. return nil
  142. }
  143. func list(c *cli.Context) error {
  144. cfg := config.LoadConfig()
  145. clone := make(map[string]bool)
  146. for service, enabled := range cfg.Rancher.ServicesInclude {
  147. clone[service] = enabled
  148. }
  149. services := availableService(cfg)
  150. if c.Bool("all") {
  151. for service := range cfg.Rancher.Services {
  152. fmt.Printf("enabled %s\n", service)
  153. }
  154. }
  155. for _, service := range services {
  156. if enabled, ok := clone[service]; ok {
  157. delete(clone, service)
  158. if enabled {
  159. fmt.Printf("enabled %s\n", service)
  160. } else {
  161. fmt.Printf("disabled %s\n", service)
  162. }
  163. } else {
  164. fmt.Printf("disabled %s\n", service)
  165. }
  166. }
  167. for service, enabled := range clone {
  168. if enabled {
  169. fmt.Printf("enabled %s\n", service)
  170. } else {
  171. fmt.Printf("disabled %s\n", service)
  172. }
  173. }
  174. return nil
  175. }
  176. func isLocal(service string) bool {
  177. return strings.HasPrefix(service, "/")
  178. }
  179. func IsLocalOrURL(service string) bool {
  180. return isLocal(service) || strings.HasPrefix(service, "http:/") || strings.HasPrefix(service, "https:/")
  181. }
  182. // ValidService checks to see if the service definition exists
  183. func ValidService(service string, cfg *config.CloudConfig) bool {
  184. services := availableService(cfg)
  185. if !IsLocalOrURL(service) && !util.Contains(services, service) {
  186. return false
  187. }
  188. return true
  189. }
  190. func validateService(service string, cfg *config.CloudConfig) {
  191. if !ValidService(service, cfg) {
  192. log.Fatalf("%s is not a valid service", service)
  193. }
  194. }
  195. func availableService(cfg *config.CloudConfig) []string {
  196. services, err := network.GetServices(cfg.Rancher.Repositories.ToArray())
  197. if err != nil {
  198. log.Fatalf("Failed to get services: %v", err)
  199. }
  200. return services
  201. }