func waitForJob(client *wsman.Client, jobinfo *dom.Element) bool { jobID := string(search.First(search.Attr("Name", "*", "InstanceID"), jobinfo.All()).Content) log.Printf("%s: Waiting for job %s to finish\n", client.Endpoint(), jobID) var code string ret := false for { time.Sleep(10 * time.Second) msg := client.Get("http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LifecycleJob") msg.Selectors("InstanceID", jobID) res, err := msg.Send() if err != nil { log.Printf("Error monitoring job: %v\n", err) if res != nil { log.Printf("Response: %s\n", res.String()) } goto out } code = strings.TrimSpace( string(search.First( search.Tag("JobStatus", "*"), res.AllBodyElements()).Content)) switch code { case "Completed": ret = true goto out case "Completed with Errors": goto out case "Failed": goto out } } out: log.Printf("Job %s finished with %s\n", jobID, code) return ret }
func getBootNic(client *wsman.Client, nics []*dom.Element) *dom.Element { fqdds := []string{} for _, nic := range nics { n := search.First(search.Tag("FQDD", "*"), nic.Children()) if n == nil { log.Printf("Nic did not contain an FQDD") os.Exit(1) } fqdd := string(n.Content) // Only care about integrated nics if !strings.HasPrefix(fqdd, "NIC.Integrated.") { log.Printf("%s is not integrated, skipping\n", fqdd) continue } speed := search.First(search.Tag("LinkSpeed", "*"), nic.Children()) // If there is not speed setting, then the server is too old to report it. // Happily enough, that also means it is too old for 10 gig ports to be a thing. if speed != nil && string(speed.Content) != "3" { log.Printf("%s is not a gigabit Ethernet port\n", fqdd) continue } fqdds = append(fqdds, fqdd) } if len(fqdds) < 1 { log.Printf("No integrated 1 GB nics!") os.Exit(1) } sort.Strings(fqdds) bootnic := fqdds[0] result := search.First(search.Content([]byte(bootnic)), nics[0].Parent().All()).Parent() if result == nil { log.Printf("Unable to find NIC with FQDD %s\n", bootnic) return nil } // Now, make sure it can PXE boot msg := client.Get("http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_NICEnumeration") msg.Selectors("InstanceID", bootnic+":LegacyBootProto") res, err := msg.Send() if err != nil { log.Printf("Error checking whether %s can PXE boot: %v\n", bootnic, err) return result } currentval := string(search.First(search.Tag("CurrentValue", "*"), res.AllBodyElements()).Content) if currentval == "PXE" { return result } msg = client.Invoke("http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_NICService", "SetAttribute") msg.Selectors( "SystemCreationClassName", "DCIM_ComputerSystem", "CreationClassName", "DCIM_NICService", "SystemName", "DCIM:ComputerSystem", "Name", "DCIM:NICService") msg.Parameters( "Target", bootnic, "AttributeName", "LegacyBootProto", "AttributeValue", "PXE") res, err = msg.Send() if err != nil { log.Printf("Error ensuring %s can PXE boot: %v\n", bootnic, err) return result } retvals := search.First(search.Tag("SetAttribute_OUTPUT", "*"), res.AllBodyElements()) if retvals == nil { log.Printf("Method invocation result did not return an output element!\n%s\n", res.String()) return result } code := search.First(search.Tag("ReturnValue", "*"), retvals.Children()) if string(code.Content) != "0" { log.Printf("Error ensuring NIC %s can PXE boot:\n%s\n", bootnic, res.String()) return result } needReboot := string(search.First(search.Tag("RebootRequired", "*"), retvals.Children()).Content) if needReboot != "Yes" { return result } // Create the config job. msg = client.Invoke("http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_NICService", "CreateTargetedConfigJob") msg.Selectors( "SystemCreationClassName", "DCIM_ComputerSystem", "CreationClassName", "DCIM_NICService", "SystemName", "DCIM:ComputerSystem", "Name", "DCIM:NICService") msg.Parameters( "Target", bootnic, "RebootJobType", "1", "ScheduledStartTime", "TIME_NOW") res, err = msg.Send() if err != nil { log.Printf("Error ensuring %s can PXE boot: %v\n", bootnic, err) return result } retvals = search.First(search.Tag("CreateTargetedConfigJob_OUTPUT", "*"), res.AllBodyElements()) if retvals == nil { log.Printf("Method invocation result did not return an output element!\n%s\n", res.String()) return result } code = search.First(search.Tag("ReturnValue", "*"), retvals.Children()) if string(code.Content) != "4096" { log.Printf("Error ensuring NIC %s can PXE boot:\n%s\n", bootnic, res.String()) return result } job_service := search.First(search.Tag("ReferenceParameters", "*"), res.AllBodyElements()) if job_service == nil { log.Printf("Did not get job info back!") return result } waitForJob(client, job_service) return result }