Exemple #1
0
def remove_subinterface(path):
    delete_commands = []
    if (_platform == LINUX or _platform == LINUX2):
        if (os.geteuid() == 0):
            temp_path = os.path.join(
                pwd.getpwuid(os.getuid()).pw_dir, "netkit_temp/")
            hash_path = str(u.generate_urlsafe_hash(path))
            if (os.path.exists(temp_path + hash_path + '_external_links')):
                if (os.stat(temp_path + hash_path + '_external_links').st_size
                        != 0):
                    with open(temp_path + hash_path + '_external_links',
                              'r') as external_file_temp:
                        delete_commands.append(
                            'echo "\033[0;33mSubinterfaces will be deleted\033[0m"'
                        )
                        for line in external_file_temp:
                            subinterface = line.split()[0]
                            delete_commands.append('sudo ip link set dev ' +
                                                   subinterface + ' ' + 'down')
                            delete_commands.append('sudo ip link delete ' +
                                                   subinterface)
                            delete_commands.append('echo ' + subinterface)

                os.remove(temp_path + hash_path + '_external_links')
        else:
            sys.stderr.write(
                "\033[0;33mPlease you started the lab with external.conf file, need root permission to clean current lab.\033[0m"
                + "\n")
            sys.exit(1)

    return delete_commands
Exemple #2
0
def external_commands(path, collision_domains, interfaces, execbash=False):
    lab_external_links_text = ''
    commands = []
    prefix = 'netkit_' + str(os.getuid()) + '_'

    for (collision_domain, interface) in zip(collision_domains, interfaces):                                       
        #check if paramater's interface have a vlan syntax 
        if interface.__contains__("."):
            prefix_interface = interface.split(".")[0]
            vlan_id = interface.split(".")[1]
            if (len(interface) > 15):
                prefix_truncate_interface = prefix_interface[-9:]
                interface = prefix_truncate_interface + '.' + vlan_id

            lab_external_links_text += interface + '\n'

            commands.append(os.path.join(os.environ['NETKIT_HOME'],'brctl_config_external ' + prefix + collision_domain + ' ' + interface + ' ' + prefix_interface  + ' ' + vlan_id))
        else:
            commands.append(os.path.join(os.environ['NETKIT_HOME'],'brctl_config_external ' + prefix + collision_domain + ' ' + interface))        

    if not execbash:
        if not PRINT: u.write_temp(lab_external_links_text, str(u.generate_urlsafe_hash(path)) + '_external_links', PLATFORM, file_mode="w+")

    return commands    
