github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/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 12:09:31</date>
    10  //</624342604443553792>
    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  //
    58  //
    59  	if w.network == "" {
    60  		fmt.Println("Please specify a network name to administer (no spaces or hyphens, please)")
    61  		for {
    62  			w.network = w.readString()
    63  			if !strings.Contains(w.network, " ") && !strings.Contains(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 or hyphens")
    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  				w.makeGenesis()
   131  			} else {
   132  				w.manageGenesis()
   133  			}
   134  		case choice == "3":
   135  			if len(w.servers) == 0 {
   136  				if w.makeServer() != "" {
   137  					w.networkStats()
   138  				}
   139  			} else {
   140  				w.manageServers()
   141  			}
   142  		case choice == "4":
   143  			if len(w.services) == 0 {
   144  				w.deployComponent()
   145  			} else {
   146  				w.manageComponents()
   147  			}
   148  
   149  		default:
   150  			log.Error("That's not something I can do")
   151  		}
   152  	}
   153  }
   154