Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
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
}
Beispiel #7
0
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
}
Beispiel #8
0
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
}