github.com/myafeier/go-ethereum@v1.6.8-0.20170719123245-3e0dbe0eaa72/cmd/puppeth/wizard_network.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "fmt" 21 "strings" 22 23 "github.com/ethereum/go-ethereum/log" 24 ) 25 26 // manageServers displays a list of servers the user can disconnect from, and an 27 // option to connect to new servers. 28 func (w *wizard) manageServers() { 29 // List all the servers we can disconnect, along with an entry to connect a new one 30 fmt.Println() 31 32 servers := w.conf.servers() 33 for i, server := range servers { 34 fmt.Printf(" %d. Disconnect %s\n", i+1, server) 35 } 36 fmt.Printf(" %d. Connect another server\n", len(w.conf.Servers)+1) 37 38 choice := w.readInt() 39 if choice < 0 || choice > len(w.conf.Servers)+1 { 40 log.Error("Invalid server choice, aborting") 41 return 42 } 43 // If the user selected an existing server, drop it 44 if choice <= len(w.conf.Servers) { 45 server := servers[choice-1] 46 client := w.servers[server] 47 48 delete(w.servers, server) 49 if client != nil { 50 client.Close() 51 } 52 delete(w.conf.Servers, server) 53 w.conf.flush() 54 55 log.Info("Disconnected existing server", "server", server) 56 w.networkStats(false) 57 return 58 } 59 // If the user requested connecting a new server, do it 60 if w.makeServer() != "" { 61 w.networkStats(false) 62 } 63 } 64 65 // makeServer reads a single line from stdin and interprets it as a hostname to 66 // connect to. It tries to establish a new SSH session and also executing some 67 // baseline validations. 68 // 69 // If connection succeeds, the server is added to the wizards configs! 70 func (w *wizard) makeServer() string { 71 fmt.Println() 72 fmt.Println("Please enter remote server's address:") 73 74 for { 75 // Read and fial the server to ensure docker is present 76 input := w.readString() 77 78 client, err := dial(input, nil) 79 if err != nil { 80 log.Error("Server not ready for puppeth", "err", err) 81 return "" 82 } 83 // All checks passed, start tracking the server 84 w.servers[input] = client 85 w.conf.Servers[input] = client.pubkey 86 w.conf.flush() 87 88 return input 89 } 90 } 91 92 // selectServer lists the user all the currnetly known servers to choose from, 93 // also granting the option to add a new one. 94 func (w *wizard) selectServer() string { 95 // List the available server to the user and wait for a choice 96 fmt.Println() 97 fmt.Println("Which server do you want to interact with?") 98 99 servers := w.conf.servers() 100 for i, server := range servers { 101 fmt.Printf(" %d. %s\n", i+1, server) 102 } 103 fmt.Printf(" %d. Connect another server\n", len(w.conf.Servers)+1) 104 105 choice := w.readInt() 106 if choice < 0 || choice > len(w.conf.Servers)+1 { 107 log.Error("Invalid server choice, aborting") 108 return "" 109 } 110 // If the user requested connecting to a new server, go for it 111 if choice <= len(w.conf.Servers) { 112 return servers[choice-1] 113 } 114 return w.makeServer() 115 } 116 117 // manageComponents displays a list of network components the user can tear down 118 // and an option 119 func (w *wizard) manageComponents() { 120 // List all the componens we can tear down, along with an entry to deploy a new one 121 fmt.Println() 122 123 var serviceHosts, serviceNames []string 124 for server, services := range w.services { 125 for _, service := range services { 126 serviceHosts = append(serviceHosts, server) 127 serviceNames = append(serviceNames, service) 128 129 fmt.Printf(" %d. Tear down %s on %s\n", len(serviceHosts), strings.Title(service), server) 130 } 131 } 132 fmt.Printf(" %d. Deploy new network component\n", len(serviceHosts)+1) 133 134 choice := w.readInt() 135 if choice < 0 || choice > len(serviceHosts)+1 { 136 log.Error("Invalid component choice, aborting") 137 return 138 } 139 // If the user selected an existing service, destroy it 140 if choice <= len(serviceHosts) { 141 // Figure out the service to destroy and execute it 142 service := serviceNames[choice-1] 143 server := serviceHosts[choice-1] 144 client := w.servers[server] 145 146 if out, err := tearDown(client, w.network, service, true); err != nil { 147 log.Error("Failed to tear down component", "err", err) 148 if len(out) > 0 { 149 fmt.Printf("%s\n", out) 150 } 151 return 152 } 153 // Clean up any references to it from out state 154 services := w.services[server] 155 for i, name := range services { 156 if name == service { 157 w.services[server] = append(services[:i], services[i+1:]...) 158 if len(w.services[server]) == 0 { 159 delete(w.services, server) 160 } 161 } 162 } 163 log.Info("Torn down existing component", "server", server, "service", service) 164 return 165 } 166 // If the user requested deploying a new component, do it 167 w.deployComponent() 168 } 169 170 // deployComponent displays a list of network components the user can deploy and 171 // guides through the process. 172 func (w *wizard) deployComponent() { 173 // Print all the things we can deploy and wait or user choice 174 fmt.Println() 175 fmt.Println("What would you like to deploy? (recommended order)") 176 fmt.Println(" 1. Ethstats - Network monitoring tool") 177 fmt.Println(" 2. Bootnode - Entry point of the network") 178 fmt.Println(" 3. Sealer - Full node minting new blocks") 179 fmt.Println(" 4. Wallet - Browser wallet for quick sends (todo)") 180 fmt.Println(" 5. Faucet - Crypto faucet to give away funds") 181 fmt.Println(" 6. Dashboard - Website listing above web-services") 182 183 switch w.read() { 184 case "1": 185 w.deployEthstats() 186 case "2": 187 w.deployNode(true) 188 case "3": 189 w.deployNode(false) 190 case "4": 191 case "5": 192 w.deployFaucet() 193 case "6": 194 w.deployDashboard() 195 default: 196 log.Error("That's not something I can do") 197 } 198 }