func dial(x *cli.Context) *client.Client { var dialAddr string switch { case x.IsSet("dial"): dialAddr = x.String("dial") case os.Getenv("CIRCUIT") != "": buf, err := ioutil.ReadFile(os.Getenv("CIRCUIT")) if err != nil { fatalf("circuit environment file %s is not readable: %v", os.Getenv("CIRCUIT"), err) } dialAddr = strings.TrimSpace(string(buf)) default: buf, err := ioutil.ReadFile(".circuit") if err != nil { fatalf("no dial address available; use flag -d or set CIRCUIT to a file name") } dialAddr = strings.TrimSpace(string(buf)) } defer func() { if r := recover(); r != nil { fatalf("addressed server is gone or a newer one is in place") } }() return client.Dial(dialAddr) }
func main() { // The first argument is the circuit server address that this execution will use. c := client.Dial(os.Args[1], nil) // Fire-off n payload processes. ch := make(chan int) for i := 0; i < n; i++ { cmd := client.Cmd{ Path: "/bin/sleep", Args: []string{strconv.Itoa(3 + i*3)}, } i_ := i go func() { // Pick a random circuit server to run payload on. t := pickServer(c).Walk([]string{"wait-all", strconv.Itoa(i_)}) // Execute the process and store it in the anchor. p, _ := t.MakeProc(cmd) // Close the process standard input to indicte no intention to write data. p.Stdin().Close() // Block until the process exits. p.Wait() // Notify the unifying waiting logic. ch <- 1 // Remove the anchor storing the process. t.Scrub() println("Payload", i_+1, "finished.") }() } // Wait for all payload processes to complete. for i := 0; i < n; i++ { <-ch } println("All done.") }
// connect establishes a client connection to the circuit cluster (via the given circuit server address) // and returns a connected client object. func connect(addr string) *client.Client { defer func() { if r := recover(); r != nil { fatalf("could not connect: %v", r) } }() return client.Dial(addr, nil) }
func dial(x *cli.Context) *client.Client { switch { case x.IsSet("dial"): defer func() { if r := recover(); r != nil { fatalf("addressed server is gone or authentication failed") } }() return client.Dial(x.String("dial"), readkey(x)) case x.IsSet("discover"): defer func() { if r := recover(); r != nil { fatalf("multicast address is unresponsive or authentication failed") } }() return client.DialDiscover(x.String("discover"), readkey(x)) case os.Getenv("CIRCUIT") != "": buf, err := ioutil.ReadFile(os.Getenv("CIRCUIT")) if err != nil { fatalf("circuit environment file %s is not readable: %v", os.Getenv("CIRCUIT"), err) } defer func() { if r := recover(); r != nil { fatalf("addressed server is gone or authentication failed") } }() return client.Dial(strings.TrimSpace(string(buf)), readkey(x)) case os.Getenv("CIRCUIT_DISCOVER") != "": defer func() { if r := recover(); r != nil { fatalf("multicast address is unresponsive or authentication failed") } }() return client.DialDiscover(os.Getenv("CIRCUIT_DISCOVER"), readkey(x)) } fatalf("no dial or discovery addresses available; use -dial or -discover") panic(0) }
func main() { // The first argument is the circuit server address that this execution will use. c := client.Dial(os.Args[1]) // if len(os.Args) == 3 { waitFotPayloadDeath(c, os.Args[2]) } // Start the payload process service := client.Cmd{ Path: "/usr/bin/say", // say is a standard OSX command which speaks, so it's easy to hear the virus in action. Args: []string{"i am a virus"}, } // Randomly choose a circuit server to host the virus payload. a := pickServer(c) // Run the payload pservice, _ := a.Walk([]string{"virus", "payload"}).MakeProc(service) if err := pservice.Peek().Exit; err != nil { println("payload not started:", err.Error()) return } // Close the standard input of the virus to indicate no intention to write data. pservice.Stdin().Close() // Start the virus nucleus process, which will wait until the payload completes, // and then start a payload as well as a new nucleus elsewhere, over and over again. b := pickServer(c) virus, _ := filepath.Abs(os.Args[0]) // We assume that the virus binary is on the same path everywhere nucleus := client.Cmd{ Path: virus, Args: []string{b.Addr(), "/" + a.Worker() + "/virus"}, } pnucleus, _ := b.Walk([]string{"virus", "nucleus"}).MakeProc(nucleus) if err := pnucleus.Peek().Exit; err != nil { println("nucleus not started:", err.Error()) return } pnucleus.Stdin().Close() }
// The initial invocation of the virus: // virus DIALIN_CIRCUIT // To invoke the virus in the role of a nucleus process: // virus DIALIN_CIRCUIT PAYLOAD_ANCHOR SELF_ANCHOR // func main() { var payloadAnchor, nucleusAnchor string switch len(os.Args) { case 2: // initial command-line invocation case 4: // invocation in role of nucleus payloadAnchor = os.Args[2] nucleusAnchor = os.Args[3] default: println("usage: virus circuit://...") os.Exit(1) } println("virus dialing into", os.Args[1]) c := client.Dial(os.Args[1], nil) // The nucleus role waits for the payload process to die before it proceeds. if nucleusAnchor != "" { waitFotPayloadDeath(c, payloadAnchor) c.Walk(client.Split(nucleusAnchor)).Scrub() // remove anchor pointing to us } spawnNucleus(c, spawnPayload(c)) }
// The initial invocation of the virus: // virus DIALIN_CIRCUIT // To invoke the virus in the role of a nucleus process: // virus DIALIN_CIRCUIT BACKCHAN_ANCHOR PAYLOAD_ANCHOR SELF_ANCHOR EPOCH // func main() { // Parse arguments var ( err error isNucleus bool myAnchor string payloadAnchor string epoch int ) switch len(os.Args) { case 2: // initial command-line invocation case 6: // invocation in role of nucleus isNucleus = true myAnchor = os.Args[4] payloadAnchor = os.Args[3] epoch, err = strconv.Atoi(os.Args[5]) if err != nil { panic(err) } default: println("usage: virus circuit://...") os.Exit(1) } println("virus nucleus epoch", epoch, "dialing into", os.Args[1]) c := client.Dial(os.Args[1], nil) // Create/get back channel backAnchor, backChan := findBackChan(c, isNucleus) // Acquire permission to send to back channel acquireBackChan(c, backChan, epoch) // The nucleus role waits for the payload process to die before it proceeds. if isNucleus { waitFotPayloadDeath(c, myAnchor, payloadAnchor, epoch) } payloadAnchor = spawnPayload(c, epoch) spawnNucleus(c, backAnchor, payloadAnchor, epoch) }