func (pod *UserPod) Validate() error { var volume_drivers = map[string]bool{ "raw": true, "qcow2": true, "vdi": true, "vfs": true, "rbd": true, } hostnameLen := len(pod.Hostname) if hostnameLen > 63 { return fmt.Errorf("Hostname exceeds the maximum length 63, len: %d", hostnameLen) } if hostnameLen > 0 { for _, seg := range strings.Split(pod.Hostname, ".") { if !utils.IsDNSLabel(seg) { return fmt.Errorf("Hostname should fullfil the pattern: %s, input hostname: %s", utils.Dns1123LabelFmt, pod.Hostname) } } } hasGw := false for idx, config := range pod.Interfaces { if config.Gateway == "" { continue } if hasGw { return fmt.Errorf("in interface %d, Other interface already configured Gateway", idx) } hasGw = true } uniq, vset := keySet(pod.Volumes) if !uniq { if len(vset) > 0 { return errors.New("Volumes name does not unique") } } uniq, fset := keySet(pod.Files) if !uniq { if len(fset) > 0 { return errors.New("Files name does not unique") } } var permReg = regexp.MustCompile("0[0-7]{3}") for idx, container := range pod.Containers { if uniq, _ := keySet(container.Volumes); !uniq { return fmt.Errorf("in container %d, volume source are not unique", idx) } if uniq, _ := keySet(container.Envs); !uniq { return fmt.Errorf("in container %d, environment name are not unique", idx) } for _, f := range container.Files { if _, ok := fset[f.Filename]; !ok { return fmt.Errorf("in container %d, file %s does not exist in file list.", idx, f.Filename) } if f.Perm == "" { f.Perm = "0755" } if f.Perm != "0" { if !permReg.Match([]byte(f.Perm)) { return fmt.Errorf("in container %d, the permission %s only accept Octal digital in string", idx, f.Perm) } } } for _, v := range container.Volumes { if _, ok := vset[v.Volume]; !ok { return fmt.Errorf("in container %d, volume %s does not exist in volume list.", idx, v.Volume) } } } for idx, v := range pod.Volumes { if v.Format == "" { continue } if _, ok := volume_drivers[v.Format]; !ok { return fmt.Errorf("in volume %d, volume does not support driver %s.", idx, v.Format) } } for _, dns := range pod.Dns { if ip := net.ParseIP(dns); ip == nil { return fmt.Errorf("incorrect dns %s.", dns) } } return nil }
func (p *UserPod) ReorganizeContainers(allowAbsent bool) error { if p.Log == nil { p.Log = &PodLogConfig{} } if p.Resource == nil { p.Resource = &UserResource{} } if p.PortmappingWhiteLists == nil { p.PortmappingWhiteLists = &PortmappingWhiteList{} } if p.Hostname == "" { p.Hostname = p.Id } if len(p.Hostname) > 63 { p.Hostname = p.Hostname[:63] } volumes := make(map[string]*UserVolume) files := make(map[string]*UserFile) for _, vol := range p.Volumes { volumes[vol.Name] = vol } for _, file := range p.Files { files[file.Name] = file } for idx, c := range p.Containers { if c.Name == "" { _, img, _ := utils.ParseImageRepoTag(c.Image) if !utils.IsDNSLabel(img) { img = "" } c.Name = fmt.Sprintf("%s-%s-%d", p.Id, img, idx) } if p.Tty && !c.Tty { c.Tty = true } cv := []*UserVolumeReference{} cf := []*UserFileReference{} for _, vol := range c.Volumes { if vol.Detail != nil { cv = append(cv, vol) continue } if v, ok := volumes[vol.Volume]; !ok { if !allowAbsent { return fmt.Errorf("volume %s of container %s do not have specification", vol.Volume, c.Name) } continue } else { vol.Detail = v cv = append(cv, vol) } } for _, file := range c.Files { if file.Detail != nil { cf = append(cf, file) continue } if f, ok := files[file.Filename]; !ok { if !allowAbsent { return fmt.Errorf("file %s of container %s do not have specification", file.Filename, c.Name) } continue } else { file.Detail = f cf = append(cf, file) } } c.Volumes = cv c.Files = cf } return nil }