func (d *Daemon) ConfigureClusterListenerPort(listen string) error { iface, err := net.InterfaceByName(listen) if err != nil { log.Debugf("Could not find interface %s", listen) return err } if iface.Flags&net.FlagUp == 0 { log.Debugf("%s is down", listen) return errors.New("Interface is down") } log.Debugf("Requesting to bind to %s", listen) context := &ClusterContext{listen, ClusterBind} d.bindChan <- context return nil }
func (d *Daemon) JoinCluster(address string) error { if addr := net.ParseIP(address); addr == nil { return errors.New("Invalid IP address") } log.Debugf("Requesting to join cluster %s", address) context := &ClusterContext{address, ClusterJoin} d.bindChan <- context return nil }
func setupIPTables(bridgeName string, bridgeIP string) error { /* # Enable IP Masquerade on all ifaces that are not docker-ovs0 iptables -t nat -A POSTROUTING -s 10.1.42.1/16 ! -o %bridgeName -j MASQUERADE # Enable outgoing connections on all interfaces iptables -A FORWARD -i %bridgeName ! -o %bridgeName -j ACCEPT # Enable incoming connections for established sessions iptables -A FORWARD -o %bridgeName -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT */ log.Debug("Setting up iptables") natArgs := []string{"-s", bridgeIP, "!", "-o", bridgeName, "-j", "MASQUERADE"} if !ruleExists("nat", "POSTROUTING", natArgs...) { output, err := installRule(append([]string{ "-t", "nat", "-A", "POSTROUTING"}, natArgs...)...) if err != nil { log.Debugf("Unable to enable network bridge NAT: %s", err) return fmt.Errorf("Unable to enable network bridge NAT: %s", err) } if len(output) != 0 { log.Debugf("Error enabling network bridge NAT: %s", err) return fmt.Errorf("Error enabling network bridge NAT: %s", output) } } outboundArgs := []string{"-i", bridgeName, "!", "-o", bridgeName, "-j", "ACCEPT"} if !ruleExists("", "FORWARD", outboundArgs...) { output, err := installRule(append([]string{ "-A", "FORWARD"}, outboundArgs...)...) if err != nil { log.Debugf("Unable to enable network outbound forwarding: %s", err) return fmt.Errorf("Unable to enable network outbound forwarding: %s", err) } if len(output) != 0 { log.Debugf("Error enabling network outbound forwarding: %s", output) return fmt.Errorf("Error enabling network outbound forwarding: %s", output) } } inboundArgs := []string{"-o", bridgeName, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"} if !ruleExists("", "FORWARD", inboundArgs...) { output, err := installRule(append([]string{ "-A", "FORWARD"}, inboundArgs...)...) if err != nil { log.Debugf("Unable to enable network inbound forwarding: %s", err) return fmt.Errorf("Unable to enable network inbound forwarding: %s", err) } if len(output) != 0 { log.Debugf("Error enabling network inbound forwarding: %s") return fmt.Errorf("Error enabling network inbound forwarding: %s", output) } } return nil }
func clusterJoin(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError { if r.URL.RawQuery == "" { return &apiError{http.StatusBadRequest, "Please provide the address parameter"} } values, err := url.ParseQuery(r.URL.RawQuery) if err != nil { return &apiError{http.StatusBadRequest, "Could not decode query parameters"} } addr, ok := values["address"] if !ok || addr[0] == "" { return &apiError{http.StatusBadRequest, "Please provide the address parameter"} } log.Debugf("Request Received. Join Cluster %s", addr[0]) err = d.JoinCluster(addr[0]) if err != nil { return &apiError{http.StatusInternalServerError, err.Error()} } return nil }
func clusterBind(d *Daemon, w http.ResponseWriter, r *http.Request) *apiError { if r.URL.RawQuery == "" { return &apiError{http.StatusBadRequest, "Please provide the interface parameter"} } values, err := url.ParseQuery(r.URL.RawQuery) if err != nil { return &apiError{http.StatusBadRequest, "Could not decode query parameters"} } iface, ok := values["iface"] if !ok || iface[0] == "" { return &apiError{http.StatusBadRequest, "Please provide the interface parameter"} } log.Debugf("Request Received. Change Cluster Interface to %s", iface[0]) err = d.ConfigureClusterListenerPort(iface[0]) if err != nil { return &apiError{http.StatusInternalServerError, err.Error()} } return nil }
func clusterJoinRPC(d *Daemon, joinAddress string) error { bindInterface, err := GetIfaceForRoute(joinAddress) if err != nil { return err } if d.clusterListener != bindInterface { log.Debug("Cluster is already bound on another interface. Leaving...") LeaveDatastore() time.Sleep(time.Second * 10) log.Debugf("Setting new cluster listener to %s", bindInterface) d.bootstrapNode = false d.clusterListener = bindInterface InitDatastore(d.clusterListener, d.bootstrapNode) } if err = JoinDatastore(joinAddress); err != nil { log.Errorf("Could not join cluster %s. %s", joinAddress, err.Error()) } return nil }
func clusterBindRPC(d *Daemon, bindInterface string) error { if bindInterface == d.clusterListener { log.Debug("Bind Interface is the same as currently bound interface") return errors.New("Bind Interface is the same as currently bound interface") } once := true if d.clusterListener != "" { log.Debug("Cluster is already bound on another interface. Leaving...") once = false LeaveDatastore() time.Sleep(time.Second * 5) } log.Debugf("Setting new cluster listener to %s", bindInterface) d.clusterListener = bindInterface InitDatastore(d.clusterListener, d.bootstrapNode) if !d.bootstrapNode && once { d.serialChan <- true } return nil }
func CreateNetwork(id string, subnet *net.IPNet) (*Network, error) { network, err := GetNetwork(id) if err == nil { log.Debugf("Network '%s' found", id) return network, nil } vlan, err := allocateVlan() if err != nil { log.Debugf("Unable to allocate VLAN for Network '%s'. Error: %v", id, err.Error()) return nil, err } var gateway net.IP addr, err := GetIfaceAddr(id) if err != nil { log.Debugf("Interface with name %s does not exist. Creating it.", id) if ovs == nil { return nil, errors.New("OVS not connected") } // Interface does not exist, use the generated subnet gateway = IPAMRequest(*subnet) network = &Network{id, subnet.String(), gateway.String(), vlan} if err = AddInternalPort(ovs, defaultBridgeName, network.ID, vlan); err != nil { return network, err } // TODO : Lame. Remove the sleep. This is required now to keep netlink happy // in the next step to find the created interface. time.Sleep(time.Second * 1) gatewayNet := &net.IPNet{gateway, subnet.Mask} log.Debugf("Setting address %s on %s", gatewayNet.String(), network.ID) if err = SetMtu(network.ID, mtu); err != nil { return network, err } if err = SetInterfaceIp(network.ID, gatewayNet.String()); err != nil { return network, err } if err = InterfaceUp(network.ID); err != nil { return network, err } } else { log.Debugf("Interface with name %s already exists", id) ifaceAddr := addr.String() gateway, subnet, err = net.ParseCIDR(ifaceAddr) if err != nil { return nil, err } network = &Network{id, subnet.String(), gateway.String(), vlan} } data, err := json.Marshal(network) if err != nil { return nil, err } eccerr := ecc.Put(networkStore, id, data, nil) if eccerr == ecc.OUTDATED { releaseVlan(vlan) IPAMRelease(gateway, *subnet) return CreateNetwork(id, subnet) } if err = setupIPTables(network.ID, network.Subnet); err != nil { return network, err } return network, nil }