github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/cmd/puppeth/module_ethstats.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  	"bytes"
    29  	"fmt"
    30  	"math/rand"
    31  	"path/filepath"
    32  	"strconv"
    33  	"strings"
    34  	"text/template"
    35  
    36  	"github.com/ethereum/go-ethereum/log"
    37  )
    38  
    39  //ethstatsDockerfile是构建ethstats后端所需的Dockerfile。
    40  //以及相关的监测站点。
    41  var ethstatsDockerfile = `
    42  FROM puppeth/ethstats:latest
    43  
    44  RUN echo 'module.exports = {trusted: [{{.Trusted}}], banned: [{{.Banned}}], reserved: ["yournode"]};' > lib/utils/config.js
    45  `
    46  
    47  //ethstatscomposefile是部署和
    48  //维护一个ethstats监控站点。
    49  var ethstatsComposefile = `
    50  version: '2'
    51  services:
    52    ethstats:
    53      build: .
    54      image: {{.Network}}/ethstats{{if not .VHost}}
    55      ports:
    56        - "{{.Port}}:3000"{{end}}
    57      environment:
    58        - WS_SECRET={{.Secret}}{{if .VHost}}
    59        - VIRTUAL_HOST={{.VHost}}{{end}}{{if .Banned}}
    60        - BANNED={{.Banned}}{{end}}
    61      logging:
    62        driver: "json-file"
    63        options:
    64          max-size: "1m"
    65          max-file: "10"
    66      restart: always
    67  `
    68  
    69  //deployethstats通过ssh将新的ethstats容器部署到远程计算机,
    70  //Docker和Docker组合。如果具有指定网络名称的实例
    71  //已经存在,将被覆盖!
    72  func deployEthstats(client *sshClient, network string, port int, secret string, vhost string, trusted []string, banned []string, nocache bool) ([]byte, error) {
    73  //生成要上载到服务器的内容
    74  	workdir := fmt.Sprintf("%d", rand.Int63())
    75  	files := make(map[string][]byte)
    76  
    77  	trustedLabels := make([]string, len(trusted))
    78  	for i, address := range trusted {
    79  		trustedLabels[i] = fmt.Sprintf("\"%s\"", address)
    80  	}
    81  	bannedLabels := make([]string, len(banned))
    82  	for i, address := range banned {
    83  		bannedLabels[i] = fmt.Sprintf("\"%s\"", address)
    84  	}
    85  
    86  	dockerfile := new(bytes.Buffer)
    87  	template.Must(template.New("").Parse(ethstatsDockerfile)).Execute(dockerfile, map[string]interface{}{
    88  		"Trusted": strings.Join(trustedLabels, ", "),
    89  		"Banned":  strings.Join(bannedLabels, ", "),
    90  	})
    91  	files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
    92  
    93  	composefile := new(bytes.Buffer)
    94  	template.Must(template.New("").Parse(ethstatsComposefile)).Execute(composefile, map[string]interface{}{
    95  		"Network": network,
    96  		"Port":    port,
    97  		"Secret":  secret,
    98  		"VHost":   vhost,
    99  		"Banned":  strings.Join(banned, ","),
   100  	})
   101  	files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
   102  
   103  //将部署文件上载到远程服务器(然后清理)
   104  	if out, err := client.Upload(files); err != nil {
   105  		return out, err
   106  	}
   107  	defer client.Run("rm -rf " + workdir)
   108  
   109  //构建和部署ethstats服务
   110  	if nocache {
   111  		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))
   112  	}
   113  	return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network))
   114  }
   115  
   116  //ethstatsInfo从ethstats状态检查返回以允许报告
   117  //各种配置参数。
   118  type ethstatsInfos struct {
   119  	host   string
   120  	port   int
   121  	secret string
   122  	config string
   123  	banned []string
   124  }
   125  
   126  //报表将类型化结构转换为纯字符串->字符串映射,其中包含
   127  //大多数(但不是全部)字段用于向用户报告。
   128  func (info *ethstatsInfos) Report() map[string]string {
   129  	return map[string]string{
   130  		"Website address":       info.host,
   131  		"Website listener port": strconv.Itoa(info.port),
   132  		"Login secret":          info.secret,
   133  		"Banned addresses":      strings.Join(info.banned, "\n"),
   134  	}
   135  }
   136  
   137  //check ethstats对ethstats服务器执行运行状况检查,以验证
   138  //它正在运行,如果是,收集有关它的有用信息。
   139  func checkEthstats(client *sshClient, network string) (*ethstatsInfos, error) {
   140  //检查主机上可能的ethstats容器
   141  	infos, err := inspectContainer(client, fmt.Sprintf("%s_ethstats_1", network))
   142  	if err != nil {
   143  		return nil, err
   144  	}
   145  	if !infos.running {
   146  		return nil, ErrServiceOffline
   147  	}
   148  //从主机或反向代理解析端口
   149  	port := infos.portmap["3000/tcp"]
   150  	if port == 0 {
   151  		if proxy, _ := checkNginx(client, network); proxy != nil {
   152  			port = proxy.port
   153  		}
   154  	}
   155  	if port == 0 {
   156  		return nil, ErrNotExposed
   157  	}
   158  //从反向代理解析主机并配置连接字符串
   159  	host := infos.envvars["VIRTUAL_HOST"]
   160  	if host == "" {
   161  		host = client.server
   162  	}
   163  	secret := infos.envvars["WS_SECRET"]
   164  	config := fmt.Sprintf("%s@%s", secret, host)
   165  	if port != 80 && port != 443 {
   166  		config += fmt.Sprintf(":%d", port)
   167  	}
   168  //检索IP黑名单
   169  	banned := strings.Split(infos.envvars["BANNED"], ",")
   170  
   171  //运行健全检查以查看端口是否可访问
   172  	if err = checkPort(host, port); err != nil {
   173  		log.Warn("Ethstats service seems unreachable", "server", host, "port", port, "err", err)
   174  	}
   175  //容器可用,组装并返回有用的信息
   176  	return &ethstatsInfos{
   177  		host:   host,
   178  		port:   port,
   179  		secret: secret,
   180  		config: config,
   181  		banned: banned,
   182  	}, nil
   183  }