urbit.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. package docker
  2. // start up urbits
  3. import (
  4. "fmt"
  5. "goseg/config"
  6. "goseg/defaults"
  7. "goseg/structs"
  8. "io/ioutil"
  9. "path/filepath"
  10. "github.com/docker/docker/api/types/container"
  11. "github.com/docker/docker/api/types/mount"
  12. "github.com/docker/go-connections/nat"
  13. )
  14. // load existing urbits from config json
  15. func LoadUrbits() error {
  16. config.Logger.Info("Loading Urbit ships")
  17. // Loop through pier list
  18. conf := config.Conf()
  19. for _, pier := range conf.Piers {
  20. config.Logger.Info(fmt.Sprintf("Loading pier %s", pier))
  21. // load json into struct
  22. err := config.LoadUrbitConfig(pier)
  23. if err != nil {
  24. config.Logger.Error(fmt.Sprintf("Error loading %s config: %v", pier, err))
  25. continue
  26. }
  27. shipConf := config.UrbitConf(pier)
  28. // don't bootstrap if it's busted
  29. if shipConf.BootStatus != "noboot" {
  30. info, err := StartContainer(pier, "vere")
  31. if err != nil {
  32. config.Logger.Error(fmt.Sprintf("Error starting %s: %v", pier, err))
  33. continue
  34. }
  35. config.UpdateContainerState(pier, info)
  36. }
  37. }
  38. return nil
  39. }
  40. // urbit container config builder
  41. func urbitContainerConf(containerName string) (container.Config, container.HostConfig, error) {
  42. var containerConfig container.Config
  43. var hostConfig container.HostConfig
  44. var scriptContent string
  45. // construct the container metadata from version server info
  46. containerInfo, err := GetLatestContainerInfo("vere")
  47. if err != nil {
  48. return containerConfig, hostConfig, err
  49. }
  50. desiredImage := fmt.Sprintf("%s:%s@sha256:%s", containerInfo["repo"], containerInfo["tag"], containerInfo["hash"])
  51. // reload urbit conf from disk
  52. err = config.LoadUrbitConfig(containerName)
  53. if err != nil {
  54. errmsg := fmt.Errorf("Error loading %s config: %v", containerName, err)
  55. return containerConfig, hostConfig, errmsg
  56. }
  57. // put in memory
  58. shipConf := config.UrbitConf(containerName)
  59. // todo: this BootStatus doesnt actually have anythin to do with pack and meld right now
  60. act := shipConf.BootStatus
  61. // get the correct startup script based on BootStatus val
  62. switch act {
  63. case "boot":
  64. scriptContent = defaults.StartScript
  65. case "pack":
  66. scriptContent = defaults.PackScript
  67. case "meld":
  68. scriptContent = defaults.MeldScript
  69. case "prep":
  70. scriptContent = defaults.PrepScript
  71. case "noboot":
  72. return containerConfig, hostConfig, fmt.Errorf("%s marked noboot!", containerName)
  73. default:
  74. return containerConfig, hostConfig, fmt.Errorf("Unknown action: %s", act)
  75. }
  76. // reset ship status to boot for next time
  77. if act != "boot" {
  78. updateUrbitConf := shipConf
  79. updateUrbitConf.BootStatus = "boot"
  80. var newConfig map[string]structs.UrbitDocker
  81. newConfig[containerName] = updateUrbitConf
  82. err = config.UpdateUrbitConfig(newConfig)
  83. if err != nil {
  84. config.Logger.Warn("Unable to reset %s boot script!", containerName)
  85. }
  86. }
  87. // write the script
  88. scriptPath := filepath.Join(config.DockerDir, containerName, "_data", containerName, "start_urbit.sh")
  89. err = ioutil.WriteFile(scriptPath, []byte(scriptContent), 0755) // make the script executable
  90. if err != nil {
  91. return containerConfig, hostConfig, fmt.Errorf("Failed to write script: %v", err)
  92. }
  93. // gather boot option values
  94. shipName := shipConf.PierName
  95. loomValue := string(shipConf.LoomSize)
  96. dirnameValue := shipConf.PierName
  97. var devMode string
  98. if shipConf.DevMode == true {
  99. devMode = "True"
  100. } else {
  101. devMode = "False"
  102. }
  103. // construct the network configuration based on conf val
  104. var httpPort string
  105. var amesPort string
  106. var network string
  107. var portMap nat.PortMap
  108. if shipConf.Network == "wireguard" {
  109. httpPort = string(shipConf.WgHTTPPort)
  110. amesPort = string(shipConf.WgAmesPort)
  111. network = "container:wireguard"
  112. } else {
  113. httpPort = string(shipConf.HTTPPort)
  114. amesPort = string(shipConf.AmesPort)
  115. network = "default"
  116. httpPortStr := nat.Port(fmt.Sprintf(httpPort + "/tcp"))
  117. amesPortStr := nat.Port(fmt.Sprintf(amesPort + "/udp"))
  118. portMap = nat.PortMap{
  119. httpPortStr: []nat.PortBinding{
  120. {HostIP: "0.0.0.0", HostPort: httpPort},
  121. },
  122. amesPortStr: []nat.PortBinding{
  123. {HostIP: "0.0.0.0", HostPort: amesPort},
  124. },
  125. }
  126. }
  127. // finally construct the container config structs
  128. containerConfig = container.Config{
  129. Image: desiredImage,
  130. Entrypoint: []string{scriptPath, shipName, "--loom=" + loomValue, "--dirname=" + dirnameValue, "--dev-mode=" + devMode, "--http-port=" + httpPort, "--port=" + amesPort},
  131. }
  132. mounts := []mount.Mount{
  133. {
  134. Type: mount.TypeBind,
  135. Source: shipName,
  136. Target: "/urbit",
  137. },
  138. }
  139. hostConfig = container.HostConfig{
  140. NetworkMode: container.NetworkMode(network),
  141. Mounts: mounts,
  142. PortBindings: portMap,
  143. }
  144. return containerConfig, hostConfig, nil
  145. }