Exemplo n.º 1
0
// serve starts the libStorage server, blocking the current thread until the
// server is shutdown.
//
//   char*  host    the golang network-style address. if no value is provided
//                  then a random TCP port bound to localhost is used
//
//   short  argc    the length of the argv array
//
//   void*  argv    a pointer to an array of char* strings that represent the
//                  drivers and corresponding service names to load. if the
//                  array is odd-numbered then the service for the trailing
//                  driver takes the name of the driver
//
// char* serve(char* host, int argc, void* argv);
//export serve
func serve(
	host *C.char, argc C.int, argv unsafe.Pointer) *C.char {

	iargc := int(argc)
	args := make([]string, iargc)
	pargv := argv

	for x := 0; x < iargc; x++ {
		gostr := C.GoString((*C.char)(pargv))
		log.WithFields(log.Fields{
			"x":     x,
			"gostr": gostr,
		}).Info("parsed gostr")
		args[x] = gostr
		pargv = unsafe.Pointer(uintptr(pargv) + unsafe.Sizeof(gostr))
	}

	szHost := C.GoString(host)

	log.WithFields(log.Fields{
		"host": szHost,
		"args": args,
	}).Info("serving")

	config, err := apicfg.NewConfig()
	if err != nil {
		return C.CString(err.Error())
	}

	if len(szHost) > 0 {
		os.Setenv("LIBSTORAGE_HOST", szHost)
	}

	_, errs, err := server.Serve(nil, config)
	if err != nil {
		return C.CString(err.Error())
	}

	<-errs
	return nil
}
Exemplo n.º 2
0
// Run the server.
func Run() {
	server.CloseOnAbort()

	flag.Usage = printUsage
	flag.Parse()

	if flagVersion != nil && *flagVersion {
		_, _, thisExeAbsPath := gotil.GetThisPathParts()
		fmt.Fprintf(os.Stdout, "Binary: %s\n", thisExeAbsPath)
		fmt.Fprint(os.Stdout, api.Version.String())
		os.Exit(0)
	}

	if flagEnv != nil && *flagEnv {
		for _, v := range os.Environ() {
			fmt.Fprintf(os.Stdout, "%s\n", v)
		}
		os.Exit(0)
	}

	// if a config is specified then do not care about any other options
	if flagConfig != nil && gotil.FileExists(*flagConfig) {

		config = gofigCore.New()

		if err := config.ReadConfigFile(*flagConfig); err != nil {
			fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err)
			os.Exit(1)
		}

		if flagPrintConfig != nil && *flagPrintConfig {
			jstr, err := config.ToJSON()
			if err != nil {
				fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err)
				os.Exit(1)
			}
			fmt.Fprintln(os.Stdout, jstr)
			os.Exit(0)
		}

		s, errs, err := server.Serve(nil, config)
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err)
			os.Exit(1)
		}

		err = <-errs
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err)
			os.Exit(1)
		}

		s.Close()
		os.Exit(0)
	}

	cfg, err := apiconfig.NewConfig()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err)
		os.Exit(1)
	}

	config = cfg
	for _, fs := range config.FlagSets() {
		flag.CommandLine.AddFlagSet(fs)
	}

	if flagHelp != nil && *flagHelp {
		flag.Usage()
	}

	if len(flag.Args()) == 0 {
		flag.Usage()
	}

	if flagHost != nil {
		os.Setenv("LIBSTORAGE_HOST", *flagHost)
	}

	if flagLogLvl != nil {
		os.Setenv("LIBSTORAGE_LOGGING_LEVEL", *flagLogLvl)
	}

	if lvl, err := log.ParseLevel(
		config.GetString(apitypes.ConfigLogLevel)); err == nil {
		log.SetLevel(lvl)
	}

	if flagPrintConfig != nil && *flagPrintConfig {
		jstr, err := config.ToJSON()
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err)
			os.Exit(1)
		}
		fmt.Fprintln(os.Stdout, jstr)
		os.Exit(0)
	}

	buf := &bytes.Buffer{}
	fmt.Fprintf(buf, "libstorage:\n  server:\n    services:\n")
	for _, ds := range flag.Args() {
		dsp := strings.Split(ds, ":")
		dn := dsp[0]
		sn := dsp[0]
		if len(dsp) > 1 {
			sn = dsp[1]
		}
		fmt.Fprintf(buf, "      %s:\n        driver: %s\n", sn, dn)
	}
	if err := config.ReadConfig(buf); err != nil {
		fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err)
		os.Exit(1)
	}

	server.CloseOnAbort()

	_, errs, err := server.Serve(nil, config)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err)
		os.Exit(1)
	}

	<-errs
}
Exemplo n.º 3
0
func (th *testHarness) run(
	t *testing.T,
	clientType types.ClientType,
	driver string,
	configBuf []byte,
	debug, group bool,
	tests ...APITestFunc) {

	if !testing.Verbose() {
		buf := &bytes.Buffer{}
		log.StandardLogger().Out = buf
		defer func() {
			if t.Failed() {
				io.Copy(os.Stderr, buf)
			}
		}()
	}

	wg := &sync.WaitGroup{}

	if group {
		config := getTestConfig(t, clientType, configBuf, debug)
		configNames, configs := getTestConfigs(t, driver, config)

		for x, config := range configs {

			wg.Add(1)
			go func(x int, config gofig.Config) {
				defer wg.Done()
				server, errs, err := apiserver.Serve(nil, config)
				if err != nil {
					th.closeServers(t)
					t.Fatal(err)
				}
				go func() {
					err := <-errs
					if err != nil {
						th.closeServers(t)
						t.Fatalf("server (%s) error: %v", configNames[x], err)
					}
				}()

				th.servers = append(th.servers, server)

				c, err := client.New(nil, config)
				assert.NoError(t, err)
				assert.NotNil(t, c)
				if err != nil || c == nil {
					t.Fatalf("err=%v, client=%v", err, c)
				}

				for _, test := range tests {
					test(config, c, t)

					if t.Failed() && printConfigOnFail {
						cj, err := config.ToJSON()
						if err != nil {
							t.Fatal(err)
						}
						fmt.Printf("client.config=%s\n", cj)
					}
				}
			}(x, config)
		}
	} else {
		for _, test := range tests {
			config := getTestConfig(t, clientType, configBuf, debug)
			configNames, configs := getTestConfigs(t, driver, config)

			for x, config := range configs {

				wg.Add(1)
				go func(test APITestFunc, x int, config gofig.Config) {

					defer wg.Done()
					server, errs, err := apiserver.Serve(nil, config)
					if err != nil {
						th.closeServers(t)
						t.Fatal(err)
					}
					go func() {
						err := <-errs
						if err != nil {
							th.closeServers(t)
							t.Fatalf("server (%s) error: %v", configNames[x], err)
						}
					}()

					th.servers = append(th.servers, server)

					c, err := client.New(nil, config)
					if err != nil {
						t.Fatal(err)
					}
					assert.NoError(t, err)
					assert.NotNil(t, c)

					if c == nil {
						panic(fmt.Sprintf("err=%v, client=%v", err, c))
					}

					test(config, c, t)

					if t.Failed() && printConfigOnFail {
						cj, err := config.ToJSON()
						if err != nil {
							t.Fatal(err)
						}
						fmt.Printf("client.config=%s\n", cj)
					}
				}(test, x, config)
			}
		}
	}

	wg.Wait()
	th.closeServers(t)
}
Exemplo n.º 4
0
func activateLibStorage(
	ctx apitypes.Context,
	config gofig.Config) (apitypes.Context, gofig.Config, <-chan error, error) {

	apiserver.DisableStartupInfo = true

	var (
		host          string
		err           error
		isRunning     bool
		errs          chan error
		serverErrChan <-chan error
		server        apitypes.Server
	)

	if host = config.GetString(apitypes.ConfigHost); host != "" {
		if !config.GetBool(apitypes.ConfigEmbedded) {
			ctx.WithField(
				"host", host,
			).Debug("not starting embedded server; embedded mode disabled")
			return ctx, config, nil, nil
		}
	}

	if host, isRunning = IsLocalServerActive(ctx, config); isRunning {
		ctx = setHost(ctx, config, host)
		ctx.WithField("host", host).Debug(
			"not starting embedded server; already running")
		return ctx, config, nil, nil
	}

	// if no host was specified then see if a set of default services need to
	// be initialized
	if host == "" {
		ctx.Debug("host is empty; initiliazing default services")
		if err = initDefaultLibStorageServices(ctx, config); err != nil {
			ctx.WithError(err).Error("error initializing default services")
			return ctx, config, nil, err
		}
	}

	ctx.Debug("starting embedded libStorage server")

	if server, serverErrChan, err = apiserver.Serve(ctx, config); err != nil {
		ctx.WithError(err).Error("error starting libStorage server")
		return ctx, config, nil, err
	}

	if host == "" {
		host = server.Addrs()[0]
		ctx.WithField("host", host).Debug("got host from new server address")
	}
	ctx = setHost(ctx, config, host)

	errs = make(chan error)
	go func() {
		for err := range serverErrChan {
			if err != nil {
				errs <- err
			}
		}
		if err := os.RemoveAll(SpecFilePath()); err == nil {
			logHostSpec(ctx, host, "removed spec file")
		}
		close(errs)
	}()

	// write the host to the spec file so that other rex-ray invocations can
	// find it, even if running as an embedded libStorage server
	if err := WriteSpecFile(host); err != nil {
		specFile := SpecFilePath()
		if os.IsPermission(err) {
			ctx.WithError(err).Errorf(
				"user does not have write permissions for %s", specFile)
		} else {
			ctx.WithError(err).Errorf(
				"error writing spec file at %s", specFile)
		}
		//WaitUntilLibStorageStopped(ctx, serverErrChan)
		return ctx, config, errs, err
	}
	logHostSpec(ctx, host, "created spec file")

	return ctx, config, errs, nil
}