go.dedis.ch/onet/v4@v4.0.0-pre1/simul/platform/deterlab_users/users.go (about) 1 package main 2 3 import ( 4 "flag" 5 "strings" 6 "sync" 7 "time" 8 9 "os" 10 "os/exec" 11 "regexp" 12 "runtime" 13 "strconv" 14 15 "go.dedis.ch/onet/v4" 16 "go.dedis.ch/onet/v4/log" 17 "go.dedis.ch/onet/v4/simul/monitor" 18 "go.dedis.ch/onet/v4/simul/platform" 19 ) 20 21 var kill = false 22 var suite string 23 24 func init() { 25 flag.BoolVar(&kill, "kill", false, "kill everything (and don't start anything)") 26 flag.StringVar(&suite, "suite", "ed25519", "suite used for simulation") 27 } 28 29 // DeterlabUsers is called on the users.deterlab.net-server and will: 30 // - copy the simulation-files to the server 31 // - start the simulation 32 func main() { 33 // init with deter.toml 34 deter := deterFromConfig() 35 flag.Parse() 36 37 // kill old processes 38 var wg sync.WaitGroup 39 re := regexp.MustCompile(" +") 40 hosts, err := exec.Command("/usr/testbed/bin/node_list", "-e", deter.Project+","+deter.Experiment).Output() 41 if err != nil { 42 log.Fatal("Deterlab experiment", deter.Project+"/"+deter.Experiment, "seems not to be swapped in. Aborting.") 43 os.Exit(-1) 44 } 45 hostsTrimmed := strings.TrimSpace(re.ReplaceAllString(string(hosts), " ")) 46 hostlist := strings.Split(hostsTrimmed, " ") 47 doneHosts := make([]bool, len(hostlist)) 48 log.Lvl2("Found the following hosts:", hostlist) 49 if kill { 50 log.Lvl1("Cleaning up", len(hostlist), "hosts.") 51 } 52 for i, h := range hostlist { 53 wg.Add(1) 54 go func(i int, h string) { 55 defer wg.Done() 56 if kill { 57 log.Lvl3("Cleaning up host", h, ".") 58 runSSH(h, "sudo killall -9 simul scp 2>/dev/null >/dev/null") 59 time.Sleep(1 * time.Second) 60 runSSH(h, "sudo killall -9 simul 2>/dev/null >/dev/null") 61 time.Sleep(1 * time.Second) 62 // Also kill all other process that start with "./" and are probably 63 // locally started processes 64 runSSH(h, "sudo pkill -9 -f '\\./'") 65 time.Sleep(1 * time.Second) 66 if log.DebugVisible() > 3 { 67 log.Lvl4("Cleaning report:") 68 _ = platform.SSHRunStdout("", h, "ps aux") 69 } 70 } else { 71 log.Lvl3("Setting the file-limit higher on", h) 72 73 // Copy configuration file to make higher file-limits 74 err := platform.SSHRunStdout("", h, "sudo cp remote/simul.conf /etc/security/limits.d") 75 if err != nil { 76 log.Fatal("Couldn't copy limit-file:", err) 77 } 78 } 79 doneHosts[i] = true 80 log.Lvl3("Host", h, "cleaned up") 81 }(i, h) 82 } 83 84 cleanupChannel := make(chan string) 85 go func() { 86 wg.Wait() 87 log.Lvl3("Done waiting") 88 cleanupChannel <- "done" 89 }() 90 select { 91 case msg := <-cleanupChannel: 92 log.Lvl3("Received msg from cleanupChannel", msg) 93 case <-time.After(time.Second * 20): 94 for i, m := range doneHosts { 95 if !m { 96 log.Lvl1("Missing host:", hostlist[i], "- You should run") 97 log.Lvl1("/usr/testbed/bin/node_reboot", hostlist[i]) 98 } 99 } 100 log.Fatal("Didn't receive all replies while cleaning up - aborting.") 101 } 102 103 if kill { 104 log.Lvl2("Only cleaning up - returning") 105 return 106 } 107 108 // ADDITIONS : the monitoring part 109 // Proxy will listen on Sink:SinkPort and redirect every packet to 110 // RedirectionAddress:SinkPort-1. With remote tunnel forwarding it will 111 // be forwarded to the real sink 112 addr, port := deter.ProxyAddress, uint16(deter.MonitorPort+1) 113 log.Lvl2("Launching proxy redirecting to", addr, ":", port) 114 prox, err := monitor.NewProxy(uint16(deter.MonitorPort), addr, port) 115 if err != nil { 116 log.Fatal("Couldn't start proxy:", err) 117 } 118 go prox.Run() 119 120 log.Lvl1("starting", deter.Servers, "cothorities for a total of", deter.Hosts, "processes.") 121 killing := false 122 for i, phys := range deter.Phys { 123 log.Lvl2("Launching simul on", phys) 124 wg.Add(1) 125 go func(phys, internal string) { 126 //log.Lvl4("running on", phys, cmd) 127 defer wg.Done() 128 monitorAddr := deter.MonitorAddress + ":" + strconv.Itoa(deter.MonitorPort) 129 log.Lvl4("Starting servers on physical machine ", internal, "with monitor = ", 130 monitorAddr) 131 132 // If PreScript is defined, run the appropriate script _before_ the simulation. 133 if deter.PreScript != "" { 134 err := platform.SSHRunStdout("", phys, "cd remote; sudo ./"+deter.PreScript+" deterlab") 135 if err != nil { 136 log.Fatal("error deploying PreScript: ", err) 137 } 138 } 139 args := " -address=" + internal + 140 " -simul=" + deter.Simulation + 141 " -monitor=" + monitorAddr + 142 " -debug=" + strconv.Itoa(log.DebugVisible()) + 143 " -suite=" + suite 144 log.Lvl3("Args is", args) 145 err := platform.SSHRunStdout("", phys, "cd remote; sudo ./simul "+ 146 args) 147 if err != nil && !killing { 148 log.Lvl1("Error starting simul - will kill all others:", err, internal) 149 killing = true 150 err := exec.Command("killall", "ssh").Run() 151 if err != nil { 152 log.Fatal("Couldn't killall ssh:", err) 153 } 154 } 155 log.Lvl4("Finished with simul on", internal) 156 }(phys, deter.Virt[i]) 157 } 158 159 // wait for the servers to finish before stopping 160 wg.Wait() 161 prox.Stop() 162 } 163 164 // Reads in the deterlab-config and drops out if there is an error 165 func deterFromConfig(name ...string) *platform.Deterlab { 166 d := &platform.Deterlab{} 167 configName := "deter.toml" 168 if len(name) > 0 { 169 configName = name[0] 170 } 171 err := onet.ReadTomlConfig(d, configName) 172 _, caller, line, _ := runtime.Caller(1) 173 who := caller + ":" + strconv.Itoa(line) 174 if err != nil { 175 log.Fatal("Couldn't read config in", who, ":", err) 176 } 177 log.SetDebugVisible(d.Debug) 178 return d 179 } 180 181 // Runs a command on the remote host and outputs an eventual error if debug level >= 3 182 func runSSH(host, cmd string) { 183 if _, err := platform.SSHRun("", host, cmd); err != nil { 184 log.Lvlf3("Host %s got error %s while running [%s]", host, err.Error(), cmd) 185 } 186 }