org.midonet.midolman.Setup.java Source code

Java tutorial

Introduction

Here is the source code for org.midonet.midolman.Setup.java

Source

/*
 * Copyright 2014 Midokura SARL
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.midonet.midolman;

import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Options;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.HierarchicalINIConfiguration;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.midonet.midolman.state.Directory;
import org.midonet.midolman.state.PathBuilder;
import org.midonet.midolman.util.Sudo;
import org.midonet.midolman.version.DataWriteVersion;

import static org.midonet.midolman.state.zkManagers.VtepZkManager.MIN_VNI;

public class Setup {

    static final Logger log = LoggerFactory.getLogger(Setup.class);

    private static final String MIDONET_QDISC_CREATE = "midonet_qdisc_create";
    private static final String NOVA_QDISC_CREATE = "nova_qdisc_create";
    private static final String QDISC_DESTROY = "qdisc_destroy";

    private HierarchicalConfiguration config;

    private void run(String[] args) throws Exception {
        Options options = new Options();
        options.addOption("c", "configFile", true, "config file path");
        CommandLineParser parser = new GnuParser();
        CommandLine cl = parser.parse(options, args);
        String configFilePath = cl.getOptionValue('c', "./conf/midolman.conf");

        config = new HierarchicalINIConfiguration(configFilePath);

        args = cl.getArgs();
        if (args.length == 0)
            return;
        String command = args[0].toLowerCase();
        if (command.equals(MIDONET_QDISC_CREATE))
            setupTrafficPriorityQdiscsMidonet();
        else if (command.equals(NOVA_QDISC_CREATE))
            setupTrafficPriorityQdiscsNova();
        else if (command.equals(QDISC_DESTROY))
            removeTrafficPriorityQdiscs();
        else
            System.out.println("Unrecognized command. Exiting.");
    }

    private static List<String> getTopLevelPaths(PathBuilder pathMgr) {
        List<String> paths = new ArrayList<>();
        paths.add(pathMgr.getAdRoutesPath());
        paths.add(pathMgr.getBgpPath());
        paths.add(pathMgr.getBridgesPath());
        paths.add(pathMgr.getVlanBridgesPath());
        paths.add(pathMgr.getChainsPath());
        paths.add(pathMgr.getFiltersPath());
        paths.add(pathMgr.getRulesPath());
        paths.add(pathMgr.getTunnelPath());
        paths.add(pathMgr.getTunnelZonesPath());
        paths.add(pathMgr.getPortsPath());
        paths.add(pathMgr.getPortSetsPath());
        paths.add(pathMgr.getRoutersPath());
        paths.add(pathMgr.getRoutesPath());
        paths.add(pathMgr.getAgentPath());
        paths.add(pathMgr.getAgentPortPath());
        paths.add(pathMgr.getPortGroupsPath());
        paths.add(pathMgr.getIpAddrGroupsPath());
        paths.add(pathMgr.getHostsPath());
        paths.add(pathMgr.getTenantsPath());
        paths.add(pathMgr.getVersionsPath());
        paths.add(pathMgr.getVersionPath(DataWriteVersion.CURRENT));
        paths.add(pathMgr.getSystemStatePath());
        paths.add(pathMgr.getTraceConditionsPath());
        paths.add(pathMgr.getHealthMonitorsPath());
        paths.add(pathMgr.getLoadBalancersPath());
        paths.add(pathMgr.getPoolHealthMonitorMappingsPath());
        paths.add(pathMgr.getPoolMembersPath());
        paths.add(pathMgr.getPoolsPath());
        paths.add(pathMgr.getVipsPath());
        paths.add(pathMgr.getHealthMonitorLeaderDirPath());
        paths.add(pathMgr.getVtepsPath());
        paths.add(pathMgr.getVxLanPortIdsPath());
        paths.add(pathMgr.getLocksPath());
        paths.add(pathMgr.getLicensesPath());
        paths.add(pathMgr.getNatPath());

        // Neutron paths
        paths.add(pathMgr.getNeutronPath());
        paths.add(pathMgr.getNeutronNetworksPath());
        paths.add(pathMgr.getNeutronSubnetsPath());
        paths.add(pathMgr.getNeutronPortsPath());
        paths.add(pathMgr.getNeutronRoutersPath());
        paths.add(pathMgr.getNeutronFloatingIpsPath());
        paths.add(pathMgr.getNeutronSecurityGroupsPath());
        paths.add(pathMgr.getNeutronSecurityGroupRulesPath());
        // Neutron LoadBalancer paths
        paths.add(pathMgr.getNeutronLoadBalancerPath());
        paths.add(pathMgr.getNeutronPoolsPath());
        paths.add(pathMgr.getNeutronVipsPath());
        paths.add(pathMgr.getNeutronMembersPath());
        paths.add(pathMgr.getNeutronHealthMonitorsPath());

        return paths;
    }

    public static void ensureZkDirectoryStructureExists(Directory rootDir, String basePath)
            throws KeeperException, InterruptedException {
        ensureBasePathExists(rootDir, basePath);
        PathBuilder pathMgr = new PathBuilder(basePath);
        for (String path : Setup.getTopLevelPaths(pathMgr)) {
            rootDir.ensureHas(path, null);
        }
        rootDir.ensureHas(pathMgr.getVniCounterPath(), Integer.toString(MIN_VNI).getBytes());
        rootDir.ensureHas(pathMgr.getWriteVersionPath(), DataWriteVersion.CURRENT.getBytes());
    }

    public static void ensureBasePathExists(Directory rootDir, String basePath)
            throws KeeperException, InterruptedException {
        String currentPath = "";
        for (String part : basePath.split("/+")) {
            if (part.trim().isEmpty())
                continue;

            currentPath += "/" + part;
            try {
                if (!rootDir.has(currentPath)) {
                    log.debug("Adding " + currentPath);
                    rootDir.add(currentPath, null, CreateMode.PERSISTENT);
                }
            } catch (KeeperException.NodeExistsException ex) {
                // Don't exit even if the node exists.
                log.warn("doStart: {} already exists.", currentPath);
            }
        }
    }

    protected void setupTrafficPriorityQdiscsMidonet()
            throws IOException, URISyntaxException, InterruptedException {
        int markValue = 0x00ACCABA; // Midokura's OUI.
        String iface = config.configurationAt("midolman").getString("control_interface", "eth0");

        // Add a prio qdisc to root, and have marked packets prioritized.
        Sudo.sudoExec("tc qdisc add dev " + iface + " root handle 1: prio");
        Sudo.sudoExec("tc filter add dev " + iface + " parent 1: protocol ip prio 1 handle " + markValue
                + " fw flowid 1:1");

        // Add rules to mark ZooKeeper packets.
        String zkHosts = config.configurationAt("zookeeper").getString("zookeeper_hosts", "127.0.0.1:2181");
        for (String zkServer : zkHosts.split(",")) {
            String[] hostport = zkServer.split(":");
            assert hostport.length == 2;
            setupTrafficPriorityRule(hostport[0], hostport[1]);
        }

        // Add rules to mark Cassandra packets.
        String mcHosts = config.configurationAt("cassandra").getString("servers", "127.0.0.1:9170");
        for (String mcServer : mcHosts.split(",")) {
            String[] hostport = mcServer.split(":");
            setupTrafficPriorityRule(hostport[0], hostport[1]);
        }
    }

    protected void setupTrafficPriorityQdiscsNova() throws IOException, InterruptedException, URISyntaxException {
        FileReader confFile = new FileReader("/etc/nova/nova.conf");
        char[] confBytes = new char[5000];
        int confByteLength = confFile.read(confBytes);
        String[] allArgs = (new String(confBytes, 0, confByteLength)).split("\n");
        for (String arg : allArgs) {
            // RabbitMQ
            if (arg.startsWith("--rabbit_host")) {
                String[] flaghost = arg.split("=");
                setupTrafficPriorityRule(flaghost[1], "5672");
            }

            // mysql
            if (arg.startsWith("--sql_connection")) {
                String[] flagurl = arg.split("=");
                URI mysqlUrl = new URI(flagurl[1]);
                int port = mysqlUrl.getPort();
                if (port == -1)
                    port = 3306;
                setupTrafficPriorityRule(mysqlUrl.getHost(), Integer.toString(port));
            }

            // VNC
            if (arg.startsWith("--sql_connection")) {
                String[] flagurl = arg.split("=");
                URI vncUrl = new URI(flagurl[1]);
                int port = vncUrl.getPort();
                if (port == -1)
                    port = 6080;
                setupTrafficPriorityRule(vncUrl.getHost(), Integer.toString(port));
            }

            // EC2
            if (arg.startsWith("--ec2_url")) {
                String[] flagurl = arg.split("=");
                URI ec2Url = new URI(flagurl[1]);
                int port = ec2Url.getPort();
                if (port == -1)
                    port = 8773;
                setupTrafficPriorityRule(ec2Url.getHost(), Integer.toString(port));
            }
        }
    }

    protected void removeTrafficPriorityQdiscs() throws IOException, InterruptedException {
        // Clear existing qdiscs
        String iface = config.configurationAt("midolman").getString("control_interface", "eth0");
        Sudo.sudoExec("tc qdisc del dev " + iface + " root");
    }

    protected static void setupTrafficPriorityRule(String host, String port)
            throws IOException, InterruptedException {
        int markValue = 0x00ACCABA; // Midokura's OUI.
        Sudo.sudoExec("iptables -t mangle -A POSTROUTING -p tcp -m tcp -d " + host + " --dport " + port
                + " -j MARK --set-mark " + markValue);
    }

    public static void main(String[] args) {
        try {
            new Setup().run(args);
        } catch (Exception e) {
            log.error("main caught", e);
            System.exit(-1);
        }
    }

}