github.hscsec.cn/scroll-tech/go-ethereum@v1.9.7/cmd/puppeth/module_nginx.go (about) 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 17 package main 18 19 import ( 20 "bytes" 21 "fmt" 22 "html/template" 23 "math/rand" 24 "path/filepath" 25 "strconv" 26 27 "github.com/ethereum/go-ethereum/log" 28 ) 29 30 // nginxDockerfile is theis the Dockerfile required to build an nginx reverse- 31 // proxy. 32 var nginxDockerfile = `FROM jwilder/nginx-proxy` 33 34 // nginxComposefile is the docker-compose.yml file required to deploy and maintain 35 // an nginx reverse-proxy. The proxy is responsible for exposing one or more HTTP 36 // services running on a single host. 37 var nginxComposefile = ` 38 version: '2' 39 services: 40 nginx: 41 build: . 42 image: {{.Network}}/nginx 43 container_name: {{.Network}}_nginx_1 44 ports: 45 - "{{.Port}}:80" 46 volumes: 47 - /var/run/docker.sock:/tmp/docker.sock:ro 48 logging: 49 driver: "json-file" 50 options: 51 max-size: "1m" 52 max-file: "10" 53 restart: always 54 ` 55 56 // deployNginx deploys a new nginx reverse-proxy container to expose one or more 57 // HTTP services running on a single host. If an instance with the specified 58 // network name already exists there, it will be overwritten! 59 func deployNginx(client *sshClient, network string, port int, nocache bool) ([]byte, error) { 60 log.Info("Deploying nginx reverse-proxy", "server", client.server, "port", port) 61 62 // Generate the content to upload to the server 63 workdir := fmt.Sprintf("%d", rand.Int63()) 64 files := make(map[string][]byte) 65 66 dockerfile := new(bytes.Buffer) 67 template.Must(template.New("").Parse(nginxDockerfile)).Execute(dockerfile, nil) 68 files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes() 69 70 composefile := new(bytes.Buffer) 71 template.Must(template.New("").Parse(nginxComposefile)).Execute(composefile, map[string]interface{}{ 72 "Network": network, 73 "Port": port, 74 }) 75 files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes() 76 77 // Upload the deployment files to the remote server (and clean up afterwards) 78 if out, err := client.Upload(files); err != nil { 79 return out, err 80 } 81 defer client.Run("rm -rf " + workdir) 82 83 // Build and deploy the reverse-proxy service 84 if nocache { 85 return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate --timeout 60", workdir, network, network)) 86 } 87 return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network)) 88 } 89 90 // nginxInfos is returned from an nginx reverse-proxy status check to allow 91 // reporting various configuration parameters. 92 type nginxInfos struct { 93 port int 94 } 95 96 // Report converts the typed struct into a plain string->string map, containing 97 // most - but not all - fields for reporting to the user. 98 func (info *nginxInfos) Report() map[string]string { 99 return map[string]string{ 100 "Shared listener port": strconv.Itoa(info.port), 101 } 102 } 103 104 // checkNginx does a health-check against an nginx reverse-proxy to verify whether 105 // it's running, and if yes, gathering a collection of useful infos about it. 106 func checkNginx(client *sshClient, network string) (*nginxInfos, error) { 107 // Inspect a possible nginx container on the host 108 infos, err := inspectContainer(client, fmt.Sprintf("%s_nginx_1", network)) 109 if err != nil { 110 return nil, err 111 } 112 if !infos.running { 113 return nil, ErrServiceOffline 114 } 115 // Container available, assemble and return the useful infos 116 return &nginxInfos{ 117 port: infos.portmap["80/tcp"], 118 }, nil 119 }