#coding:utf-8

import os
import sys
import sunhpc
import shutil
import textwrap
import subprocess
class Command(sunhpc.commands.pxelinux.build.command):
    """
    Build the tftp service for the sunhpc cluster.

    <param type='Path' name='PxeDir'>
    supply an pxelinux base directory.default:/tftpboot/pxelinux
    </param>

    <param type='Bool' name='Quiet'>
    Whether to output detailed information, default: no
    </param>
    
    <example cmd='pxelinux build tftpd'>
    In local build the tftp service.
    </example>

    <example cmd='pxelinux build tftpd pxedir=/tftpboot/pxelinux'>
    In local /tftpboot/pxelinux directory build the tftp service.
    </example>
    """
    def run(self, params, args):

        (self.basedir, quiet) = self.fillParams([
            ('pxedir', '/tftpboot/pxelinux'),
            ('quiet', 'no')])

        q = self.str2bool(quiet)
        self.msg('Starting build the tftpd service...', q=q)

        if not os.path.exists(self.basedir):
            self.msg('Create the tftpd dirctory ...', q=q)
            os.makedirs(self.basedir)

        self.pxecfg = os.path.join(self.basedir, 'pxelinux.cfg')
        if not os.path.exists(self.pxecfg):
            self.msg('Create the pxelinux.cfg dirctory ...', q=q)
            os.makedirs(self.pxecfg)

        shared  = os.path.join(self.prefix, 'share/isobuild/anaconda-shared')

        os.chmod(self.pxecfg, 0o755)
        self.create_user('apache', uid=48, gid=48, home='/var/apache', nohome=1, shell='/sbin/nologin')
        os.system('chown -R root.apache %s' % self.pxecfg)
            
        distbase    = self.command('report.distro',[]).strip()
        distname    = self.db.getHostAttr('localhost', 'distribution')
        distro      = os.path.join(distbase, distname, self.arch)
        images      = os.path.join(distro, 'images')

        pxefile =  os.listdir(images) + os.listdir(shared)
        for i in pxefile:
            if i.startswith('initrd'):
                self.msg('Copying to %s - %s' % (self.basedir, i), q=q)
                self.copyit(os.path.join(images, i), os.path.join(self.basedir, i), 0o755, '0.0')

            if i.startswith('vmlinuz'):
                self.msg('Copying to %s - %s' % (self.basedir, i), q=q)
                self.copyit(os.path.join(images, i), os.path.join(self.basedir, i), 0o755, '0.0')

            if i.startswith('efiboot.img'):
                self.msg('Copying to %s - %s' % (self.basedir, i), q=q)
                self.copyit(os.path.join(images, i), os.path.join(self.basedir, i), 0o644, '0.0')

            if i.startswith('pxelinux.0'):
                self.msg('Copying to %s - %s' % (self.basedir, i), q=q)
                self.copyit(os.path.join(shared, i), os.path.join(self.basedir, i), 0o644, '0.0')

            if i.startswith('gpxelinux.0'):
                self.msg('Copying to %s - %s' % (self.basedir, i), q=q)
                self.copyit(os.path.join(shared, i), os.path.join(self.basedir, i), 0o644, '0.0')

            if i.startswith('memtest'):
                self.msg('Copying to %s - %s' % (self.basedir, i), q=q)
                self.copyit(os.path.join(shared, i), os.path.join(self.basedir, i), 0o755, '0.0')

        # write the pxelinux default file
        self.writeDefault(q)

        # install tftp server
        self.installTftpd(q)

    def writeDefault(self, q):
        default = os.path.join(self.pxecfg, 'default')
        
        self.msg('Configure pxelinux default boot file to %s ' % (default), q=q)
        self.db.execute('select kernel, ramdisk, args from bootactions where id=1')
        vmlinuz, initrd, argsks = self.db.fetchone()

        with open(default, 'w') as f:
            f.write('#\n# Generated by sunhpc pxelinux build tftpd\n#\n')
            f.write('default sunhpc\n')
            f.write('prompt 0\n')
            f.write('label sunhpc\n')
            f.write('   kernel %s\n' % vmlinuz)
            f.write('   append initrd=%s %s \n' % (initrd, argsks))
        os.chmod(default, 0o0664)
        os.system('chown root.apache %s' % default)

    def installTftpd(self, q):
        conf = '/etc/xinetd.d/tftp'
        hostname = self.db.getHostAttr('localhost', 'Kickstart_PrivateHostname')
        basedirs = self.db.getHostAttr('localhost', 'Kickstart_BaseDir')
        distdirs = self.command('report.distro')

        # The httpd is not installed.
        if not os.path.exists(conf):
            self.shcmd('yum install -y tftp tftp-server syslinux --enablerepo=Sunhpc-%s' % sunhpc.version)

        self.fw.addports(['69'], ['udp'])
        self.fw.addservice('tftp')

        sunhpc_tftpd_conf = '/etc/xinetd.d/tftp'
        with open(sunhpc_tftpd_conf, 'w') as f:
            f.write(textwrap.dedent("""\
                # default: off
                #   protocol.  The tftp protocol is often used to boot diskless
                #   workstations, download configuration files to network-aware printers,
                #   and to start the installation process for some operating systems.
                service tftp
                {
                    socket_type     = dgram
                    protocol        = udp
                    wait            = yes
                    user            = root
                    server          = /usr/sbin/in.tftpd
                    server_args     = -s %s -B 1468
                    disable         = no
                    per_source      = 11
                    cps             = 100 2
                    flags           = IPv4
                }
            """ % self.basedir))

        tftpd_service_conf = '/usr/lib/systemd/system/tftp.service'
        with open(tftpd_service_conf, 'w') as f:
            f.write(textwrap.dedent(f"""\
                [Unit]
                Description=Tftp Server
                Requires=tftp.socket
                Documentation=man:in.tftpd

                [Service]
                ExecStart=/usr/sbin/in.tftpd -s {self.basedir}
                StandardInput=socket

                [Install]
                Also=tftp.socket
            """))

        self.shcmd('systemctl daemon-reload')
        self.shcmd('systemctl start tftp')
        self.shcmd('systemctl enable tftp.socket')

    def copyit(self, src, dst, perms=0o644, owner=None):
        if not os.path.exists(src):
            self.msg('The %s not exists.' % src, 'a')

        if os.path.exists(dst): os.remove(dst)

        shutil.copyfile(src, dst)
        os.chmod(dst, perms)
        if owner:
            os.system('chown %s %s' % (owner, dst))

RollName = "base"
