// DeviceScanType gets the configured device scan type. func DeviceScanType(config gofig.Config) types.DeviceScanType { return types.ParseDeviceScanType(config.GetInt(types.ConfigDeviceScanType)) }
// Run runs the executor CLI. func Run() { args := os.Args if len(args) < 3 { printUsageAndExit() } d, err := registry.NewStorageExecutor(args[1]) if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } driverName := strings.ToLower(d.Name()) config, err := apiconfig.NewConfig() if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } apiconfig.UpdateLogLevel(config) ctx := context.Background() if err := d.Init(ctx, config); err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } cmd := cmdRx.FindString(args[2]) if cmd == "" { printUsageAndExit() } store := utils.NewStore() var ( result interface{} op string exitCode int ) if strings.EqualFold(cmd, apitypes.LSXCmdSupported) { op = "supported" if dws, ok := d.(apitypes.StorageExecutorWithSupported); ok { opResult, opErr := dws.Supported(ctx, store) if opErr != nil { err = opErr } else { result = opResult } } else { err = apitypes.ErrNotImplemented } } else if strings.EqualFold(cmd, apitypes.LSXCmdInstanceID) { op = "instance ID" opResult, opErr := d.InstanceID(ctx, store) if opErr != nil { err = opErr } else { opResult.Driver = driverName result = opResult } } else if strings.EqualFold(cmd, apitypes.LSXCmdNextDevice) { op = "next device" opResult, opErr := d.NextDevice(ctx, store) if opErr != nil && opErr != apitypes.ErrNotImplemented { err = opErr } else { result = opResult } } else if strings.EqualFold(cmd, apitypes.LSXCmdLocalDevices) { if len(args) < 4 { printUsageAndExit() } op = "local devices" opResult, opErr := d.LocalDevices(ctx, &apitypes.LocalDevicesOpts{ ScanType: apitypes.ParseDeviceScanType(args[3]), Opts: store, }) opResult.Driver = driverName if opErr != nil { err = opErr } else { result = opResult } } else if strings.EqualFold(cmd, apitypes.LSXCmdWaitForDevice) { if len(args) < 5 { printUsageAndExit() } op = "wait" opts := &apitypes.WaitForDeviceOpts{ LocalDevicesOpts: apitypes.LocalDevicesOpts{ ScanType: apitypes.ParseDeviceScanType(args[3]), Opts: store, }, Token: strings.ToLower(args[4]), Timeout: utils.DeviceAttachTimeout(args[5]), } ldl := func() (bool, *apitypes.LocalDevices, error) { ldm, err := d.LocalDevices(ctx, &opts.LocalDevicesOpts) if err != nil { return false, nil, err } for k := range ldm.DeviceMap { if strings.ToLower(k) == opts.Token { return true, ldm, nil } } return false, ldm, nil } var ( found bool opErr error opResult *apitypes.LocalDevices timeoutC = time.After(opts.Timeout) tick = time.Tick(500 * time.Millisecond) ) TimeoutLoop: for { select { case <-timeoutC: exitCode = apitypes.LSXExitCodeTimedOut break TimeoutLoop case <-tick: if found, opResult, opErr = ldl(); found || opErr != nil { break TimeoutLoop } } } if opErr != nil { err = opErr } else { opResult.Driver = driverName result = opResult } } if err != nil { // if the function is not implemented then exit with // apitypes.LSXExitCodeNotImplemented to let callers // know that the function is unsupported on this system exitCode = 1 if strings.EqualFold(err.Error(), apitypes.ErrNotImplemented.Error()) { exitCode = apitypes.LSXExitCodeNotImplemented } fmt.Fprintf(os.Stderr, "error: error getting %s: %v\n", op, err) os.Exit(exitCode) } switch tr := result.(type) { case bool: fmt.Fprintf(os.Stdout, "%v", result) case string: fmt.Fprintln(os.Stdout, result) case encoding.TextMarshaler: buf, err := tr.MarshalText() if err != nil { fmt.Fprintf(os.Stderr, "error: error encoding %s: %v\n", op, err) os.Exit(1) } os.Stdout.Write(buf) default: buf, err := json.Marshal(result) if err != nil { fmt.Fprintf(os.Stderr, "error: error encoding %s: %v\n", op, err) os.Exit(1) } if isNullBuf(buf) { os.Stdout.Write(emptyJSONBuff) } else { os.Stdout.Write(buf) } } os.Exit(exitCode) }