Example #1
0
// AddFlags adds configuration flags to the given FlagSet.
func (c *Config) AddFlags(fs *flag.FlagSet) {
	fs.StringVar(&c.ServerAddr, "http", c.ServerAddr, "Address in form of ip:port to listen on for HTTP")
	fs.StringVar(&c.TLSServerAddr, "https", c.TLSServerAddr, "Address in form of ip:port to listen on for HTTPS")
	fs.StringVar(&c.TLSCertFile, "cert", c.TLSCertFile, "X.509 certificate file for HTTPS server")
	fs.StringVar(&c.TLSKeyFile, "key", c.TLSKeyFile, "X.509 key file for HTTPS server")
	fs.StringVar(&c.APIPrefix, "api-prefix", c.APIPrefix, "URL prefix for API endpoints")
	fs.StringVar(&c.CORSOrigin, "cors-origin", c.CORSOrigin, "CORS origin API endpoints")
	fs.DurationVar(&c.ReadTimeout, "read-timeout", c.ReadTimeout, "Read timeout for HTTP and HTTPS client conns")
	fs.DurationVar(&c.WriteTimeout, "write-timeout", c.WriteTimeout, "Write timeout for HTTP and HTTPS client conns")
	fs.StringVar(&c.PublicDir, "public", c.PublicDir, "Public directory to serve at the {prefix}/ endpoint")
	fs.StringVar(&c.DB, "db", c.DB, "IP database file or URL")
	fs.DurationVar(&c.UpdateInterval, "update", c.UpdateInterval, "Database update check interval")
	fs.DurationVar(&c.RetryInterval, "retry", c.RetryInterval, "Max time to wait before retrying to download database")
	fs.BoolVar(&c.UseXForwardedFor, "use-x-forwarded-for", c.UseXForwardedFor, "Use the X-Forwarded-For header when available (e.g. behind proxy)")
	fs.BoolVar(&c.Silent, "silent", c.Silent, "Disable HTTP and HTTPS log request details")
	fs.BoolVar(&c.LogToStdout, "logtostdout", c.LogToStdout, "Log to stdout instead of stderr")
	fs.BoolVar(&c.LogTimestamp, "logtimestamp", c.LogTimestamp, "Prefix non-access logs with timestamp")
	fs.StringVar(&c.RedisAddr, "redis", c.RedisAddr, "Redis address in form of host:port[,host:port] for quota")
	fs.DurationVar(&c.RedisTimeout, "redis-timeout", c.RedisTimeout, "Redis read/write timeout")
	fs.StringVar(&c.MemcacheAddr, "memcache", c.MemcacheAddr, "Memcache address in form of host:port[,host:port] for quota")
	fs.DurationVar(&c.MemcacheTimeout, "memcache-timeout", c.MemcacheTimeout, "Memcache read/write timeout")
	fs.StringVar(&c.RateLimitBackend, "quota-backend", c.RateLimitBackend, "Backend for rate limiter: map, redis, or memcache")
	fs.Uint64Var(&c.RateLimitLimit, "quota-max", c.RateLimitLimit, "Max requests per source IP per interval; set 0 to turn quotas off")
	fs.DurationVar(&c.RateLimitInterval, "quota-interval", c.RateLimitInterval, "Quota expiration interval, per source IP querying the API")
	fs.StringVar(&c.InternalServerAddr, "internal-server", c.InternalServerAddr, "Address in form of ip:port to listen on for metrics and pprof")
}
Example #2
0
// ApplyWithError populates the flag given the flag set and environment
func (f Uint64Flag) ApplyWithError(set *flag.FlagSet) error {
	if f.EnvVar != "" {
		for _, envVar := range strings.Split(f.EnvVar, ",") {
			envVar = strings.TrimSpace(envVar)
			if envVal, ok := syscall.Getenv(envVar); ok {
				envValInt, err := strconv.ParseUint(envVal, 0, 64)
				if err != nil {
					return fmt.Errorf("could not parse %s as uint64 value for flag %s: %s", envVal, f.Name, err)
				}

				f.Value = uint64(envValInt)
				break
			}
		}
	}

	eachName(f.Name, func(name string) {
		if f.Destination != nil {
			set.Uint64Var(f.Destination, name, f.Value, f.Usage)
			return
		}
		set.Uint64(name, f.Value, f.Usage)
	})

	return nil
}
Example #3
0
File: parser.go Project: qiniu/dyn
func parseFlagArg(fv reflect.Value, f *flag.FlagSet, tag string) (err error) {

	n := 0
	for n < len(tag) {
		if tag[n] == ',' || tag[n] == ' ' {
			break
		}
		n++
	}

	name := tag[:n]
	usage := ""
	pos := strings.Index(tag[n:], " - ")
	if pos >= 0 {
		usage = tag[pos+3:]
	}

	switch fv.Kind() {
	case reflect.Ptr:
		switch fv.Elem().Kind() {
		case reflect.Bool:
			fv.Set(reflect.ValueOf(f.Bool(name, false, usage)))
		case reflect.Int:
			fv.Set(reflect.ValueOf(f.Int(name, 0, usage)))
		case reflect.Uint:
			fv.Set(reflect.ValueOf(f.Uint(name, 0, usage)))
		case reflect.Uint64:
			fv.Set(reflect.ValueOf(f.Uint64(name, 0, usage)))
		default:
			return ErrUnsupportedFlagType
		}
	case reflect.Bool:
		f.BoolVar(fv.Addr().Interface().(*bool), name, false, usage)
	case reflect.Int:
		f.IntVar(fv.Addr().Interface().(*int), name, 0, usage)
	case reflect.Uint:
		f.UintVar(fv.Addr().Interface().(*uint), name, 0, usage)
	case reflect.Uint64:
		f.Uint64Var(fv.Addr().Interface().(*uint64), name, 0, usage)
	default:
		return ErrUnsupportedFlagType
	}
	return nil
}
Example #4
0
// registerFlagStruct parse struct field, and register with flag set
func registerFlagStruct(i interface{}, fs *flag.FlagSet) error {
	if fs.Parsed() {
		return ErrFlagParsed
	}

	sf := structFields(i)
	for _, fd := range sf {
		field := fd.field

		flagName := fd.tag.name
		flagUsage := fd.tag.usage
		fieldPtr := unsafe.Pointer(fd.value.UnsafeAddr())

		switch field.Type.Kind() {
		case reflect.Int:
			fs.IntVar((*int)(fieldPtr), flagName, fd.tag.intValue(), flagUsage)
		case reflect.Int64:
			fs.Int64Var((*int64)(fieldPtr), flagName, fd.tag.int64Value(), flagUsage)
		case reflect.Uint:
			fs.UintVar((*uint)(fieldPtr), flagName, fd.tag.uintValue(), flagUsage)
		case reflect.Uint64:
			fs.Uint64Var((*uint64)(fieldPtr), flagName, fd.tag.uint64Value(), flagUsage)
		case reflect.String:
			fs.StringVar((*string)(fieldPtr), flagName, fd.tag.stringValue(), flagUsage)
		case reflect.Bool:
			fs.BoolVar((*bool)(fieldPtr), flagName, fd.tag.boolValue(), flagUsage)
		case reflect.Float64:
			fs.Float64Var((*float64)(fieldPtr), flagName, fd.tag.float64Value(), flagUsage)
		default:
			if !reflect.PtrTo(field.Type).Implements(flagValueType) {
				return ErrUnsupportType
			}

			fieldValue := reflect.NewAt(field.Type, fieldPtr)
			switch value := fieldValue.Interface().(type) {
			case flag.Value:
				fs.Var(value, flagName, flagUsage)
			}
		}
	}

	return nil
}
Example #5
0
File: flag.go Project: nlf/dlite
// Apply populates the flag given the flag set and environment
func (f Uint64Flag) Apply(set *flag.FlagSet) {
	if f.EnvVar != "" {
		for _, envVar := range strings.Split(f.EnvVar, ",") {
			envVar = strings.TrimSpace(envVar)
			if envVal := os.Getenv(envVar); envVal != "" {
				envValInt, err := strconv.ParseUint(envVal, 0, 64)
				if err == nil {
					f.Value = uint64(envValInt)
					break
				}
			}
		}
	}

	eachName(f.Name, func(name string) {
		if f.Destination != nil {
			set.Uint64Var(f.Destination, name, f.Value, f.Usage)
			return
		}
		set.Uint64(name, f.Value, f.Usage)
	})
}
Example #6
0
File: config.go Project: kho/easy
func addFieldFlag(field reflect.StructField, value reflect.Value, fs *flag.FlagSet) {
	name, usage := getFieldNameUsage(field)
	ptr := unsafe.Pointer(value.UnsafeAddr())
	switch field.Type.Kind() {
	case reflect.Bool:
		fs.BoolVar((*bool)(ptr), name, *(*bool)(ptr), usage)
	case reflect.Float64:
		fs.Float64Var((*float64)(ptr), name, *(*float64)(ptr), usage)
	case reflect.Int64:
		fs.Int64Var((*int64)(ptr), name, *(*int64)(ptr), usage)
	case reflect.Int:
		fs.IntVar((*int)(ptr), name, *(*int)(ptr), usage)
	case reflect.String:
		fs.StringVar((*string)(ptr), name, *(*string)(ptr), usage)
	case reflect.Uint64:
		fs.Uint64Var((*uint64)(ptr), name, *(*uint64)(ptr), usage)
	case reflect.Uint:
		fs.UintVar((*uint)(ptr), name, *(*uint)(ptr), usage)
	default:
		panic(fmt.Sprintf("unsupported type: %v", field.Type))
	}
}
Example #7
0
// Add the flags accepted by run to the supplied flag set, returning the
// variables into which the flags will parse.
func populateFlagSet(fs *flag.FlagSet) (flags *flagStorage) {
	flags = new(flagStorage)

	flags.MountOptions = make(map[string]string)
	fs.Var(
		mountpkg.OptionValue(flags.MountOptions),
		"o",
		"Additional system-specific mount options. Be careful!")

	fs.Int64Var(
		&flags.Uid,
		"uid",
		-1,
		"If non-negative, the UID that owns all inodes. The default is the UID of "+
			"the gcsfuse process.")

	fs.Int64Var(
		&flags.Gid,
		"gid",
		-1,
		"If non-negative, the GID that owns all inodes. The default is the GID of "+
			"the gcsfuse process.")

	fs.UintVar(
		&flags.FileMode,
		"file-mode",
		0644,
		"Permissions bits for files. Default is 0644.")

	fs.UintVar(
		&flags.DirMode,
		"dir-mode",
		0755,
		"Permissions bits for directories. Default is 0755.")

	fs.StringVar(
		&flags.TempDir,
		"temp-dir", "",
		"The temporary directory in which to store local copies of GCS objects. "+
			"If empty, the system default (probably /tmp) will be used.")

	fs.Int64Var(
		&flags.TempDirLimit,
		"temp-dir-bytes", 1<<31,
		"A desired limit on the number of bytes used in --temp-dir. May be "+
			"exceeded for dirty files that have not been flushed or closed.")

	fs.Uint64Var(
		&flags.GCSChunkSize,
		"gcs-chunk-size", 1<<24,
		"If set to a non-zero value N, split up GCS objects into multiple "+
			"chunks of size at most N when reading, and do not read or cache "+
			"unnecessary chunks.")

	fs.BoolVar(
		&flags.ImplicitDirs,
		"implicit-dirs",
		false,
		"Implicitly define directories based on their content. See "+
			"docs/semantics.md.")

	fs.DurationVar(
		&flags.StatCacheTTL,
		"stat-cache-ttl",
		time.Minute,
		"How long to cache StatObject results from GCS.")

	fs.DurationVar(
		&flags.TypeCacheTTL,
		"type-cache-ttl",
		time.Minute,
		"How long to cache name -> file/dir type mappings in directory inodes.")

	fs.Float64Var(
		&flags.OpRateLimitHz,
		"limit-ops-per-sec",
		5.0,
		"If positive, a limit on the rate at which we send requests to GCS, "+
			"measured over a 30-second window.")

	fs.Float64Var(
		&flags.EgressBandwidthLimitBytesPerSecond,
		"limit-bytes-per-sec",
		-1,
		"If positive, a limit on the GCS -> gcsfuse bandwidth for reading "+
			"objects, measured over a 30-second window.")

	return
}
Example #8
0
// Register fields in the given struct that have the tag `flag:"name,desc"`.
// Nested structs are supported as long as the field is a struct value field and not pointer to a struct.
// Exception to this is the use of StringList which needs to be a pointer.  The StringList type implements
// the Set and String methods required by the flag package and is dynamically allocated when registering its flag.
// See the test case for example.
func RegisterFlags(name string, val interface{}, fs *flag.FlagSet) {
	t := reflect.TypeOf(val).Elem()
	v := reflect.Indirect(reflect.ValueOf(val)) // the actual value of val
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if field.Anonymous && field.Type.Kind() == reflect.Struct {
			RegisterFlags(name+"."+field.Name, v.Field(i).Addr().Interface(), fs)
			continue
		}

		// See https://golang.org/ref/spec#Uniqueness_of_identifiers
		exported := field.PkgPath == ""
		if exported {

			tag := field.Tag
			spec := tag.Get("flag")
			if spec == "" {
				continue
			}

			// Bind the flag based on the tag spec
			f, d := "", ""
			p := strings.Split(spec, ",")
			if len(p) == 1 {
				// Just one field, use it as description
				f = fmt.Sprintf("%s.%s", name, strings.ToLower(field.Name))
				d = strings.Trim(p[0], " ")
			} else {
				// More than one, the first is the name of the flag
				f = strings.Trim(p[0], " ")
				d = strings.Trim(p[1], " ")
			}

			fv := v.Field(i).Interface()
			if v.Field(i).CanAddr() {
				ptr := v.Field(i).Addr().Interface() // The pointer value

				switch fv := fv.(type) {
				case bool:
					fs.BoolVar(ptr.(*bool), f, fv, d)
				case string:
					fs.StringVar(ptr.(*string), f, fv, d)
				case uint:
					fs.UintVar(ptr.(*uint), f, fv, d)
				case uint64:
					fs.Uint64Var(ptr.(*uint64), f, fv, d)
				case int64:
					fs.Int64Var(ptr.(*int64), f, fv, d)
				case int:
					fs.IntVar(ptr.(*int), f, fv, d)
				case float64:
					fs.Float64Var(ptr.(*float64), f, fv, d)
				case time.Duration:
					fs.DurationVar(ptr.(*time.Duration), f, fv, d)
				case []time.Duration:
					if len(fv) == 0 {
						// Special case where we allocate an empty list - otherwise it's default.
						v.Field(i).Set(reflect.ValueOf([]time.Duration{}))
					}
					fs.Var(&durationListProxy{list: ptr.(*[]time.Duration)}, f, d)
				default:
					// We only register if the field is a concrete vale and not a pointer
					// since we don't automatically allocate zero value structs to fill the field slot.
					switch field.Type.Kind() {

					case reflect.String:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: stringFromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Bool:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: boolFromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Float64:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: float64FromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Int:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: intFromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Int64:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: int64FromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Uint:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: uintFromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Uint64:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: uint64FromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Struct:
						RegisterFlags(f, ptr, fs)
					case reflect.Slice:
						et := field.Type.Elem()
						proxy := &sliceProxy{
							fieldType: field.Type,
							elemType:  et,
							slice:     ptr,
							defaults:  reflect.ValueOf(fv).Len() > 0,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}
						fs.Var(proxy, f, d)
						switch {
						// Checking for string is placed here first because other types are
						// convertible to string as well.
						case reflect.TypeOf(string("")).ConvertibleTo(et):
							proxy.fromString = stringFromString
						case reflect.TypeOf(bool(true)).ConvertibleTo(et):
							proxy.fromString = boolFromString
						case reflect.TypeOf(float64(1.)).ConvertibleTo(et):
							proxy.fromString = float64FromString
						case reflect.TypeOf(int(1)).ConvertibleTo(et):
							proxy.fromString = intFromString
						case reflect.TypeOf(int64(1)).ConvertibleTo(et):
							proxy.fromString = int64FromString
						case reflect.TypeOf(uint(1)).ConvertibleTo(et):
							proxy.fromString = uintFromString
						case reflect.TypeOf(uint64(1)).ConvertibleTo(et):
							proxy.fromString = uint64FromString
						case reflect.TypeOf(time.Second).AssignableTo(et):
							proxy.fromString = durationFromString
						}
					}
				}
			}
		}
	}
}