github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/cmd/puppeth/module.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2017 Go Ethereum作者 10 //此文件是Go以太坊的一部分。 11 // 12 //Go以太坊是免费软件:您可以重新发布和/或修改它 13 //根据GNU通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊的分布希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU通用公共许可证了解更多详细信息。 21 // 22 //你应该已经收到一份GNU通用公共许可证的副本 23 //一起去以太坊吧。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package main 26 27 import ( 28 "encoding/json" 29 "errors" 30 "fmt" 31 "net" 32 "strconv" 33 "strings" 34 "time" 35 36 "github.com/ethereum/go-ethereum/log" 37 ) 38 39 var ( 40 //当服务容器不存在时,返回errServiceUnknown。 41 ErrServiceUnknown = errors.New("service unknown") 42 43 //存在服务容器时返回errServiceOffline,但不存在 44 //跑步。 45 ErrServiceOffline = errors.New("service offline") 46 47 //当服务容器正在运行时返回errServiceUnreachable,但是 48 //似乎对沟通尝试没有反应。 49 ErrServiceUnreachable = errors.New("service unreachable") 50 51 //如果Web服务没有公开的端口,则返回errnotexposed,或者 52 //它前面的反向代理来转发请求。 53 ErrNotExposed = errors.New("service not exposed, nor proxied") 54 ) 55 56 //ContainerInfos是大型检验数据集的一个大大简化的版本。 57 //从Docker-Inspect返回,被puppeth解析成易于使用的形式。 58 type containerInfos struct { 59 running bool //标记容器当前是否正在运行 60 envvars map[string]string //容器上设置的环境变量集合 61 portmap map[string]int //从内部端口/协议组合到主机绑定的端口映射 62 volumes map[string]string //从容器到主机目录的卷装入点 63 } 64 65 //InspectContainer运行Docker根据正在运行的容器进行检查 66 func inspectContainer(client *sshClient, container string) (*containerInfos, error) { 67 //检查是否有正在运行服务的容器 68 out, err := client.Run(fmt.Sprintf("docker inspect %s", container)) 69 if err != nil { 70 return nil, ErrServiceUnknown 71 } 72 //如果是,则提取各种配置选项 73 type inspection struct { 74 State struct { 75 Running bool 76 } 77 Mounts []struct { 78 Source string 79 Destination string 80 } 81 Config struct { 82 Env []string 83 } 84 HostConfig struct { 85 PortBindings map[string][]map[string]string 86 } 87 } 88 var inspects []inspection 89 if err = json.Unmarshal(out, &inspects); err != nil { 90 return nil, err 91 } 92 inspect := inspects[0] 93 94 //检索到的信息,将上面的内容解析为有意义的内容 95 infos := &containerInfos{ 96 running: inspect.State.Running, 97 envvars: make(map[string]string), 98 portmap: make(map[string]int), 99 volumes: make(map[string]string), 100 } 101 for _, envvar := range inspect.Config.Env { 102 if parts := strings.Split(envvar, "="); len(parts) == 2 { 103 infos.envvars[parts[0]] = parts[1] 104 } 105 } 106 for portname, details := range inspect.HostConfig.PortBindings { 107 if len(details) > 0 { 108 port, _ := strconv.Atoi(details[0]["HostPort"]) 109 infos.portmap[portname] = port 110 } 111 } 112 for _, mount := range inspect.Mounts { 113 infos.volumes[mount.Destination] = mount.Source 114 } 115 return infos, err 116 } 117 118 //TearDown通过ssh连接到远程计算机并终止Docker容器 119 //在指定网络中以指定名称运行。 120 func tearDown(client *sshClient, network string, service string, purge bool) ([]byte, error) { 121 //拆下正在运行(或暂停)的容器 122 out, err := client.Run(fmt.Sprintf("docker rm -f %s_%s_1", network, service)) 123 if err != nil { 124 return out, err 125 } 126 //如果需要,也清除关联的Docker映像 127 if purge { 128 return client.Run(fmt.Sprintf("docker rmi %s/%s", network, service)) 129 } 130 return nil, nil 131 } 132 133 //resolve通过返回 134 //实际的服务器名称和端口,或者最好是nginx虚拟主机(如果可用)。 135 func resolve(client *sshClient, network string, service string, port int) (string, error) { 136 //检查服务以从中获取各种配置 137 infos, err := inspectContainer(client, fmt.Sprintf("%s_%s_1", network, service)) 138 if err != nil { 139 return "", err 140 } 141 if !infos.running { 142 return "", ErrServiceOffline 143 } 144 //在线容器,提取任何环境变量 145 if vhost := infos.envvars["VIRTUAL_HOST"]; vhost != "" { 146 return vhost, nil 147 } 148 return fmt.Sprintf("%s:%d", client.server, port), nil 149 } 150 151 //checkport尝试连接到给定主机上的远程主机 152 func checkPort(host string, port int) error { 153 log.Trace("Verifying remote TCP connectivity", "server", host, "port", port) 154 conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", host, port), time.Second) 155 if err != nil { 156 return err 157 } 158 conn.Close() 159 return nil 160 }