diff options
author | kelvin <xiubuzhe@sina.com> | 2023-12-20 20:27:21 +0800 |
---|---|---|
committer | kelvin <xiubuzhe@sina.com> | 2023-12-20 20:27:21 +0800 |
commit | 689ae7255b5d2958aba47f7c406394396ad482ea (patch) | |
tree | 5a2bdc9f818fca604997aabed3f5dc56dcd7fd92 /lib | |
parent | 8a52a10fb6d6f6802872cc7ceee6f38ccd631c9b (diff) | |
download | sunhpc-689ae7255b5d2958aba47f7c406394396ad482ea.tar.gz sunhpc-689ae7255b5d2958aba47f7c406394396ad482ea.tar.bz2 sunhpc-689ae7255b5d2958aba47f7c406394396ad482ea.zip |
fix cdpxe module
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sunhpc/commands/__init__.py | 19 | ||||
-rw-r--r-- | lib/sunhpc/commands/pxelinux/build/__init__.py | 19 | ||||
-rw-r--r-- | lib/sunhpc/commands/pxelinux/build/cdpxe/__init__.py | 406 |
3 files changed, 404 insertions, 40 deletions
diff --git a/lib/sunhpc/commands/__init__.py b/lib/sunhpc/commands/__init__.py index 744273e..f52182a 100644 --- a/lib/sunhpc/commands/__init__.py +++ b/lib/sunhpc/commands/__init__.py @@ -770,6 +770,18 @@ class Command(object): return newline + def formatByte(self, number): + """格式化文件大小函数, number: 要格式化的字节数""" + symbols = ('KB', 'MB', 'GB', 'TB', 'PB') + prefix = {} + for i, s in enumerate(symbols): + prefix[s] = 1 << (i + 1) * 10 + for s in reversed(symbols): + if number >= prefix[s]: + value = float(number) / prefix[s] + return '%6.2f %s' % (value, s) + return '%s KB' % number + def shrun(self, cmd): return subprocess.run(cmd, shell=True, check=True) @@ -782,8 +794,11 @@ class Command(object): stderr=subprocess.PIPE) if ret == 'str': - info['o'] = p.stdout.read().decode('UTF-8') - info['e'] = p.stderr.read().decode('UTF-8') + out, err = p.communicate() + info['o'] = out.decode('UTF-8') + info['e'] = err.decode('UTF-8') + #info['o'] = p.stdout.read().decode('UTF-8') + #info['e'] = p.stderr.read().decode('UTF-8') if ret == 'list': info['o'] = [ l.decode('UTF-8') for l in p.stdout.readlines() ] info['e'] = [ l.decode('UTF-8') for l in p.stderr.readlines() ] diff --git a/lib/sunhpc/commands/pxelinux/build/__init__.py b/lib/sunhpc/commands/pxelinux/build/__init__.py index 370f846..dbcbb8c 100644 --- a/lib/sunhpc/commands/pxelinux/build/__init__.py +++ b/lib/sunhpc/commands/pxelinux/build/__init__.py @@ -241,25 +241,6 @@ class Command(command): roll_handler.umount_iso() if roll_handler.foreign: - local_repos = '/etc/yum.repos.d/Rocky-Local.repo' - with open(local_repos, 'w') as fn: - fn.write('#\n# Rocky-Local.repo\n# Generate by sunhpc\n#\n\n') - fn.write('[local-baseos]\n') - fn.write('name=Rocky Linux $releasever - Local - BaseOS\n') - fn.write('baseurl=file:///%s/BaseOS\n' % roll_handler.repodirs) - fn.write('gpgcheck=1\n') - fn.write('enabled=1\n') - fn.write('gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial\n\n') - - fn.write('[local-appstream]\n') - fn.write('name=Rocky Linux $releasever - Local - AppStream\n') - fn.write('baseurl=file:///%s/AppStream\n' % roll_handler.repodirs) - fn.write('gpgcheck=1\n') - fn.write('enabled=1\n') - fn.write('gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial\n\n') - - self.msg('Add %s to %s' % (roll_handler.repodirs, local_repos)) - self.msg(' Use the command: yum/dnf repolist all') sys.exit(0) if pxesrv: diff --git a/lib/sunhpc/commands/pxelinux/build/cdpxe/__init__.py b/lib/sunhpc/commands/pxelinux/build/cdpxe/__init__.py index a245cae..e409e0a 100644 --- a/lib/sunhpc/commands/pxelinux/build/cdpxe/__init__.py +++ b/lib/sunhpc/commands/pxelinux/build/cdpxe/__init__.py @@ -17,6 +17,18 @@ class Command(sunhpc.commands.pxelinux.build.command): <param type='name' name='dev'> supply an network device name,e.g,, eth0,eth1... </param> + + <param type='path' name='repo'> + supply an pxe repo path,e.g,, /export/sunhpc/install/repos/Rocky/8/x86_64/ + </param> + + <param type='path' name='pxedir'> + supply an pxelinux dirs. Default: /tftpboot/pxelinux + </param> + + <param type='string' name='boot'> + supply an boot mode, mbr or uefi. Default: UEFI + </param> <example cmd='pxelinux build cdpxe'> In local build the iso pxe dhcpd, tftpd, httpd services. @@ -26,40 +38,397 @@ class Command(sunhpc.commands.pxelinux.build.command): Build the iso pxe dhcpd, tftpd, httpd service. </example> """ + def writeRepos(self, repo_dirs): + + base_repo = os.path.join(repo_dirs, 'BaseOS') + apps_repo = os.path.join(repo_dirs, 'AppStream') + + local_repos = '/etc/yum.repos.d/sunhpc-local.repo' + with open(local_repos, 'w') as fn: + fn.write('#\n# sunhpc-local.repo\n# Generate by sunhpc\n#\n\n') + fn.write('[sunhpc-baseos]\n') + fn.write('name=Sunhpc Linux $releasever - Local - BaseOS\n') + fn.write('baseurl=file://%s\n' % base_repo) + fn.write('gpgcheck=1\n') + fn.write('enabled=1\n') + fn.write('gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial\n\n') + + fn.write('[sunhpc-appstream]\n') + fn.write('name=Sunhpc Linux $releasever - Local - AppStream\n') + fn.write('baseurl=file://%s\n' % apps_repo) + fn.write('gpgcheck=1\n') + fn.write('enabled=1\n') + fn.write('gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial\n\n') + + 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)) + + def writeKSRepos(self, ksdirs, httpd_repos, rpath, addr): + if not os.path.exists(ksdirs): + os.makedirs(ksdirs) + + if not os.path.islink(httpd_repos): + os.symlink(rpath, httpd_repos) + + rootpw = '$6$eT.sWNwV69wyvhaR$N5tY4rJn6Y2slOrwuejfUBq3MhC5SNe1gUfTSYmOACObwW4ckUK9fjkKwC9TgSPhwwlaGdbtn0EFg11TJmAbC1' + usernm = 'admin' + userpw = '$6$0WN9CulSREVORA0S$FVWh6tkvdncbmSrsNPEb13GwxnGnEOKZliZLdL2IdY5E/fzLB8QmZAmgxyHh6ElSjObUCTbDEJ0l9.wRCRrsU.' + + bpacks, baddon, banaconda, bender = '%packages', '%addon', '%anaconda', '%end' + ksfile = os.path.join(ksdirs, 'kickstart.conf') + with open(ksfile, 'w') as f: + f.write(textwrap.dedent("""\ + #version=RHEL8 + # Use graphical install + graphical + + %s + @^graphical-server-environment + @container-management + @development + @graphical-admin-tools + @headless-management + @infiniband + @legacy-unix + @network-file-system-client + @performance + @remote-desktop-clients + @remote-system-management + @rpm-development-tools + @system-tools + @web-server + %s + + keyboard --xlayouts='us' + lang en_US.UTF-8 + firstboot --enable + timezone Asia/Shanghai --isUtc --nontp + + network --bootproto=dhcp --onboot=on --ipv6=auto + network --hostname=compute.local + clearpart --all --initlabel + autopart --type=lvm + + repo --name="AppStream" --baseurl=http://%s/redhat/AppStream + repo --name="BaseOS" --baseurl=http://%s/redhat/BaseOS + + rootpw --iscrypted %s + user --name=%s --password=%s --iscrypted --gecos="%s" + + %s com_redhat_kdump --disable --reserve-mb='auto' + %s + + %s + pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty + pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok + pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty + %s + """ % (bpacks, bender, addr, addr, rootpw, usernm, userpw, usernm, baddon, bender, banaconda, bender))) + + os.system('chmod 777 %s' % ksfile) + def run(self, params, args): - (quiet, devices) = self.fillParams([('quiet', 'no'), ('dev', None)]) + (quiet, pxedir, dev, rpath, boot) = self.fillParams([ + ('quiet', 'no'), + ('pxedir', '/tftpboot/pxelinux'), + ('dev', None), + ('repo', ''), + ('boot', 'uefi') + ]) q = self.str2bool(quiet) - self.msg('Starting build the dhcpd service...', q=q) - if devices is None: + if dev is None: self.msg('Must supply an network dev name,e.g,, eth0/eth1...', 'a') + address = os.popen("ip -4 addr show %s |grep inet|awk '{print $2}'" % dev).read().strip().split('/')[0] + + if not os.path.exists(rpath): + self.msg('supply an pxe repo path,e.g,, repo=/export/sunhpc/install/repos/Rocky/8/x86_64', 'a') + + # write new repos + self.writeRepos(rpath) + # install dhcp server - self.installDhcpd(q, devices) + self.installDhcpd(dev, boot, address, q) - def installDhcpd(self, q, devices): - config = '/etc/dhcp/dhcpd.conf' + # install tftp server + self.installTftpd(pxedir, rpath, boot, address, q) + + # install httpd server + self.installHttpd(dev, rpath, address, q) + + # off selinux + os.system('sed -i "s/SELINUX=enforcing/SELINUX=disabled/ /etc/selinux/config"') + + def installHttpd(self, devices, rpath, address, q): + self.msg('Starting build the httpd service...', q=q) + + rootdir = '/var/www/html' + ksdirs = os.path.join(rootdir, 'ks') + httpd_repos = os.path.join(rootdir, 'redhat') + self.writeKSRepos(ksdirs, httpd_repos, rpath, address) + + sunhpc_httpd_config = '/etc/httpd/conf.d/ks-sunhpc.conf' + if not os.path.exists(sunhpc_httpd_config): + cmds = 'yum install -y httpd' + cmds += '--disablerepo=* --enablerepo=sunhpc-appstream,sunhpc-baseos' + self.shcmd(cmds) + + cmds = 'sed -i "s/#ServerName www.example.com:80/ServerName localhost:80/" /etc/httpd/conf/httpd.conf' + self.shcmd(cmds) + + with open(sunhpc_httpd_config, 'w') as f: + f.write(textwrap.dedent("""\ + <VirtualHost %s:80> + ServerAdmin root@cluster.hpc.com + DocumentRoot %s + ServerName cluster.hpc.com + ErrorLog logs/ks-sunhpc-error_log + CustomLog logs/ks-sunhpc-access_log common + <Directory %s> + AllowOverride All + Require all granted + </Directory> + <Directory %s> + Options Indexes MultiViews + AllowOverride All + Require all granted + </Directory> + </VirtualHost> + """ % (address, rootdir, ksdirs, httpd_repos))) + + self.fw.addports(['80', '443'], ['tcp']) + self.fw.addservice('http') + self.fw.addservice('https') + os.system('systemctl daemon-reload') + os.system('systemctl restart httpd.service') + os.system('systemctl status httpd.service') + + + def installTftpd(self, pxedir, rpath, boot, address, q): + self.msg('Starting build the tftpd service...', q=q) + + sunhpc_tftpd_config = '/etc/xinetd.d/tftp' + # The dhcpd is not installed. + if not os.path.exists(sunhpc_tftpd_config): + cmds = 'yum install -y tftp tftp-server syslinux ' + cmds += '--disablerepo=* --enablerepo=sunhpc-appstream,sunhpc-baseos' + self.shcmd(cmds) + + if not os.path.exists(pxedir): + os.makedirs(pxedir) + + self.fw.addports(['69'], ['udp']) + self.fw.addservice('tftp') + + sunhpc_tftpd_config = '/etc/xinetd.d/tftp' + with open(sunhpc_tftpd_config, '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 + } + """ % pxedir)) + + tftpd_srvs_config = '/usr/lib/systemd/system/tftp.service' + with open(tftpd_srvs_config, '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 %s + StandardInput=socket + + [Install] + Also=tftp.socket + """ % pxedir)) + + os.system('systemctl daemon-reload') + os.system('systemctl restart tftp.service') + + # + # copy uefi boot file + # BaseOS/Packages/s/shim-x64-15.6-1.el8.x86_64.rpm + # BaseOS/Packages/g/grub2-efi-x64-2.02-142.el8.rocky.0.2.x86_64.rpm + # decompress: rpm2cpio xxx-xxx-xxx.rpm |cpio -dim + # boot/efi/EFI/BOOT/BOOTX64.EFI + # boot/efi/EFI/rocky/grubx64.efi + # + share = '/opt/sunhpc/share/pxeboot' + repos = os.path.join(rpath, 'isolinux') + + pxefile = os.listdir(share) + os.listdir(repos) + for i in pxefile: + if i.startswith('initrd.img'): + self.msg('Copying to %s - %s' % (pxedir, i), q=q) + self.copyit(os.path.join(repos, i), os.path.join(pxedir, i), 0o755, '0.0') + + if i.startswith('vmlinuz'): + self.msg('Copying to %s - %s' % (pxedir, i), q=q) + self.copyit(os.path.join(repos, i), os.path.join(pxedir, i), 0o755, '0.0') + + if i.startswith('memtest'): + self.msg('Copying to %s - %s' % (pxedir, i), q=q) + self.copyit(os.path.join(repos, i), os.path.join(pxedir, i), 0o755, '0.0') + + if i.startswith('BOOTX64.EFI'): + self.msg('Copying to %s - %s' % (pxedir, i), q=q) + self.copyit(os.path.join(share, i), os.path.join(pxedir, i), 0o644, '0.0') + + if i.startswith('grubx64.efi'): + self.msg('Copying to %s - %s' % (pxedir, i), q=q) + self.copyit(os.path.join(share, i), os.path.join(pxedir, i), 0o644, '0.0') + + if i.startswith('pxelinux.0'): + self.msg('Copying to %s - %s' % (pxedir, i), q=q) + self.copyit(os.path.join(share, i), os.path.join(pxedir, i), 0o644, '0.0') + + if i.startswith('ldlinux.c32'): + self.msg('Copying to %s - %s' % (pxedir, i), q=q) + self.copyit(os.path.join(share, i), os.path.join(pxedir, i), 0o644, '0.0') + + if i.startswith('lpxelinux.0'): + self.msg('Copying to %s - %s' % (pxedir, i), q=q) + self.copyit(os.path.join(share, i), os.path.join(pxedir, i), 0o644, '0.0') + + if i.startswith('gpxelinux.0'): + self.msg('Copying to %s - %s' % (pxedir, i), q=q) + self.copyit(os.path.join(share, i), os.path.join(pxedir, i), 0o644, '0.0') + + self.writeBootCFG(pxedir, boot, address, q) + + def writeBootCFG(self, pxedirs, boot, address, q): + + # pxedirs : /tftpboot/pxelinux + # boot : mbr + + ksfile = 'http://%s/ks/kickstart.conf' % address + images = 'http://%s/redhat/image/' % address + pxedir = os.path.join(pxedirs, 'pxelinux.cfg') + if not os.path.exists(pxedir): + os.makedirs(pxedir) + + if boot.lower() in ['mbr']: + + default = os.path.join(pxedir, 'default') + self.msg('Configure pxelinux pxe boot file to %s ' % (default), q=q) + with open(default, 'w') as f: + f.write(textwrap.dedent("""\ + # + # Generated by sunhpc pxelinux build tftpd + # + default sunhpc + prompt 0 + label sunhpc + kernel vmlinuz + append initrd=initrd.img inst.ks=%s inst.stage2=%s quiet net.ifnames=0 + """ % (ksfile, images))) + os.chmod(default, 0o0664) + os.system('chown root.apache %s' % default) + else: + + default = os.path.join(pxedirs, 'grub.cfg') + with open(default, 'w') as f: + f.write(textwrap.dedent("""\ + # + # the file generate by sunhpc + # + set timeout = 30 + menuentry 'Install Rocky 8' { + initrdefi pxelinux/initrd.img + linuxefi pxelinux/vmlinuz inst.ks=%s inst.stage2=%s quiet net.ifnames=0 + } + """ % (ksfile, images))) + + def installDhcpd(self, devices, boot, address, q): + self.msg('Starting build the dhcpd service...', q=q) + + config = '/etc/dhcp/dhcpd.conf' # The dhcpd is not installed. if not os.path.exists(config): - self.shcmd('yum install -y dhcp-server') + cmds = 'yum install -y dhcp-server ' + cmds += '--disablerepo=* --enablerepo=sunhpc-appstream,sunhpc-baseos' + self.shcmd(cmds) + + # 172.16.2.1 -> ['172','16','0'] -> 172.16.2 + addr_pre = '.'.join(address.split('.')[:3]) with open(config, 'w') as f: f.write(textwrap.dedent("""\ # # dhcpd.conf # - subnet 172.16.2.0 netmask 255.255.255.0 { - range 172.16.2.10 172.16.2.200; - option domain-name "hpc.com"; - option domain-name-servers 8.8.8.8; - option routers 172.16.2.1; - default-lease-time 600; - max-lease-time 7200; + + ddns-update-style none; + allow bootp; + allow booting; + option space pxelinux; + option pxelinux.magic code 208 = string; + option pxelinux.configfile code 209 = text; + option pxelinux.pathprefix code 210 = text; + option pxelinux.reboottime code 211 = unsigned integer 32; + option arch-type code 93 = unsigned integer 16; + + subnet %s.0 netmask 255.255.255.0 { + default-lease-time 600; + max-lease-time 7200; + + range %s.10 %s.200; + option routers %s; + option domain-name "local"; + option domain-name-servers %s; + option interface-mtu 1500; + + class "pxeclients" { + match if substring (option vendor-class-identifier, 0, 9) = "PXEClient"; + next-server %s; + + if exists user-class and option user-class = "iPXE" { + filename "ipxe_after/index.ipxe"; + } else { + if option arch-type = 00:00 { + # 0x00 0x00 x86 BIOS + filename "pxelinux.0"; + } else if option arch-type = 00:06 { + # 0x00 0x06 x86 UEFI + filename "BOOTX86.EFI"; + } else if option arch-type = 00:07 { + # 0x00 0x07 x64 UEFI + filename "BOOTX64.EFI"; + } else { + filename "pxelinux.0"; + } + } + } } - """)) + """ % (addr_pre, addr_pre, addr_pre, address, address, address))) dhcpd_srv_conf = '/usr/lib/systemd/system/dhcpd.service' with open(dhcpd_srv_conf, 'w') as f: @@ -81,10 +450,9 @@ class Command(sunhpc.commands.pxelinux.build.command): self.fw.addports(['67'], ['udp']) self.fw.addports(['68'], ['udp']) - self.shcmd('systemctl daemon-reload') - self.shcmd('systemctl stop dhcpd') - self.shcmd('systemctl start dhcpd') - self.shcmd('systemctl enable dhcpd') + self.fw.addservice('dhcp') + os.system('systemctl daemon-reload') + os.system('systemctl restart dhcpd') os.system('systemctl status dhcpd') RollName = "base" |