// Checks if the client set configurations for more than one network while creating a container // Also checks if the IPAMConfig is valid func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingConfig) error { if nwConfig == nil || len(nwConfig.EndpointsConfig) == 0 { return nil } if len(nwConfig.EndpointsConfig) == 1 { for _, v := range nwConfig.EndpointsConfig { if v != nil && v.IPAMConfig != nil { if v.IPAMConfig.IPv4Address != "" && net.ParseIP(v.IPAMConfig.IPv4Address).To4() == nil { return errors.NewBadRequestError(fmt.Errorf("invalid IPv4 address: %s", v.IPAMConfig.IPv4Address)) } if v.IPAMConfig.IPv6Address != "" { n := net.ParseIP(v.IPAMConfig.IPv6Address) // if the address is an invalid network address (ParseIP == nil) or if it is // an IPv4 address (To4() != nil), then it is an invalid IPv6 address if n == nil || n.To4() != nil { return errors.NewBadRequestError(fmt.Errorf("invalid IPv6 address: %s", v.IPAMConfig.IPv6Address)) } } } } return nil } l := make([]string, 0, len(nwConfig.EndpointsConfig)) for k := range nwConfig.EndpointsConfig { l = append(l, k) } err := fmt.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", ")) return errors.NewBadRequestError(err) }
// GetContainer looks for a container using the provided information, which could be // one of the following inputs from the caller: // - A full container ID, which will exact match a container in daemon's list // - A container name, which will only exact match via the GetByName() function // - A partial container ID prefix (e.g. short ID) of any length that is // unique enough to only return a single container object // If none of these searches succeed, an error is returned func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, error) { if len(prefixOrName) == 0 { return nil, errors.NewBadRequestError(fmt.Errorf("No container name or ID supplied")) } if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil { // prefix is an exact match to a full container ID return containerByID, nil } // GetByName will match only an exact name provided; we ignore errors if containerByName, _ := daemon.GetByName(prefixOrName); containerByName != nil { // prefix is an exact match to a full container Name return containerByName, nil } containerID, indexError := daemon.idIndex.Get(prefixOrName) if indexError != nil { // When truncindex defines an error type, use that instead if indexError == truncindex.ErrNotExist { err := fmt.Errorf("No such container: %s", prefixOrName) return nil, errors.NewRequestNotFoundError(err) } return nil, indexError } return daemon.containers.Get(containerID), nil }
// Checks if the client set configurations for more than one network while creating a container func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingConfig) error { if nwConfig == nil || len(nwConfig.EndpointsConfig) <= 1 { return nil } l := make([]string, 0, len(nwConfig.EndpointsConfig)) for k := range nwConfig.EndpointsConfig { l = append(l, k) } err := fmt.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", ")) return errors.NewBadRequestError(err) }
func (s *systemRouter) getEvents(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } since, err := eventTime(r.Form.Get("since")) if err != nil { return err } until, err := eventTime(r.Form.Get("until")) if err != nil { return err } var ( timeout <-chan time.Time onlyPastEvents bool ) if !until.IsZero() { if until.Before(since) { return errors.NewBadRequestError(fmt.Errorf("`since` time (%s) cannot be after `until` time (%s)", r.Form.Get("since"), r.Form.Get("until"))) } now := time.Now() onlyPastEvents = until.Before(now) if !onlyPastEvents { dur := until.Sub(now) timeout = time.NewTimer(dur).C } } ef, err := filters.FromParam(r.Form.Get("filters")) if err != nil { return err } w.Header().Set("Content-Type", "application/json") output := ioutils.NewWriteFlusher(w) defer output.Close() output.Flush() enc := json.NewEncoder(output) buffered, l := s.backend.SubscribeToEvents(since, until, ef) defer s.backend.UnsubscribeFromEvents(l) for _, ev := range buffered { if err := enc.Encode(ev); err != nil { return err } } if onlyPastEvents { return nil } for { select { case ev := <-l: jev, ok := ev.(events.Message) if !ok { logrus.Warnf("unexpected event message: %q", ev) continue } if err := enc.Encode(jev); err != nil { return err } case <-timeout: return nil case <-ctx.Done(): logrus.Debug("Client context cancelled, stop sending events") return nil } } }