Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
| ... | ... |
@@ -167,12 +167,20 @@ property is not set, the client falls back to the default table |
| 167 | 167 |
format. For a list of supported formatting directives, see |
| 168 | 168 |
[**Formatting** section in the `docker secret ls` documentation](secret_ls.md) |
| 169 | 169 |
|
| 170 |
+ |
|
| 170 | 171 |
The property `nodesFormat` specifies the default format for `docker node ls` output. |
| 171 | 172 |
When the `--format` flag is not provided with the `docker node ls` command, |
| 172 | 173 |
Docker's client uses the value of `nodesFormat`. If the value of `nodesFormat` is not set, |
| 173 | 174 |
the client uses the default table format. For a list of supported formatting |
| 174 | 175 |
directives, see the [**Formatting** section in the `docker node ls` documentation](node_ls.md) |
| 175 | 176 |
|
| 177 |
+The property `configFormat` specifies the default format for `docker |
|
| 178 |
+config ls` output. When the `--format` flag is not provided with the |
|
| 179 |
+`docker config ls` command, Docker's client uses this property. If this |
|
| 180 |
+property is not set, the client falls back to the default table |
|
| 181 |
+format. For a list of supported formatting directives, see |
|
| 182 |
+[**Formatting** section in the `docker config ls` documentation](config_ls.md) |
|
| 183 |
+ |
|
| 176 | 184 |
The property `credsStore` specifies an external binary to serve as the default |
| 177 | 185 |
credential store. When this property is set, `docker login` will attempt to |
| 178 | 186 |
store credentials in the binary specified by `docker-credential-<value>` which |
| ... | ... |
@@ -218,6 +226,7 @@ Following is a sample `config.json` file: |
| 218 | 218 |
"statsFormat": "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}",
|
| 219 | 219 |
"servicesFormat": "table {{.ID}}\t{{.Name}}\t{{.Mode}}",
|
| 220 | 220 |
"secretFormat": "table {{.ID}}\t{{.Name}}\t{{.CreatedAt}}\t{{.UpdatedAt}}",
|
| 221 |
+ "configFormat": "table {{.ID}}\t{{.Name}}\t{{.CreatedAt}}\t{{.UpdatedAt}}",
|
|
| 221 | 222 |
"serviceInspectFormat": "pretty", |
| 222 | 223 |
"nodesFormat": "table {{.ID}}\t{{.Hostname}}\t{{.Availability}}",
|
| 223 | 224 |
"detachKeys": "ctrl-e,e", |
| 224 | 225 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,98 @@ |
| 0 |
+package opts |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/csv" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ "os" |
|
| 6 |
+ "strconv" |
|
| 7 |
+ "strings" |
|
| 8 |
+ |
|
| 9 |
+ swarmtypes "github.com/docker/docker/api/types/swarm" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+// ConfigOpt is a Value type for parsing configs |
|
| 13 |
+type ConfigOpt struct {
|
|
| 14 |
+ values []*swarmtypes.ConfigReference |
|
| 15 |
+} |
|
| 16 |
+ |
|
| 17 |
+// Set a new config value |
|
| 18 |
+func (o *ConfigOpt) Set(value string) error {
|
|
| 19 |
+ csvReader := csv.NewReader(strings.NewReader(value)) |
|
| 20 |
+ fields, err := csvReader.Read() |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ return err |
|
| 23 |
+ } |
|
| 24 |
+ |
|
| 25 |
+ options := &swarmtypes.ConfigReference{
|
|
| 26 |
+ File: &swarmtypes.ConfigReferenceFileTarget{
|
|
| 27 |
+ UID: "0", |
|
| 28 |
+ GID: "0", |
|
| 29 |
+ Mode: 0444, |
|
| 30 |
+ }, |
|
| 31 |
+ } |
|
| 32 |
+ |
|
| 33 |
+ // support a simple syntax of --config foo |
|
| 34 |
+ if len(fields) == 1 {
|
|
| 35 |
+ options.File.Name = fields[0] |
|
| 36 |
+ options.ConfigName = fields[0] |
|
| 37 |
+ o.values = append(o.values, options) |
|
| 38 |
+ return nil |
|
| 39 |
+ } |
|
| 40 |
+ |
|
| 41 |
+ for _, field := range fields {
|
|
| 42 |
+ parts := strings.SplitN(field, "=", 2) |
|
| 43 |
+ key := strings.ToLower(parts[0]) |
|
| 44 |
+ |
|
| 45 |
+ if len(parts) != 2 {
|
|
| 46 |
+ return fmt.Errorf("invalid field '%s' must be a key=value pair", field)
|
|
| 47 |
+ } |
|
| 48 |
+ |
|
| 49 |
+ value := parts[1] |
|
| 50 |
+ switch key {
|
|
| 51 |
+ case "source", "src": |
|
| 52 |
+ options.ConfigName = value |
|
| 53 |
+ case "target": |
|
| 54 |
+ options.File.Name = value |
|
| 55 |
+ case "uid": |
|
| 56 |
+ options.File.UID = value |
|
| 57 |
+ case "gid": |
|
| 58 |
+ options.File.GID = value |
|
| 59 |
+ case "mode": |
|
| 60 |
+ m, err := strconv.ParseUint(value, 0, 32) |
|
| 61 |
+ if err != nil {
|
|
| 62 |
+ return fmt.Errorf("invalid mode specified: %v", err)
|
|
| 63 |
+ } |
|
| 64 |
+ |
|
| 65 |
+ options.File.Mode = os.FileMode(m) |
|
| 66 |
+ default: |
|
| 67 |
+ return fmt.Errorf("invalid field in config request: %s", key)
|
|
| 68 |
+ } |
|
| 69 |
+ } |
|
| 70 |
+ |
|
| 71 |
+ if options.ConfigName == "" {
|
|
| 72 |
+ return fmt.Errorf("source is required")
|
|
| 73 |
+ } |
|
| 74 |
+ |
|
| 75 |
+ o.values = append(o.values, options) |
|
| 76 |
+ return nil |
|
| 77 |
+} |
|
| 78 |
+ |
|
| 79 |
+// Type returns the type of this option |
|
| 80 |
+func (o *ConfigOpt) Type() string {
|
|
| 81 |
+ return "config" |
|
| 82 |
+} |
|
| 83 |
+ |
|
| 84 |
+// String returns a string repr of this option |
|
| 85 |
+func (o *ConfigOpt) String() string {
|
|
| 86 |
+ configs := []string{}
|
|
| 87 |
+ for _, config := range o.values {
|
|
| 88 |
+ repr := fmt.Sprintf("%s -> %s", config.ConfigName, config.File.Name)
|
|
| 89 |
+ configs = append(configs, repr) |
|
| 90 |
+ } |
|
| 91 |
+ return strings.Join(configs, ", ") |
|
| 92 |
+} |
|
| 93 |
+ |
|
| 94 |
+// Value returns the config requests |
|
| 95 |
+func (o *ConfigOpt) Value() []*swarmtypes.ConfigReference {
|
|
| 96 |
+ return o.values |
|
| 97 |
+} |