opts.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package opts
  2. import (
  3. "fmt"
  4. "github.com/dotcloud/docker/utils"
  5. "os"
  6. "path/filepath"
  7. "regexp"
  8. "strings"
  9. )
  10. // ListOpts type
  11. type ListOpts struct {
  12. values []string
  13. validator ValidatorFctType
  14. }
  15. func NewListOpts(validator ValidatorFctType) ListOpts {
  16. return ListOpts{
  17. validator: validator,
  18. }
  19. }
  20. func (opts *ListOpts) String() string {
  21. return fmt.Sprintf("%v", []string(opts.values))
  22. }
  23. // Set validates if needed the input value and add it to the
  24. // internal slice.
  25. func (opts *ListOpts) Set(value string) error {
  26. if opts.validator != nil {
  27. v, err := opts.validator(value)
  28. if err != nil {
  29. return err
  30. }
  31. value = v
  32. }
  33. opts.values = append(opts.values, value)
  34. return nil
  35. }
  36. // Delete remove the given element from the slice.
  37. func (opts *ListOpts) Delete(key string) {
  38. for i, k := range opts.values {
  39. if k == key {
  40. opts.values = append(opts.values[:i], opts.values[i+1:]...)
  41. return
  42. }
  43. }
  44. }
  45. // GetMap returns the content of values in a map in order to avoid
  46. // duplicates.
  47. // FIXME: can we remove this?
  48. func (opts *ListOpts) GetMap() map[string]struct{} {
  49. ret := make(map[string]struct{})
  50. for _, k := range opts.values {
  51. ret[k] = struct{}{}
  52. }
  53. return ret
  54. }
  55. // GetAll returns the values' slice.
  56. // FIXME: Can we remove this?
  57. func (opts *ListOpts) GetAll() []string {
  58. return opts.values
  59. }
  60. // Get checks the existence of the given key.
  61. func (opts *ListOpts) Get(key string) bool {
  62. for _, k := range opts.values {
  63. if k == key {
  64. return true
  65. }
  66. }
  67. return false
  68. }
  69. // Len returns the amount of element in the slice.
  70. func (opts *ListOpts) Len() int {
  71. return len(opts.values)
  72. }
  73. // Validators
  74. type ValidatorFctType func(val string) (string, error)
  75. func ValidateAttach(val string) (string, error) {
  76. if val != "stdin" && val != "stdout" && val != "stderr" {
  77. return val, fmt.Errorf("Unsupported stream name: %s", val)
  78. }
  79. return val, nil
  80. }
  81. func ValidateLink(val string) (string, error) {
  82. if _, err := utils.PartParser("name:alias", val); err != nil {
  83. return val, err
  84. }
  85. return val, nil
  86. }
  87. func ValidatePath(val string) (string, error) {
  88. var containerPath string
  89. if strings.Count(val, ":") > 2 {
  90. return val, fmt.Errorf("bad format for volumes: %s", val)
  91. }
  92. splited := strings.SplitN(val, ":", 2)
  93. if len(splited) == 1 {
  94. containerPath = splited[0]
  95. val = filepath.Clean(splited[0])
  96. } else {
  97. containerPath = splited[1]
  98. val = fmt.Sprintf("%s:%s", splited[0], filepath.Clean(splited[1]))
  99. }
  100. if !filepath.IsAbs(containerPath) {
  101. return val, fmt.Errorf("%s is not an absolute path", containerPath)
  102. }
  103. return val, nil
  104. }
  105. func ValidateEnv(val string) (string, error) {
  106. arr := strings.Split(val, "=")
  107. if len(arr) > 1 {
  108. return val, nil
  109. }
  110. return fmt.Sprintf("%s=%s", val, os.Getenv(val)), nil
  111. }
  112. func ValidateIp4Address(val string) (string, error) {
  113. re := regexp.MustCompile(`^(([0-9]+\.){3}([0-9]+))\s*$`)
  114. var ns = re.FindSubmatch([]byte(val))
  115. if len(ns) > 0 {
  116. return string(ns[1]), nil
  117. }
  118. return "", fmt.Errorf("%s is not an ip4 address", val)
  119. }
  120. func ValidateDomain(val string) (string, error) {
  121. alpha := regexp.MustCompile(`[a-zA-Z]`)
  122. if alpha.FindString(val) == "" {
  123. return "", fmt.Errorf("%s is not a valid domain", val)
  124. }
  125. re := regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
  126. ns := re.FindSubmatch([]byte(val))
  127. if len(ns) > 0 {
  128. return string(ns[1]), nil
  129. }
  130. return "", fmt.Errorf("%s is not a valid domain", val)
  131. }