func (c Container) String() string { cmdStr := strings.Join(append([]string{"run", c.Image}, c.Command...), " ") tags := []string{cmdStr} if c.DockerID != "" { id := util.ShortUUID(c.DockerID) tags = append(tags, fmt.Sprintf("DockerID: %s", id)) } if c.Pid != 0 { tags = append(tags, fmt.Sprintf("Pid: %d", c.Pid)) } if c.IP != "" { tags = append(tags, fmt.Sprintf("IP: %s", c.IP)) } if c.Mac != "" { tags = append(tags, fmt.Sprintf("Mac: %s", c.Mac)) } if len(c.Labels) > 0 { tags = append(tags, fmt.Sprintf("Labels: %s", c.Labels)) } if len(c.Env) > 0 { tags = append(tags, fmt.Sprintf("Env: %s", c.Env)) } return fmt.Sprintf("Container-%d{%s}", c.ID, strings.Join(tags, ", ")) }
func generateEtcHosts(dbc db.Container, labelIP map[string]string, conns map[string][]string) string { type entry struct { ip, host string } localhosts := []entry{ {"127.0.0.1", "localhost"}, {"::1", "localhost ip6-localhost ip6-loopback"}, {"fe00::0", "ip6-localnet"}, {"ff00::0", "ip6-mcastprefix"}, {"ff02::1", "ip6-allnodes"}, {"ff02::2", "ip6-allrouters"}, } if dbc.IP != "" && dbc.DockerID != "" { entry := entry{dbc.IP, util.ShortUUID(dbc.DockerID)} localhosts = append(localhosts, entry) } newHosts := make(map[entry]struct{}) for _, entry := range localhosts { newHosts[entry] = struct{}{} } for _, l := range dbc.Labels { for _, toLabel := range conns[l] { if toLabel == stitch.PublicInternetLabel { continue } if ip := labelIP[toLabel]; ip != "" { newHosts[entry{ip, toLabel + ".q"}] = struct{}{} } } } var hosts []string for h := range newHosts { hosts = append(hosts, fmt.Sprintf("%-15s %s", h.ip, h.host)) } sort.Strings(hosts) return strings.Join(hosts, "\n") + "\n" }
// The leader of the cluster is responsible for properly configuring OVN northd for // container networking. This simply means creating a logical port for each container // and label. The specialized OpenFlow rules Quilt requires are managed by the workers // individuallly. func runMaster(conn db.Conn) { var leader bool var labels []db.Label var containers []db.Container var connections []db.Connection conn.Transact(func(view db.Database) error { leader = view.EtcdLeader() labels = view.SelectFromLabel(func(label db.Label) bool { return label.IP != "" }) containers = view.SelectFromContainer(func(dbc db.Container) bool { return dbc.DockerID != "" && dbc.Mac != "" && dbc.IP != "" }) connections = view.SelectFromConnection(nil) return nil }) if !leader { return } ovsdb, err := ovsdb.Open() if err != nil { log.WithError(err).Error("Failed to connect to OVSDB.") return } defer ovsdb.Close() ovsdb.CreateSwitch(lSwitch) lportSlice, err := ovsdb.ListPorts(lSwitch) if err != nil { log.WithError(err).Error("Failed to list OVN ports.") return } // The garbageMap starts of containing every logical port in OVN. As we find // that these ports are still useful, they're deleted from garbageMap until only // leftover garbage ports are remaining. These are then deleted. garbageMap := make(map[string]struct{}) for _, lport := range lportSlice { garbageMap[lport.Name] = struct{}{} } for _, dbl := range labels { if !dbl.MultiHost { continue } if _, ok := garbageMap[dbl.Label]; ok { delete(garbageMap, dbl.Label) continue } log.WithFields(log.Fields{ "name": dbl.Label, "IP": dbl.IP, }).Info("New logical port.") err := ovsdb.CreatePort(lSwitch, dbl.Label, labelMac, dbl.IP) if err != nil { log.WithError(err).Warnf("Failed to create port %s.", dbl.Label) } } for _, dbc := range containers { if _, ok := garbageMap[dbc.DockerID]; ok { delete(garbageMap, dbc.DockerID) continue } log.WithFields(log.Fields{ "name": util.ShortUUID(dbc.DockerID), "IP": dbc.IP, }).Info("New logical port.") err := ovsdb.CreatePort("quilt", dbc.DockerID, dbc.Mac, dbc.IP) if err != nil { log.WithFields(log.Fields{ "error": err, "name": dbc.DockerID, }).Warn("Failed to create port.") } } // Ports still in the map don't have a corresponding label otherwise they would // have been deleted in the preceding loop. for lport := range garbageMap { log.Infof("Delete logical port %s.", lport) if err := ovsdb.DeletePort(lSwitch, lport); err != nil { log.WithError(err).Warn("Failed to delete logical port.") } } updateACLs(connections, labels, containers) }