Exemple #3
0
def create_commands(machines,
                    links,
                    options,
                    metadata,
                    path,
                    execbash=False,
                    no_machines_tmp=False):
    docker = DOCKER_BIN

    # deciding machine and network prefix in order to avoid conflicts with other users and containers
    if PLATFORM != WINDOWS:
        prefix = 'netkit_' + str(os.getuid()) + '_'
    else:
        prefix = 'netkit_nt_'

    # generating network create command and network names separated by spaces for the temp file
    lab_links_text = ''
    lab_machines_text = ''

    create_network_template = docker + ' network create '
    create_network_commands = []

    base_path = os.path.join(os.environ['NETKIT_HOME'], 'temp')
    if PLATFORM != WINDOWS:
        base_path = os.path.join(os.environ['HOME'], 'netkit_temp')
    network_counter = 0
    if not os.path.exists(os.path.join(base_path, 'last_network_counter.txt')):
        last_network_counter = open(
            os.path.join(base_path, 'last_network_counter.txt'), 'w')
        last_network_counter.close()

    with open(os.path.join(base_path, 'last_network_counter.txt'),
              'r') as last_network_counter:
        try:
            network_counter = int(last_network_counter.readline())
        except:
            network_counter = 0
        for link in links:
            create_network_commands.append(create_network_template + prefix +
                                           link + " --subnet=172." +
                                           str(19 + network_counter) +
                                           ".0.0/16 --gateway=172." +
                                           str(19 + network_counter) + ".0.1")
            lab_links_text += prefix + link + ' '
            network_counter = (network_counter + 1) % 236
            create_network_commands.append(
                os.path.join(os.environ['NETKIT_HOME'],
                             'brctl_config ' + prefix + link))
    with open(os.path.join(base_path, 'last_network_counter.txt'),
              'w') as last_network_counter:
        last_network_counter.write(str(network_counter))

    # writing the network list in the temp file
    if not execbash:
        if not PRINT:
            u.write_temp(lab_links_text,
                         str(u.generate_urlsafe_hash(path)) + '_links',
                         PLATFORM,
                         file_mode="w+")

    # generating commands for running the containers, copying the config folder and executing the terminals connected to the containers
    if PLATFORM != WINDOWS:
        create_machine_template = docker + ' run -tid --privileged=true --name ' + prefix + '{machine_name} --hostname={machine_name} --network=' + prefix + '{first_link} {machine_options} {image_name}'
    else:
        create_machine_template = docker + ' run --volume="' + os.path.expanduser(
            '~'
        ) + '":/hosthome -tid --privileged=true --name ' + prefix + '{machine_name} --hostname={machine_name} --network=' + prefix + '{first_link} {machine_options} {image_name}'
    # we could use -ti -a stdin -a stdout and then /bin/bash -c "commands;bash",
    # but that woult execute commands like ifconfig BEFORE all the networks are linked
    create_machine_commands = []

    create_connection_template = docker + ' network connect ' + prefix + '{link} ' + prefix + '{machine_name}'
    create_bridge_connection_template = docker + ' network connect {link} ' + prefix + '{machine_name}'
    create_connection_commands = []
    create_bridge_connection_commands = []

    copy_folder_template = docker + ' cp "' + path + '{machine_name}/{folder_or_file}" ' + prefix + '{machine_name}:/{dest}'
    copy_folder_commands = []

    exec_template = docker + ' exec {params} -i --privileged=true ' + prefix + '{machine_name} {command}'
    exec_commands = []
    startup_commands = []

    count = 0

    for machine_name, interfaces in machines.items():
        this_image = DOCKER_HUB_PREFIX + IMAGE_NAME
        this_shell = 'bash'

        # copying the hostlab directory
        if not execbash:
            copy_folder_commands.append(docker + ' cp "' + path + '" ' +
                                        prefix + machine_name + ':/hostlab')

        #get the shell we run inside docker
        if options.get(machine_name):
            matching = [s for s in options[machine_name] if "shell" in s]
            if len(matching) > 0:
                this_shell = matching[0][1]

        # applying docker patch for /proc and icmp
        repls = ('{machine_name}', machine_name), (
            '{command}', this_shell +
            ' -c "sysctl net.ipv4.conf.all.rp_filter=0"'), ('{params}', '')
        startup_commands.insert(0,
                                u.replace_multiple_items(repls, exec_template))
        repls = ('{machine_name}', machine_name), (
            '{command}', this_shell +
            ' -c "sysctl net.ipv4.conf.default.rp_filter=0"'), ('{params}', '')
        startup_commands.insert(1,
                                u.replace_multiple_items(repls, exec_template))
        repls = ('{machine_name}', machine_name), (
            '{command}', this_shell +
            ' -c "sysctl net.ipv4.conf.lo.rp_filter=0"'), ('{params}', '')
        startup_commands.insert(2,
                                u.replace_multiple_items(repls, exec_template))
        repls = ('{machine_name}', machine_name), (
            '{command}', this_shell +
            ' -c "sysctl net.ipv4.conf.eth0.rp_filter=0"'), ('{params}', '')
        startup_commands.insert(2,
                                u.replace_multiple_items(repls, exec_template))

        # Parsing options from lab.conf
        machine_option_string = " "
        if options.get(machine_name):
            for opt, val in options[machine_name]:
                if opt == 'mem' or opt == 'M':
                    machine_option_string += '--memory=' + val.upper() + ' '
                if opt == 'image' or opt == 'i' or opt == 'model-fs' or opt == 'm' or opt == 'f' or opt == 'filesystem':
                    this_image = DOCKER_HUB_PREFIX + val
                if opt == 'eth':
                    app = val.split(":")
                    create_network_commands.append(create_network_template +
                                                   prefix + app[1])
                    repls = ('{link}', app[1]), ('{machine_name}',
                                                 machine_name)
                    create_connection_commands.append(
                        u.replace_multiple_items(repls,
                                                 create_connection_template))
                    if not PRINT:
                        u.write_temp(" " + prefix + app[1],
                                     u.generate_urlsafe_hash(path) + '_links',
                                     PLATFORM)
                    repls = ('{machine_name}',
                             machine_name), ('{command}', this_shell +
                                             ' -c "sysctl net.ipv4.conf.eth' +
                                             str(app[0]) +
                                             '.rp_filter=0"'), ('{params}', '')
                    startup_commands.insert(
                        4, u.replace_multiple_items(repls, exec_template))
                if opt == 'bridged':
                    repls = ('{link}', "bridge"), ('{machine_name}',
                                                   machine_name)
                    create_bridge_connection_commands.append(
                        u.replace_multiple_items(
                            repls, create_bridge_connection_template))
                if opt == 'e' or opt == 'exec':
                    repls = ('{machine_name}', machine_name), (
                        '{command}', this_shell +
                        ' -c "' + val.strip().replace('\\', r'\\').replace(
                            '"', r'\\"').replace("'", r"\\'") +
                        '"'), ('{params}', '-d')
                    startup_commands.append(
                        u.replace_multiple_items(repls, exec_template))
                if opt == 'port':
                    machine_option_string += '-p=' + val.upper(
                    ) + ':3000' + ' '
        repls = ('{machine_name}', machine_name), ('{number}', str(count)), (
            '{first_link}',
            interfaces[0][0]), ('{image_name}',
                                this_image), ('{machine_options}',
                                              machine_option_string)
        create_machine_commands.append(
            u.replace_multiple_items(repls, create_machine_template))
        count += 1
        eth_cnt = 1
        for link, _ in interfaces[1:]:
            repls = ('{link}', link), ('{machine_name}', machine_name)
            create_connection_commands.append(
                u.replace_multiple_items(repls, create_connection_template))
            repls = ('{machine_name}',
                     machine_name), ('{command}', this_shell +
                                     ' -c "sysctl net.ipv4.conf.eth' +
                                     str(eth_cnt) +
                                     '.rp_filter=0"'), ('{params}', '')
            startup_commands.insert(
                4, u.replace_multiple_items(repls, exec_template))
            eth_cnt += 1
        # convoluted method to copy MACHINE_NAME/etc folder to the etc of the container
        if os.path.exists(os.path.join(path, machine_name)) and not execbash:
            for folder_or_file in os.listdir(os.path.join(path, machine_name)):
                if folder_or_file == 'etc':
                    repls = ('{machine_name}',
                             machine_name), ('{machine_name}', machine_name), (
                                 '{folder_or_file}',
                                 folder_or_file), ('{dest}', 'temp_etc')
                    repls2 = ('{machine_name}', machine_name), (
                        '{command}', this_shell +
                        ' -c "chmod -R 777 /temp_etc/*; cp -rfp /temp_etc/* /etc/; rm -rf /temp_etc; mkdir /var/log/zebra; chmod -R 777 /var/log/quagga; chmod -R 777 /var/log/zebra; chmod -R 777 /var/www/*"'
                    ), ('{params}', '')
                    startup_commands.insert(
                        0, u.replace_multiple_items(repls2, exec_template))
                else:
                    repls = ('{machine_name}',
                             machine_name), ('{machine_name}', machine_name), (
                                 '{folder_or_file}',
                                 folder_or_file), ('{dest}', '')
                copy_folder_commands.append(
                    u.replace_multiple_items(repls, copy_folder_template))
        if PLATFORM == WINDOWS:
            repls = ('{machine_name}',
                     machine_name), ('{command}', this_shell +
                                     ' -c "echo -ne \'\033]0;' + machine_name +
                                     '\007\'; bash"'), ('{params}',
                                                        '-t -e TERM=vt100')
        else:
            repls = ('{machine_name}',
                     machine_name), ('{command}',
                                     this_shell), ('{params}',
                                                   '-t -e TERM=vt100')
        exec_commands.append(u.replace_multiple_items(repls, exec_template))
        lab_machines_text += prefix + machine_name + ' '

    # writing the container list in the temp file
    if not no_machines_tmp:
        if not execbash:
            if not PRINT:
                u.write_temp(lab_machines_text,
                             str(u.generate_urlsafe_hash(path)) + '_machines',
                             PLATFORM)

    # for each machine we have to get the machine.startup file and insert every non empty line as a string inside an array of exec commands. We also replace escapes and quotes
    for machine_name, _ in machines.items():
        startup_file = os.path.join(path, machine_name + '.startup')
        if os.path.exists(startup_file):
            f = open(startup_file, 'r')
            full_startup_command = ''
            for line in f:
                if line.strip() and (line.strip() not in [
                        '\n', '\r\n', '\n\r'
                ]) and (not line.startswith('#')):
                    full_startup_command += line.strip().replace(
                        '\\', r'\\').replace('"', r'\"').replace("'",
                                                                 r"\'") + ';'
            f.close()
            repls = ('{machine_name}',
                     machine_name), ('{command}', this_shell + ' -c "' +
                                     full_startup_command + '"'), ('{params}',
                                                                   '-d')
            startup_commands.append(
                u.replace_multiple_items(repls, exec_template))

    commands = create_network_commands + create_machine_commands + create_connection_commands + create_bridge_connection_commands + copy_folder_commands

    return commands, startup_commands, exec_commands
Exemple #4
0
DEBUG = nc.DEBUG
nc.DEBUG = False

parser = argparse.ArgumentParser(description='Create and start a Netkit Lab.')
parser.add_argument('path')
parser.add_argument('-d',
                    '--directory',
                    required=False,
                    help='Folder contining the lab.')
parser.add_argument(
    '--print',
    dest="print_only",
    required=False,
    action='store_true',
    help=
    'Print commands used to start the containers to stderr (containers are not started).'
)

args, unknown = parser.parse_known_args()

lab_path = args.path.replace('"', '').replace("'", '').replace("//", '/')
if args.directory:
    lab_path = args.directory.replace('"', '').replace("'",
                                                       '').replace("//", '/')

if args.print_only and nc.PLATFORM == nc.WINDOWS:  #linux still needs the hash for the while statement
    print " "
else:
    print u.generate_urlsafe_hash(lab_path)