github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/cmd/puppeth/wizard_intro.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:33</date>
    10  //</624450070019837952>
    11  
    12  
    13  package main
    14  
    15  import (
    16  	"bufio"
    17  	"encoding/json"
    18  	"fmt"
    19  	"io/ioutil"
    20  	"os"
    21  	"path/filepath"
    22  	"strings"
    23  	"sync"
    24  
    25  	"github.com/ethereum/go-ethereum/log"
    26  )
    27  
    28  //
    29  func makeWizard(network string) *wizard {
    30  	return &wizard{
    31  		network: network,
    32  		conf: config{
    33  			Servers: make(map[string][]byte),
    34  		},
    35  		servers:  make(map[string]*sshClient),
    36  		services: make(map[string][]string),
    37  		in:       bufio.NewReader(os.Stdin),
    38  	}
    39  }
    40  
    41  //
    42  //
    43  func (w *wizard) run() {
    44  	fmt.Println("+-----------------------------------------------------------+")
    45  	fmt.Println("| Welcome to puppeth, your Ethereum private network manager |")
    46  	fmt.Println("|                                                           |")
    47  	fmt.Println("| This tool lets you create a new Ethereum network down to  |")
    48  	fmt.Println("| the genesis block, bootnodes, miners and ethstats servers |")
    49  	fmt.Println("| without the hassle that it would normally entail.         |")
    50  	fmt.Println("|                                                           |")
    51  	fmt.Println("| Puppeth uses SSH to dial in to remote servers, and builds |")
    52  	fmt.Println("| its network components out of Docker containers using the |")
    53  	fmt.Println("| docker-compose toolset.                                   |")
    54  	fmt.Println("+-----------------------------------------------------------+")
    55  	fmt.Println()
    56  
    57  //确保我们有一个好的网络名称来使用fmt.println()。
    58  //Docker接受图像名称中的连字符,但不喜欢容器名称中的连字符
    59  	if w.network == "" {
    60  		fmt.Println("Please specify a network name to administer (no spaces, hyphens or capital letters please)")
    61  		for {
    62  			w.network = w.readString()
    63  			if !strings.Contains(w.network, " ") && !strings.Contains(w.network, "-") && strings.ToLower(w.network) == w.network {
    64  				fmt.Printf("\nSweet, you can set this via --network=%s next time!\n\n", w.network)
    65  				break
    66  			}
    67  			log.Error("I also like to live dangerously, still no spaces, hyphens or capital letters")
    68  		}
    69  	}
    70  	log.Info("Administering Ethereum network", "name", w.network)
    71  
    72  //加载初始配置并连接到所有活动服务器
    73  	w.conf.path = filepath.Join(os.Getenv("HOME"), ".puppeth", w.network)
    74  
    75  	blob, err := ioutil.ReadFile(w.conf.path)
    76  	if err != nil {
    77  		log.Warn("No previous configurations found", "path", w.conf.path)
    78  	} else if err := json.Unmarshal(blob, &w.conf); err != nil {
    79  		log.Crit("Previous configuration corrupted", "path", w.conf.path, "err", err)
    80  	} else {
    81  //同时拨打所有以前已知的服务器
    82  		var pend sync.WaitGroup
    83  		for server, pubkey := range w.conf.Servers {
    84  			pend.Add(1)
    85  
    86  			go func(server string, pubkey []byte) {
    87  				defer pend.Done()
    88  
    89  				log.Info("Dialing previously configured server", "server", server)
    90  				client, err := dial(server, pubkey)
    91  				if err != nil {
    92  					log.Error("Previous server unreachable", "server", server, "err", err)
    93  				}
    94  				w.lock.Lock()
    95  				w.servers[server] = client
    96  				w.lock.Unlock()
    97  			}(server, pubkey)
    98  		}
    99  		pend.Wait()
   100  		w.networkStats()
   101  	}
   102  //基本完成了,无限循环关于该做什么
   103  	for {
   104  		fmt.Println()
   105  		fmt.Println("What would you like to do? (default = stats)")
   106  		fmt.Println(" 1. Show network stats")
   107  		if w.conf.Genesis == nil {
   108  			fmt.Println(" 2. Configure new genesis")
   109  		} else {
   110  			fmt.Println(" 2. Manage existing genesis")
   111  		}
   112  		if len(w.servers) == 0 {
   113  			fmt.Println(" 3. Track new remote server")
   114  		} else {
   115  			fmt.Println(" 3. Manage tracked machines")
   116  		}
   117  		if len(w.services) == 0 {
   118  			fmt.Println(" 4. Deploy network components")
   119  		} else {
   120  			fmt.Println(" 4. Manage network components")
   121  		}
   122  
   123  		choice := w.read()
   124  		switch {
   125  		case choice == "" || choice == "1":
   126  			w.networkStats()
   127  
   128  		case choice == "2":
   129  			if w.conf.Genesis == nil {
   130  				fmt.Println()
   131  				fmt.Println("What would you like to do? (default = create)")
   132  				fmt.Println(" 1. Create new genesis from scratch")
   133  				fmt.Println(" 2. Import already existing genesis")
   134  
   135  				choice := w.read()
   136  				switch {
   137  				case choice == "" || choice == "1":
   138  					w.makeGenesis()
   139  				case choice == "2":
   140  					w.importGenesis()
   141  				default:
   142  					log.Error("That's not something I can do")
   143  				}
   144  			} else {
   145  				w.manageGenesis()
   146  			}
   147  		case choice == "3":
   148  			if len(w.servers) == 0 {
   149  				if w.makeServer() != "" {
   150  					w.networkStats()
   151  				}
   152  			} else {
   153  				w.manageServers()
   154  			}
   155  		case choice == "4":
   156  			if len(w.services) == 0 {
   157  				w.deployComponent()
   158  			} else {
   159  				w.manageComponents()
   160  			}
   161  		default:
   162  			log.Error("That's not something I can do")
   163  		}
   164  	}
   165  }
   166