summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/sunhpc/commands/__init__.py19
-rw-r--r--lib/sunhpc/commands/pxelinux/build/__init__.py19
-rw-r--r--lib/sunhpc/commands/pxelinux/build/cdpxe/__init__.py406
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"