#!/usr/bin/python
# copyright (C) 2013 FUJITSU LIMITED All Rights Reserved

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

# -*- coding: utf-8 -*-

import sys
import os
import fcntl
import ConfigParser
import IPy
from optparse import OptionParser

CONFIG_FILE = '/etc/lxcf/lxcf.conf'
HOSTS_FILE = '/etc/hosts'

# check root
if os.geteuid() != 0:
    print "error: Because you are not root, you cannot execute this command. "
    exit(-1)

parser = OptionParser()
(options, args) = parser.parse_args(sys.argv)

argc = len(args)

if (argc != 2):
    print "usage : lxcf-clone-setup  LXCNAME"
    quit()

domain_name = args[1]

ETH0_FILE = ('/opt/lxcf/' + domain_name + '/etc/network/interfaces')


#
# Function for IP address
#


def erase_ipaddr(name, hosts_file):
    """erase IP addres from /etc/hosts"""
    # read hosts file and check ip addr
    try:
        f = open(hosts_file, "r")
    except:
        return

    Lines = f.readlines()

    f = open(hosts_file, "w")
    fcntl.flock(f.fileno(), fcntl.LOCK_EX)

    for l in Lines:
        S = l.split()
        if (len(S) >= 1):
            if ((S[0])[0] == '#'):
                continue
            if (name != S[1]):
                f.write(l)

    # unlock hosts file
    fcntl.flock(f.fileno(), fcntl.LOCK_UN)

    f.close()


def find_ipaddr(name, hosts_file):
    """find IP addres from /etc/hosts"""
    # read hosts file and check ip addr
    try:
        f = open(hosts_file, "r")
    except:
        return IPy.IP(1)

    while True:
        Line = f.readline()
        if (Line):
            S = Line.split()

            if (len(S) >= 1):
                if ((S[0])[0] == '#'):
                    continue

                try:
                    ip_s = IPy.IP(S[0])
                except:
                    continue

                if (name == S[1]):
                    f.close()
                    return ip_s
        else:
            break

    return IPy.IP(1)


def check_ipaddr(ip, hosts_file):
    """check IP address in /etc/hosts"""
    # read hosts file and check ip addr
    try:
        f = open(hosts_file, "r")
    except:
        return False

    while True:
        Line = f.readline()
        if (Line):
            S = Line.split()

            if (len(S) >= 1):
                if ((S[0])[0] == '#'):
                    continue

                try:
                    ip_s = IPy.IP(S[0])
                except:
                    continue

                if (ip_s == ip):
                    f.close()
                    return False
        else:
            break

    return True


def set_ipaddr(hosts_file, ipaddr, domain_name):
    """set new IP address"""
    try:
        with open(hosts_file, 'a') as f:
            f.write(ipaddr.strNormal()+'\t'+domain_name+'\n')
    except:
        pass


def get_ipaddr(hosts_file):
    """get new IP address"""
    # read the config file
    conf = ConfigParser.SafeConfigParser()
    conf.read(CONFIG_FILE)

    ipaddr_start = IPy.IP(conf.get('ipaddr_range', 'ipaddr_start'))
    ipaddr_end = IPy.IP(conf.get('ipaddr_range', 'ipaddr_end'))

    ip1 = ipaddr_start.int()
    ip2 = ipaddr_end.int()

    # looks for empty IP.address
    for i in range(ip1, ip2+1):
        ipa = IPy.IP(i)
        if (check_ipaddr(ipa, hosts_file)):
            break

    set_ipaddr(hosts_file, ipa, domain_name)
    return ipa


def clone_ipaddr(hosts_file):
    """clone IP addres"""
    # get the dist ip address
    dist_ip = get_ipaddr(hosts_file)

    # lock ifcfg-eth0 file
    rfp = file(ETH0_FILE, "r")

    fcntl.flock(rfp.fileno(), fcntl.LOCK_EX)

    # read ifcfg-eth0 file and change ip addr
    try:
        f = open(ETH0_FILE, "r")
    except:
        return dist_ip

    Lines = f.readlines()
    f.close()

    try:
        f = open(ETH0_FILE, "w")
    except:
        return dist_ip

    flg = 0
    for l in Lines:
        if ( flg == 0 ):
            if (l[5:9] == "eth0"):
                flg = 1
            f.write(l)
        elif (flg == 1):
            if (l[0:7] == "address"):
                f.write("address "+dist_ip.strNormal()+"\n")
                flg = 2
            else:
                f.write(l)
        else:
            f.write(l)

    f.close()

    # lock network file
    try:
        rfp = file(NETWORK_FILE, "r")
    except:
        return dist_ip

    fcntl.flock(rfp.fileno(), fcntl.LOCK_EX)

    # read ifcfg-eth0 file and change ip addr
    try:
        f = open(NETWORK_FILE, "r")
    except:
        return dist_ip

    Lines = f.readlines()
    f.close()

    try:
        f = open(NETWORK_FILE, "w")
    except:
        return dist_ip

    f.close()
    return dist_ip

erase_ipaddr(domain_name, HOSTS_FILE)
newipaddr = clone_ipaddr(HOSTS_FILE)
for hfile in os.listdir('/opt/lxcf/'):
    hf = '/opt/lxcf/'+hfile+'/etc/hosts'
    erase_ipaddr(domain_name, hf)
    set_ipaddr(hf, newipaddr, domain_name)
