github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/cmd/puppeth/wizard_intro.go (about)

     1  // This file is part of the go-sberex library. The go-sberex library is 
     2  // free software: you can redistribute it and/or modify it under the terms 
     3  // of the GNU Lesser General Public License as published by the Free 
     4  // Software Foundation, either version 3 of the License, or (at your option)
     5  // any later version.
     6  //
     7  // The go-sberex library is distributed in the hope that it will be useful, 
     8  // but WITHOUT ANY WARRANTY; without even the implied warranty of
     9  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 
    10  // General Public License <http://www.gnu.org/licenses/> for more details.
    11  
    12  package main
    13  
    14  import (
    15  	"bufio"
    16  	"encoding/json"
    17  	"fmt"
    18  	"io/ioutil"
    19  	"os"
    20  	"path/filepath"
    21  	"strings"
    22  	"sync"
    23  
    24  	"github.com/Sberex/go-sberex/log"
    25  )
    26  
    27  // makeWizard creates and returns a new puppeth wizard.
    28  func makeWizard(network string) *wizard {
    29  	return &wizard{
    30  		network: network,
    31  		conf: config{
    32  			Servers: make(map[string][]byte),
    33  		},
    34  		servers:  make(map[string]*sshClient),
    35  		services: make(map[string][]string),
    36  		in:       bufio.NewReader(os.Stdin),
    37  	}
    38  }
    39  
    40  // run displays some useful infos to the user, starting on the journey of
    41  // setting up a new or managing an existing Sberex private network.
    42  func (w *wizard) run() {
    43  	fmt.Println("+-----------------------------------------------------------+")
    44  	fmt.Println("| Welcome to puppeth, your Sberex private network manager   |")
    45  	fmt.Println("|                                                           |")
    46  	fmt.Println("| This tool lets you create a new Sberex network down to    |")
    47  	fmt.Println("| the genesis block, bootnodes, miners and ethstats servers |")
    48  	fmt.Println("| without the hassle that it would normally entail.         |")
    49  	fmt.Println("|                                                           |")
    50  	fmt.Println("| Puppeth uses SSH to dial in to remote servers, and builds |")
    51  	fmt.Println("| its network components out of Docker containers using the |")
    52  	fmt.Println("| docker-compose toolset.                                   |")
    53  	fmt.Println("+-----------------------------------------------------------+")
    54  	fmt.Println()
    55  
    56  	// Make sure we have a good network name to work with	fmt.Println()
    57  	// Docker accepts hyphens in image names, but doesn't like it for container names
    58  	if w.network == "" {
    59  		fmt.Println("Please specify a network name to administer (no spaces or hyphens, please)")
    60  		for {
    61  			w.network = w.readString()
    62  			if !strings.Contains(w.network, " ") && !strings.Contains(w.network, "-") {
    63  				fmt.Printf("\nSweet, you can set this via --network=%s next time!\n\n", w.network)
    64  				break
    65  			}
    66  			log.Error("I also like to live dangerously, still no spaces or hyphens")
    67  		}
    68  	}
    69  	log.Info("Administering Sberex network", "name", w.network)
    70  
    71  	// Load initial configurations and connect to all live servers
    72  	w.conf.path = filepath.Join(os.Getenv("HOME"), ".puppeth", w.network)
    73  
    74  	blob, err := ioutil.ReadFile(w.conf.path)
    75  	if err != nil {
    76  		log.Warn("No previous configurations found", "path", w.conf.path)
    77  	} else if err := json.Unmarshal(blob, &w.conf); err != nil {
    78  		log.Crit("Previous configuration corrupted", "path", w.conf.path, "err", err)
    79  	} else {
    80  		// Dial all previously known servers concurrently
    81  		var pend sync.WaitGroup
    82  		for server, pubkey := range w.conf.Servers {
    83  			pend.Add(1)
    84  
    85  			go func(server string, pubkey []byte) {
    86  				defer pend.Done()
    87  
    88  				log.Info("Dialing previously configured server", "server", server)
    89  				client, err := dial(server, pubkey)
    90  				if err != nil {
    91  					log.Error("Previous server unreachable", "server", server, "err", err)
    92  				}
    93  				w.lock.Lock()
    94  				w.servers[server] = client
    95  				w.lock.Unlock()
    96  			}(server, pubkey)
    97  		}
    98  		pend.Wait()
    99  		w.networkStats()
   100  	}
   101  	// Basics done, loop ad infinitum about what to do
   102  	for {
   103  		fmt.Println()
   104  		fmt.Println("What would you like to do? (default = stats)")
   105  		fmt.Println(" 1. Show network stats")
   106  		if w.conf.Genesis == nil {
   107  			fmt.Println(" 2. Configure new genesis")
   108  		} else {
   109  			fmt.Println(" 2. Manage existing genesis")
   110  		}
   111  		if len(w.servers) == 0 {
   112  			fmt.Println(" 3. Track new remote server")
   113  		} else {
   114  			fmt.Println(" 3. Manage tracked machines")
   115  		}
   116  		if len(w.services) == 0 {
   117  			fmt.Println(" 4. Deploy network components")
   118  		} else {
   119  			fmt.Println(" 4. Manage network components")
   120  		}
   121  
   122  		choice := w.read()
   123  		switch {
   124  		case choice == "" || choice == "1":
   125  			w.networkStats()
   126  
   127  		case choice == "2":
   128  			if w.conf.Genesis == nil {
   129  				w.makeGenesis()
   130  			} else {
   131  				w.manageGenesis()
   132  			}
   133  		case choice == "3":
   134  			if len(w.servers) == 0 {
   135  				if w.makeServer() != "" {
   136  					w.networkStats()
   137  				}
   138  			} else {
   139  				w.manageServers()
   140  			}
   141  		case choice == "4":
   142  			if len(w.services) == 0 {
   143  				w.deployComponent()
   144  			} else {
   145  				w.manageComponents()
   146  			}
   147  
   148  		default:
   149  			log.Error("That's not something I can do")
   150  		}
   151  	}
   152  }