func containerValidConfigKey(d *Daemon, key string, value string) error { f, err := shared.ConfigKeyChecker(key) if err != nil { return err } if err = f(value); err != nil { return err } if key == "raw.lxc" { return lxcValidConfig(value) } if key == "security.syscalls.blacklist_compat" { for _, arch := range d.architectures { if arch == shared.ARCH_64BIT_INTEL_X86 || arch == shared.ARCH_64BIT_ARMV8_LITTLE_ENDIAN || arch == shared.ARCH_64BIT_POWERPC_BIG_ENDIAN { return nil } } return fmt.Errorf("security.syscalls.blacklist_compat isn't supported on this architecture") } return nil }
func (c *listCmd) parseColumns() ([]column, error) { columnsShorthandMap := map[rune]column{ '4': column{i18n.G("IPV4"), c.IP4ColumnData, true, false}, '6': column{i18n.G("IPV6"), c.IP6ColumnData, true, false}, 'a': column{i18n.G("ARCHITECTURE"), c.ArchitectureColumnData, false, false}, 'c': column{i18n.G("CREATED AT"), c.CreatedColumnData, false, false}, 'l': column{i18n.G("LAST USED AT"), c.LastUsedColumnData, false, false}, 'n': column{i18n.G("NAME"), c.nameColumnData, false, false}, 'p': column{i18n.G("PID"), c.PIDColumnData, true, false}, 'P': column{i18n.G("PROFILES"), c.ProfilesColumnData, false, false}, 'S': column{i18n.G("SNAPSHOTS"), c.numberSnapshotsColumnData, false, true}, 's': column{i18n.G("STATE"), c.statusColumnData, false, false}, 't': column{i18n.G("TYPE"), c.typeColumnData, false, false}, } if c.fast { c.columnsRaw = "nsacPt" } columnList := strings.Split(c.columnsRaw, ",") columns := []column{} for _, columnEntry := range columnList { if columnEntry == "" { return nil, fmt.Errorf("Empty column entry (redundant, leading or trailing command) in '%s'", c.columnsRaw) } // Config keys always contain a period, parse anything without a // period as a series of shorthand runes. if !strings.Contains(columnEntry, ".") { for _, columnRune := range columnEntry { if column, ok := columnsShorthandMap[columnRune]; ok { columns = append(columns, column) } else { return nil, fmt.Errorf("Unknown column shorthand char '%c' in '%s'", columnRune, columnEntry) } } } else { cc := strings.Split(columnEntry, ":") if len(cc) > 3 { return nil, fmt.Errorf("Invalid config key column format (too many fields): '%s'", columnEntry) } k := cc[0] if _, err := shared.ConfigKeyChecker(k); err != nil { return nil, fmt.Errorf("Invalid config key '%s' in '%s'", k, columnEntry) } column := column{Name: k} if len(cc) > 1 { if len(cc[1]) == 0 && len(cc) != 3 { return nil, fmt.Errorf("Invalid name in '%s', empty string is only allowed when defining maxWidth", columnEntry) } column.Name = cc[1] } maxWidth := -1 if len(cc) > 2 { temp, err := strconv.ParseInt(cc[2], 10, 64) if err != nil { return nil, fmt.Errorf("Invalid max width (must be an integer) '%s' in '%s'", cc[2], columnEntry) } if temp < -1 { return nil, fmt.Errorf("Invalid max width (must -1, 0 or a positive integer) '%s' in '%s'", cc[2], columnEntry) } if temp == 0 { maxWidth = len(column.Name) } else { maxWidth = int(temp) } } column.Data = func(cInfo shared.ContainerInfo, cState *shared.ContainerState, cSnaps []shared.SnapshotInfo) string { v, ok := cInfo.Config[k] if !ok { v, ok = cInfo.ExpandedConfig[k] } // Truncate the data according to the max width. A negative max width // indicates there is no effective limit. if maxWidth > 0 && len(v) > maxWidth { return v[:maxWidth] } return v } columns = append(columns, column) } } return columns, nil }