module_nginx.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright 2017 The go-ethereum Authors
  2. // This file is part of go-ethereum.
  3. //
  4. // go-ethereum is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // go-ethereum is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
  16. package main
  17. import (
  18. "bytes"
  19. "fmt"
  20. "html/template"
  21. "math/rand"
  22. "path/filepath"
  23. "strconv"
  24. "github.com/ethereum/go-ethereum/log"
  25. )
  26. // nginxDockerfile is theis the Dockerfile required to build an nginx reverse-
  27. // proxy.
  28. var nginxDockerfile = `FROM jwilder/nginx-proxy`
  29. // nginxComposefile is the docker-compose.yml file required to deploy and maintain
  30. // an nginx reverse-proxy. The proxy is responsible for exposing one or more HTTP
  31. // services running on a single host.
  32. var nginxComposefile = `
  33. version: '2'
  34. services:
  35. nginx:
  36. build: .
  37. image: {{.Network}}/nginx
  38. ports:
  39. - "{{.Port}}:80"
  40. volumes:
  41. - /var/run/docker.sock:/tmp/docker.sock:ro
  42. logging:
  43. driver: "json-file"
  44. options:
  45. max-size: "1m"
  46. max-file: "10"
  47. restart: always
  48. `
  49. // deployNginx deploys a new nginx reverse-proxy container to expose one or more
  50. // HTTP services running on a single host. If an instance with the specified
  51. // network name already exists there, it will be overwritten!
  52. func deployNginx(client *sshClient, network string, port int, nocache bool) ([]byte, error) {
  53. log.Info("Deploying nginx reverse-proxy", "server", client.server, "port", port)
  54. // Generate the content to upload to the server
  55. workdir := fmt.Sprintf("%d", rand.Int63())
  56. files := make(map[string][]byte)
  57. dockerfile := new(bytes.Buffer)
  58. template.Must(template.New("").Parse(nginxDockerfile)).Execute(dockerfile, nil)
  59. files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
  60. composefile := new(bytes.Buffer)
  61. template.Must(template.New("").Parse(nginxComposefile)).Execute(composefile, map[string]interface{}{
  62. "Network": network,
  63. "Port": port,
  64. })
  65. files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
  66. // Upload the deployment files to the remote server (and clean up afterwards)
  67. if out, err := client.Upload(files); err != nil {
  68. return out, err
  69. }
  70. defer client.Run("rm -rf " + workdir)
  71. // Build and deploy the reverse-proxy service
  72. if nocache {
  73. return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate", workdir, network, network))
  74. }
  75. return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate", workdir, network))
  76. }
  77. // nginxInfos is returned from an nginx reverse-proxy status check to allow
  78. // reporting various configuration parameters.
  79. type nginxInfos struct {
  80. port int
  81. }
  82. // Report converts the typed struct into a plain string->string map, containing
  83. // most - but not all - fields for reporting to the user.
  84. func (info *nginxInfos) Report() map[string]string {
  85. return map[string]string{
  86. "Shared listener port": strconv.Itoa(info.port),
  87. }
  88. }
  89. // checkNginx does a health-check against an nginx reverse-proxy to verify whether
  90. // it's running, and if yes, gathering a collection of useful infos about it.
  91. func checkNginx(client *sshClient, network string) (*nginxInfos, error) {
  92. // Inspect a possible nginx container on the host
  93. infos, err := inspectContainer(client, fmt.Sprintf("%s_nginx_1", network))
  94. if err != nil {
  95. return nil, err
  96. }
  97. if !infos.running {
  98. return nil, ErrServiceOffline
  99. }
  100. // Container available, assemble and return the useful infos
  101. return &nginxInfos{
  102. port: infos.portmap["80/tcp"],
  103. }, nil
  104. }