11 Commits

Author SHA1 Message Date
ecccb8bdf6 fix ks file add eula and firstboot=disable 2023-12-23 20:47:09 +08:00
f232a9316a add pxe files 2023-12-21 02:04:31 +08:00
689ae7255b fix cdpxe module 2023-12-20 20:27:21 +08:00
8a52a10fb6 add cdpxe command 2023-12-19 22:28:55 +08:00
e17ec5a485 fix synax error for distro 2023-12-19 15:52:30 +08:00
03a68da029 fix syntaxwarning error 2023-12-19 15:50:36 +08:00
f2733eef4e fix yumrepos 2023-12-19 13:58:09 +08:00
b89a492b6a fix bash-completion 2023-10-17 00:47:21 +08:00
6cb42d6b8d add bash-complete scripts 2023-10-15 23:51:49 +08:00
98fae3427e add bash-completion in /sbin/sunhpc-compxxxx-bak 2023-10-15 03:40:31 +08:00
4e37223538 add grub command 2023-10-11 18:33:26 +08:00
40 changed files with 2014 additions and 54 deletions

31
bin/completions-sunhpc.py Executable file
View File

@@ -0,0 +1,31 @@
#!/opt/sunpy3/bin/python3
import os
import sys
cword = int(os.environ['COMP_CWORD'])
cwords = os.environ['COMP_WORDS'].split()
cline = os.environ['COMP_LINE']
#curr = os.environ['COMP_CURR']
if 'sunhpc' in cwords:
cwords.remove('sunhpc')
commands = '/opt/sunhpc/lib/sunhpc/commands/'
modules = commands + '/'.join(cwords)
if os.path.exists(modules):
cmdpath = os.listdir(modules)
else:
cmdpath = os.listdir(commands)
print (modules)
print ('-------------------------------')
print(' '.join(cmdpath))
#print("candaidate1 candbidate2")
#print ('\n-cword---%s---' % cword)
#print ('\n-cwords--%s---' % cwords)
#print ('\n-cline---%s---' % cline)
#print ('\n-curr----%s---' % sys.argv)

View File

@@ -6,20 +6,14 @@ import sys
import sunhpc import sunhpc
import syslog import syslog
import shutil import shutil
import readline
import sunhpc.invoke import sunhpc.invoke
if sys.getdefaultencoding() != 'utf-8': if sys.getdefaultencoding() != 'utf-8':
reload(sys) reload(sys)
sys.setdefaultencoding('utf-8') sys.setdefaultencoding('utf-8')
def ttySize(): os.environ['COLUMNS'] = str(sunhpc.commands.get_help_width())
try:
(width, heigh) = shutil.get_terminal_size()
except:
width = 80
return width
os.environ['COLUMNS'] = str(ttySize())
syslog.openlog('SunhpcCMD', syslog.LOG_PID, syslog.LOG_LOCAL0) syslog.openlog('SunhpcCMD', syslog.LOG_PID, syslog.LOG_LOCAL0)
try: try:

View File

@@ -1 +1 @@
2023-04-16 08:28:49 2023-10-12 18:44:23

Binary file not shown.

55
etc/bash-complete-sunhpc Normal file
View File

@@ -0,0 +1,55 @@
# sunhpc(1) completion
#
# /etc/bash_completion.d/sunhpc
#
_sunhpc_array_delete_at()
{
eval "local ARRAY=(\"\${$1[@]}\")"
local i
local tmp=()
local lower=$2
local upper=${3:-$lower}
for i in "${!ARRAY[@]}"; do
if [[ "$i" -lt "$2" || "$i" -gt "${3-$2}" ]]; then
tmp=("${tmp[@]}" "${ARRAY[$i]}")
fi
done
eval "$1=(\"\${tmp[@]}\")"
}
_sunhpc()
{
local cur prev words cword i output
_init_completion || return
_sunhpc_array_delete_at words $((cword+1)) ${#words[@]}
_sunhpc_array_delete_at words 0
for i in ${!words[@]}; do
words[i]="$(printf '%s' "${words[i]}" | xargs printf '%s\n' 2>/dev/null || true)"
done
if [[ "$cur" =~ ^[[:space:]]+ ]]; then
cur=''
fi
output="$(sunhpc report completion ${words[@]} 2>/dev/null)"
if [ $? = 65 ]; then
compopt -o default
COMPREPLY=()
return 0
fi
#local IFS=$'\n'
COMPREPLY=( $( compgen -W '$output' -- ${cur} ) )
# do not append a space to words that end with =
[[ $COMPREPLY == *= ]] && compopt -o nospace
} &&
complete -F _sunhpc sunhpc
# ex: ts=4 sw=4 et filetype=sh

46
etc/sunhpc.conf Normal file
View File

@@ -0,0 +1,46 @@
#
# sunhpc cluster config file.
#
country CN
state LiaoNing
city DaLian
url https://www.sunhpc.com
name Sunhpc-cluster
contact info@sunhpc.com
worksdir /export
distrodir /export/sunhpc
partition default
safeport 372
safedirs safe.d
safesecurity safe-security
publichostname cluster.sunhpc.com
publicinterface eth0
publicaddress 172.16.1.1
publicgateway 172.16.1.1
publicnetmask 255.255.255.0
publicdnsserver 223.5.5.5
publicmacaddress B8:CA:3A:A8:C5:D3
publiccidr 24
publicnetwork 172.16.1.0
publicdomain sunhpc.com
publicmtu 1500
publicntphost pool.ntp.org
privatehostname cluster
privateinterface wlan0
privateaddress 192.168.199.146
privatenetmask 255.255.255.0
privatemacaddress 00:21:6A:A7:D5:62
privatecidr 24
privatenetwork 192.168.199.0
privatedomain local
privatemtu 1500
privatentphost cluster.local
timezone Asia/Shanghai
bootargs net.ifnames=0 biosdevname=0 ksdevice=bootif
basedir install
ganglia 224.0.0.3
nextserver 192.168.199.146
plugin_port 12345
pxefilename pxelinux.0
pxelinuxdir /tftpboot/pxelinux
distribution sunhpc-dist

View File

@@ -14,7 +14,6 @@ import socket
import syslog import syslog
import struct import struct
import sqlite3 import sqlite3
import termios
import argparse import argparse
import textwrap import textwrap
import datetime import datetime
@@ -38,10 +37,8 @@ DEFAULT_HELP_WIDTH = 8
def get_help_width(): def get_help_width():
try: try:
data = fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, '1234') (columns, heigh) = shutil.get_terminal_size()
columns = int(struct.unpack('hh', data)[1])
except (IOError, ValueError) as e: except (IOError, ValueError) as e:
print ("terminal size detection failed, using default width.")
return DEFAULT_HELP_WIDTH return DEFAULT_HELP_WIDTH
columns = columns - RIGHT_PADDING columns = columns - RIGHT_PADDING
@@ -653,12 +650,12 @@ class Command(object):
#print("\033[92m[+]\033[0m \033[96m%s\033[0m" % (msg)) #print("\033[92m[+]\033[0m \033[96m%s\033[0m" % (msg))
print("\033[92m[+]\033[0m %s" % (msg)) print("\033[92m[+]\033[0m %s" % (msg))
def message(self, msg, tag='[+]', end=''): def message(self, tag='[+]', msg=' ', end=' '):
header = '\033[92m%s\033[0m' % tag header = '\033[92m%s\033[0m' % tag
ender = '\033[95m%s\033[0m' % end ender = '\033[95m%s\033[0m' % end
msger = '\033[31m%s\033[0m' % msg msger = '\033[31m%s\033[0m' % msg
result = '%s %s %s' % (header, msger, ender) result = '%s %s %s' % (header, msger, ender)
return result print (result)
def abort(self, msg): def abort(self, msg):
@@ -773,6 +770,18 @@ class Command(object):
return newline 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): def shrun(self, cmd):
return subprocess.run(cmd, shell=True, check=True) return subprocess.run(cmd, shell=True, check=True)
@@ -785,8 +794,11 @@ class Command(object):
stderr=subprocess.PIPE) stderr=subprocess.PIPE)
if ret == 'str': if ret == 'str':
info['o'] = p.stdout.read().decode('UTF-8') out, err = p.communicate()
info['e'] = p.stderr.read().decode('UTF-8') 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': if ret == 'list':
info['o'] = [ l.decode('UTF-8') for l in p.stdout.readlines() ] info['o'] = [ l.decode('UTF-8') for l in p.stdout.readlines() ]
info['e'] = [ l.decode('UTF-8') for l in p.stderr.readlines() ] info['e'] = [ l.decode('UTF-8') for l in p.stderr.readlines() ]
@@ -856,7 +868,7 @@ class Command(object):
w, r ,e = (p.stdin, p.stdout, p.stderr) w, r ,e = (p.stdin, p.stdout, p.stderr)
currLength = 0 currLength = 0
prevLength = 0 prevLength = 0
spinChars = '-\|/' spinChars = r'-\|/'
spinIndex = 0 spinIndex = 0
while 1: while 1:
line = e.readline().decode() line = e.readline().decode()
@@ -977,17 +989,17 @@ class Command(object):
def getText(self): def getText(self):
return self.text return self.text
def dictOutput(self, strDict, sep='\t'): def dictOutput(self, strDict, sep=' '):
maxlen = max(map(len, strDict.keys())) maxlen = max(map(len, strDict.keys()))
for k in strDict: for k in strDict:
strings = str(strDict[k]) strings = str(strDict[k])
if strings.strip().lower() in ['ok', 'on', 'yes']: if strings.strip().lower() in ['ok', 'on', 'yes']:
value = '|\033[1;32m %s \033[0m' % strings.upper() value = '\033[1;32m %s \033[0m' % strings.upper()
elif strings.strip().lower() in ['fail', 'off', 'no', 'error', 'failed']: elif strings.strip().lower() in ['fail', 'off', 'no', 'error', 'failed']:
value = '|\033[1;31m %s \033[0m' % strings.upper() value = '\033[1;31m %s \033[0m' % strings.upper()
else: else:
value = '| %s' % strings value = '%s' % strings
print ('\t\033[1;95m%s\033[0m %s \033[1;96m%s\033[0m' % (k.ljust(maxlen), sep, value)) print ('\t\033[1;95m%s\033[0m %s = \033[1;96m%s\033[0m' % (k.ljust(maxlen), sep, value))
def beginFmtOutput(self, header=[]): def beginFmtOutput(self, header=[]):
self.fmtOutput = prettytable.PrettyTable(header) self.fmtOutput = prettytable.PrettyTable(header)
@@ -1255,8 +1267,22 @@ class Command(object):
o.runWrapper(n, args) o.runWrapper(n, args)
return o.getText() return o.getText()
def remove_empty_values(self, input_list):
"""
从列表中删除空值
:param input_list: 输入的列表
:return: 不包含空值的新列表
"""
# 使用列表推导式过滤掉空值
result_list = [value for value in input_list if value is not None and value != ""]
return result_list
def runWrapper(self, name, args): def runWrapper(self, name, args):
# 删除所有空值和None.
args = self.remove_empty_values(args)
username = pwd.getpwuid(os.geteuid())[0] username = pwd.getpwuid(os.geteuid())[0]
if args: if args:
command = '%s %s' % (name, ' '.join(args)) command = '%s %s' % (name, ' '.join(args))
@@ -1269,7 +1295,7 @@ class Command(object):
pdict = {} pdict = {}
plist = [] plist = []
nparams = 0 nparams = 0
flagpattern=re.compile("^[a-zA-z0-9\-_+]+=") flagpattern=re.compile(r"^[a-zA-z0-9\-_+]+=")
for arg in args: for arg in args:
tokens = arg.split() tokens = arg.split()
if tokens[0] == 'select': if tokens[0] == 'select':
@@ -1543,7 +1569,7 @@ class DocStringHandler(
s += '*[%s]*' % name s += '*[%s]*' % name
else: else:
s += '*{%s}*' % name s += '*{%s}*' % name
txt = txt.replace('*', '\*') txt = txt.replace('*', '\\*')
s += '\n%s\n' % txt.replace('\t', ' ') s += '\n%s\n' % txt.replace('\t', ' ')
if self.section['param']: if self.section['param']:
s += '\n**Parameters:**\n\n' s += '\n**Parameters:**\n\n'
@@ -1553,12 +1579,12 @@ class DocStringHandler(
s += '*[%s=%s]*' % (name, type) s += '*[%s=%s]*' % (name, type)
else: else:
s += '*{%s=%s}*' % (name, type) s += '*{%s=%s}*' % (name, type)
txt = txt.replace('*', '\*') txt = txt.replace('*', '\\*')
s += '\n%s\n' % txt.replace('\t', ' ') s += '\n%s\n' % txt.replace('\t', ' ')
if self.section['example']: if self.section['example']:
s += '\n**Examples:**\n' s += '\n**Examples:**\n'
for (cmd, txt) in self.section['example']: for (cmd, txt) in self.section['example']:
txt = txt.replace('*', '\*') txt = txt.replace("*", "\\*")
s += '%s::\n\n' % txt.replace('\t',' ') s += '%s::\n\n' % txt.replace('\t',' ')
s += ' %s sunhpc %s\n' % (prompt, cmd) s += ' %s sunhpc %s\n' % (prompt, cmd)
if self.section['related']: if self.section['related']:

View File

@@ -0,0 +1,84 @@
#
#coding:utf-8
#
#Author : QCSun
#Email : qcsun@sunhpc.com
#Times : 2023-04-14 05:21:02
#WebSite : https://www.sunhpc.com
import os
import re
import sys
import sunhpc
import readline
from sunhpc.core.interpreter import SunhpcInterpreter
class Struct(object):
pass
class command(sunhpc.commands.build.command):
pass
class Command(command, SunhpcInterpreter):
#class Command(command):
"""
Initialzed the sunhpc database.
"""
def run(self, params, args):
SunhpcInterpreter.__init__(self)
self.results = {}
self.results['country'] = 'CN'
self.results['state'] = 'LiaoNing'
self.results['city'] = 'Dalian'
self.results['url'] = 'https://www.sunhpc.com'
self.current_keys = list(self.results.keys())
self.current_values = self.results
self.start()
def preceding(self):
print(' 下列是数据库的初始化配置的基础选项.')
print(' 可以使用命令 set key=value 进行修改:\n')
self.dictOutput(self.results)
print(' ---------------------------------------------\n')
def _SunhpcInterpreter__show_all(self, root=''):
self.dictOutput(self.current_values)

View File

@@ -466,12 +466,12 @@ class Command(command):
Networks = ''' Networks = '''
CREATE TABLE Networks ( CREATE TABLE Networks (
ID integer NOT NULL primary key autoincrement, ID integer NOT NULL primary key autoincrement,
Node integer(11) default NULL, Node integer(11) default NULL,
MAC varchar(64) default NULL, MAC varchar(64) default NULL,
IP varchar(32) default NULL, IP varchar(32) default NULL,
Name varchar(128) default NULL, Name varchar(128) default NULL,
Device varchar(32) default NULL, Device varchar(32) default NULL,
Subnet integer(11) default NULL, Subnet integer(11) default NULL,
Foreign key(subnet) references subnets(id) on delete cascade on update restrict, Foreign key(subnet) references subnets(id) on delete cascade on update restrict,
Foreign key(node) references nodes(id) on delete cascade on update restrict Foreign key(node) references nodes(id) on delete cascade on update restrict
)''' )'''

View File

@@ -133,7 +133,7 @@ class Command(sunhpc.commands.create.command):
mirrors = distro.getMirrors() mirrors = distro.getMirrors()
fullmirror = mirrors[0].getRollsPath() fullmirror = mirrors[0].getRollsPath()
# modify all dirs mode 755 # modify all dirs mode 755
os.system('find %s -type d ' % (fullmirror) + '-exec chmod -R 0755 {} \;') os.system(r'find %s -type d ' % (fullmirror) + r'-exec chmod -R 0755 {} \;')
if self.arch != arch and os.path.exists(dist): if self.arch != arch and os.path.exists(dist):
shutil.move(os.path.join(tempdist, arch), os.path.join(dist, arch)) shutil.move(os.path.join(tempdist, arch), os.path.join(dist, arch))

View File

@@ -25,6 +25,7 @@ class Command(sunhpc.commands.list.command):
def run(self, params, args): def run(self, params, args):
(subdir, cols) = self.fillParams([('subdir', ), ('cols', 80) ], params) (subdir, cols) = self.fillParams([('subdir', ), ('cols', 80) ], params)
if subdir: if subdir:
filepath = os.path.join(sunhpc.commands.__path__[0], subdir) filepath = os.path.join(sunhpc.commands.__path__[0], subdir)
modpath = 'sunhpc.commands.%s' % '.'.join(subdir.split(os.sep)) modpath = 'sunhpc.commands.%s' % '.'.join(subdir.split(os.sep))

View File

@@ -12,7 +12,10 @@ class RollHandler(object):
self.cmd = cmd self.cmd = cmd
self.clean = clean self.clean = clean
self.mntdir = mnt self.mntdir = mnt
self.repodirs = ''
self.rinfo = None self.rinfo = None
self.isoname = 'unknown'
self.foreign = False
def is_mounted(self): def is_mounted(self):
cmd = 'mount |grep %s' % self.mntdir cmd = 'mount |grep %s' % self.mntdir
@@ -22,12 +25,13 @@ class RollHandler(object):
def mount_iso(self, iso): def mount_iso(self, iso):
subprocess.run('mount -r %s %s' % (iso, self.mntdir), shell=True, check=True) subprocess.run('mount -r %s %s' % (iso, self.mntdir), shell=True, check=True)
self.isoname = iso
def umount_iso(self): def umount_iso(self):
subprocess.run('umount %s' % self.mntdir, shell=True) subprocess.run('umount %s' % self.mntdir, shell=True)
def read_iso(self): def read_iso(self):
cmd = 'find %s -type f -name roll-\*.xml' % self.mntdir cmd = r'find %s -type f -name roll-\*.xml' % self.mntdir
ret = self.cmd.shcmd(cmd, code=True) ret = self.cmd.shcmd(cmd, code=True)
try: try:
roll = sunhpc.core.files.RollInfoFile(ret['o'].strip()) roll = sunhpc.core.files.RollInfoFile(ret['o'].strip())
@@ -36,7 +40,25 @@ class RollHandler(object):
pass pass
def foreign_roll(self): def foreign_roll(self):
self.cmd.msg('This ISO file cannot be recognized.This ISO was not produced by sunhpc created.', 'w') self.cmd.msg('The "%s" was not produced by sunhpc created.' % self.isoname, 'w')
# check iso .discinfo file
discinfo = os.path.join(self.mntdir, '.discinfo')
if not os.path.exists(discinfo):
self.cmd.msg('The %s is not exists.' % discinfo, 'a')
info = []
with open(discinfo, 'r') as fn:
info = fn.readlines()
try:
self.foreign = True
self.rinfo = sunhpc.core.utils.Struct()
self.rinfo.name = info[1].split()[0].strip()
self.rinfo.version = info[1].split()[-1].strip()
self.rinfo.arch = info[2].strip()
except IndexError:
self.foreign = False
def copy_iso(self): def copy_iso(self):
self.read_iso() self.read_iso()
@@ -47,11 +69,20 @@ class RollHandler(object):
def copy_roll(self): def copy_roll(self):
# self.rinfo是经过file.RollInfoFile处理过的,返回相应的类对象. # self.rinfo是经过file.RollInfoFile处理过的,返回相应的类对象.
roll_name = self.rinfo.getRollName() if self.foreign:
roll_vers = self.rinfo.getRollVersion() roll_name = self.rinfo.name
roll_arch = self.rinfo.getRollArch() roll_vers = self.rinfo.version
roll_os = self.rinfo.getRollOS() roll_arch = self.rinfo.arch
roll_boot = self.rinfo.isBootable() roll_os = self.cmd.os
roll_boot = None
roll_path = self.mntdir
else:
roll_name = self.rinfo.getRollName()
roll_vers = self.rinfo.getRollVersion()
roll_arch = self.rinfo.getRollArch()
roll_os = self.rinfo.getRollOS()
roll_boot = self.rinfo.isBootable()
roll_path = os.path.join(self.mntdir, roll_name)
# 获取rolls存放位置 # 获取rolls存放位置
cmd = '/opt/sunhpc/bin/sunhpc report distro' cmd = '/opt/sunhpc/bin/sunhpc report distro'
@@ -59,10 +90,16 @@ class RollHandler(object):
distro = line[:-1] distro = line[:-1]
# /export/sunhpc/install/rolls # /export/sunhpc/install/rolls
rolls_dir = '%s/rolls' % (distro) if self.foreign:
rolls_dir = '%s/repos' % (distro)
else:
rolls_dir = '%s/rolls' % (distro)
# /export/sunhpc/install/rolls/kernel...... # /export/sunhpc/install/rolls/kernel......
roll_dir = os.path.join(rolls_dir, roll_name) if self.foreign:
roll_dir = os.path.join(rolls_dir, roll_name, roll_vers, roll_arch)
else:
roll_dir = os.path.join(rolls_dir, roll_name)
if self.clean: if self.clean:
# /export/sunhpc/install/rolls/kernel/version/x86_64 # /export/sunhpc/install/rolls/kernel/version/x86_64
@@ -75,7 +112,7 @@ class RollHandler(object):
os.makedirs(specific_roll_dir) os.makedirs(specific_roll_dir)
cwd = os.getcwd() cwd = os.getcwd()
os.chdir(os.path.join(self.mntdir, roll_name)) os.chdir(roll_path)
# 计算一下大小 # 计算一下大小
cmd = 'du -sh %s' % self.mntdir cmd = 'du -sh %s' % self.mntdir
@@ -104,7 +141,7 @@ class RollHandler(object):
os.chdir(os.path.join(self.mntdir, roll_name)) os.chdir(os.path.join(self.mntdir, roll_name))
# 修改所有目录权限,确保所有人能够访问,例如Apache等. # 修改所有目录权限,确保所有人能够访问,例如Apache等.
self.cmd.shcmd("find %s -type d -exec chmod a+rx {} \;" % roll_dir, code=True) self.cmd.shcmd(r"find %s -type d -exec chmod a+rx {} \;" % roll_dir, code=True)
# 插入roll信息到数据库,如果存在则放弃插入. # 插入roll信息到数据库,如果存在则放弃插入.
rows = self.cmd.db.search('select * from rolls where' \ rows = self.cmd.db.search('select * from rolls where' \
@@ -122,6 +159,7 @@ class RollHandler(object):
# 如果是引导roll,需要使用软件Kylins create distro重新部署. # 如果是引导roll,需要使用软件Kylins create distro重新部署.
# 重新创建images,stage2,和相关连接相关任务. # 重新创建images,stage2,和相关连接相关任务.
self.cmd.msg('Copy the %s finished.' % roll_name) self.cmd.msg('Copy the %s finished.' % roll_name)
self.repodirs = roll_dir
def clean_dirs(self, dirs): def clean_dirs(self, dirs):
for root, dirs, files in os.walk(dirs, topdown=False): for root, dirs, files in os.walk(dirs, topdown=False):
@@ -202,6 +240,9 @@ class Command(command):
roll_handler.copy_iso() roll_handler.copy_iso()
roll_handler.umount_iso() roll_handler.umount_iso()
if roll_handler.foreign:
sys.exit(0)
if pxesrv: if pxesrv:
self.configSRV(q) self.configSRV(q)
else: else:

View File

@@ -0,0 +1,382 @@
#coding:utf-8
import os
import sys
import sunhpc
import shutil
import textwrap
import subprocess
class Command(sunhpc.commands.pxelinux.build.command):
"""
Build the iso pxe (dhcpd, tftpd, httpd service for the sunhpc cluster.
1) config interface(e,g.. eth0/eth1) ip address
2) source /opt/sunhpc/etc/env.sunhpc
3) git clone https://gitee.com/qcsun/sunhpc.git
4) git clone https://gitee.com/qcsun/tools.git
5) rpm -ivh tools/sunhpc-python-3.12.0-1.el8.x86_64.rpm
6) sunhpc pxelinux build Rocky-8.7-x86_64-dvd1.iso
7) sunhpc pxelinux build cdpxe dev=eth1 repo=/export/sunhpc/install/repos/Rocky/8/x86_64
<param type='Bool' name='Quiet'>
Whether to output detailed information, default: no
</param>
<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: MBR
</param>
<example cmd='pxelinux build cdpxe'>
In local build the iso pxe dhcpd, tftpd, httpd services.
</example>
<example cmd='pxelinux build cdpxe dev=eth1 repo=/export/sunhpc/install/repos/Rocky/8/x86_64'>
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 run(self, params, args):
(quiet, pxedir, dev, rpath, boot) = self.fillParams([
('quiet', 'no'),
('pxedir', '/tftpboot/pxelinux'),
('dev', None),
('repo', ''),
('boot', 'mbr')
])
q = self.str2bool(quiet)
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(dev, boot, address, q)
# 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=.*/SELINUX=disabled/g" /etc/selinux/config')
def installHttpd(self, devices, rpath, address, q):
self.msg('Starting build the httpd service...', q=q)
webdir = '/var/www/html'
ksdirs = os.path.join(webdir, 'ksfile')
redhat = os.path.join(webdir, 'redhat')
repos = os.path.join(redhat, 'r8')
if not os.path.exists(ksdirs):
os.makedirs(ksdirs)
if not os.path.exists(redhat):
os.makedirs(redhat)
if not os.path.islink(repos):
os.symlink(rpath, repos)
shared = '/opt/sunhpc/share/pxeboot/kickstart'
ksfile = os.listdir(shared)
for i in ksfile:
if i.startswith('r8_min.conf'):
self.msg('Copying to %s - %s' % (ksdirs, i), q=q)
self.copyit(os.path.join(shared, i), os.path.join(ksdirs, i), 0o755, '0.0')
if i.startswith('r8_gui.conf'):
self.msg('Copying to %s - %s' % (ksdirs, i), q=q)
self.copyit(os.path.join(shared, i), os.path.join(ksdirs, i), 0o755, '0.0')
if not os.path.exists(os.path.join(ksdirs, i)):
continue
# replace ip address for kickstart config file.
os.system('sed -i "s/ipaddress/%s/g" %s' % (address, os.path.join(ksdirs, i)))
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, webdir, ksdirs, 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)
# pxedir: /tftpboot/pxelinux
c7 = os.path.join(pxedir, 'c7')
r8 = os.path.join(pxedir, 'r8')
r9 = os.path.join(pxedir, 'r9')
pd = os.path.join(pxedir, 'pxelinux.cfg')
if not os.path.exists(pxedir):
os.makedirs(c7)
os.makedirs(r8)
os.makedirs(r9)
os.makedirs(pd)
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
# /usr/share/syslinux/{pxelinux.0, menu.c32}
# isolinux/{ldlinux.c32, libcom32.c32, libutil.c32}
# decompress: rpm2cpio xxx-xxx-xxx.rpm |cpio -dim
# boot/efi/EFI/BOOT/shimx64.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' % (r8, i), q=q)
self.copyit(os.path.join(repos, i), os.path.join(r8, i), 0o755, '0.0')
if i.startswith('vmlinuz'):
self.msg('Copying to %s - %s' % (r8, i), q=q)
self.copyit(os.path.join(repos, i), os.path.join(r8, i), 0o755, '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('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('libcom32.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('libutil.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('menu.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('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('shimx64.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('vesamenu.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('default'):
self.msg('Copying to %s - %s' % (pd, i), q=q)
self.copyit(os.path.join(share, i), os.path.join(pd, i), 0o644, '0.0')
# replace ip address for pxelinux.cfg/default
os.system('sed -i "s/ipaddress/%s/g" %s' % (address, os.path.join(pd, 'default')))
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):
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
#
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 option arch-type = 00:07 {
filename "shimx64.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:
f.write(textwrap.dedent("""\
[Unit]
Description=DHCPv4 Server Daemon
Documentation=man:dhcpd(8) man:dhcpd.conf(5)
Wants=network-online.target
After=network-online.target
After=time-sync.target
[Service]
Type=notify
ExecStart=/usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid %s
[Install]
WantedBy=multi-user.target
""" % devices))
self.fw.addports(['67'], ['udp'])
self.fw.addports(['68'], ['udp'])
self.fw.addservice('dhcp')
os.system('systemctl daemon-reload')
os.system('systemctl restart dhcpd')
os.system('systemctl status dhcpd')
RollName = "base"

View File

@@ -0,0 +1,110 @@
#coding:utf-8
import os
import sys
import json
import sunhpc
class Command(sunhpc.commands.report.command):
"""
Output the path prefix for the location of the Rocks distribution.
<example cmd='report distro'>
Output the current path prefix to the distribution.
</example>
"""
def run(self, params, args):
basepath = '/opt/sunhpc/lib'
cmd = args
dotscmd = ''
listcmd = []
module = None
if len(cmd):
s = 'sunhpc.commands.%s' % '.'.join(cmd)
try:
__import__(s)
module, listcmd, dotscmd = eval(s), s.split('.'), '.'.join(cmd)
i = 1
except:
module = None
else:
listcmd = ['sunhpc', 'commands']
if not module:
for i in range(len(args), 0, -1):
s = 'sunhpc.commands.%s' % '.'.join(args[:i])
try:
__import__(s)
module, listcmd, dotscmd = eval(s), s.split('.'), '.'.join(args[:i])
if module:
break
except ImportError:
listcmd = s.split('.')[:-1]
continue
cmdpath = os.path.join(basepath, '/'.join(listcmd))
cmddirs = []
for d in os.listdir(cmdpath):
tmpdirs = os.path.join(cmdpath, d)
if d.startswith('__'):
continue
if not os.path.isdir(tmpdirs):
continue
cmddirs.append(d)
print (' '.join(cmddirs))
try:
o = getattr(module, 'Command')(None)
except AttributeError:
sys.exit(0)
if o.MustBeRoot and not self.isRootUser():
sys.exit(0)
results = []
for arg in o.usage().split():
tmp = arg.split('=', 1)
if len(tmp) != 2:
continue
tmpstr = arg.replace('[', '')
tmpstr = tmpstr.replace(']', '')
tmpstr = tmpstr.split('=')[0] + '='
results.append(tmpstr)
print (' '.join(results))
RollName = "base"

View File

@@ -114,7 +114,7 @@ class Command(sunhpc.commands.report.command):
# #
# Generated by sunhpc report yumrepos commands. # Generated by sunhpc report yumrepos commands.
# #
[appstream] [baseos]
name=Rocky Linux $releasever - BaseOS name=Rocky Linux $releasever - BaseOS
%s %s
gpgcheck=1 gpgcheck=1
@@ -131,7 +131,7 @@ class Command(sunhpc.commands.report.command):
# #
# Generated by sunhpc report yumrepos commands. # Generated by sunhpc report yumrepos commands.
# #
[appstream] [rockyextras]
name=Rocky Linux $releasever - Extras name=Rocky Linux $releasever - Extras
%s %s
gpgcheck=1 gpgcheck=1

View File

@@ -0,0 +1,57 @@
#coding:utf-8
import os
import sys
import sunhpc
class command(sunhpc.commands.HostArgumentProcessor,
sunhpc.commands.set.command):
pass
class Command(command):
"""
Grub2 boot configure
<param type='strings' name='default'>
Set the default boot options
</param>
<example cmd='grub default=1'>
Set the default boot options index 1
</example>
"""
def run(self, params, args):
(default, ) = self.fillParams([
('default', None),
])
if default:
try:
default_number = int(default)
#self.msg('Please modify it manually by using the command: grubby --set-defautl-index=%s' % default)
info = self.message('[*]', 'Please modify it manually by using the command:', 'grubby --set-default-index=%s' % default)
print (info)
sys.exit(0)
except ValueError:
self.msg('The "default" parameters must be the numbers.', 'a')
current_kernel = os.popen('uname -r').read().strip()
self.msg('--> Current kernel: %s' % current_kernel)
default_kernel = os.popen('grubby --default-kernel').read().strip()
self.msg('--> Default kernel: %s' % default_kernel)
kernel_index = os.popen('grubby --default-index').read().strip()
self.msg('--> Default kernel index: %s' % kernel_index)
kernel_list = os.popen('grubby --info=ALL').readlines()
self.msg('')
self.msg('-------- All Kernel List begin----------')
for i in kernel_list:
self.msg(i.strip())
self.msg('-------- All Kernel List ender----------')
self.msg('')
self.msg('Using index number, you can change the default boot kernel.e,g.. sunhpc set grub default=1', 'i')
RollName = "base"

View File

@@ -51,7 +51,10 @@ class Command(command):
softname = 'autodock' softname = 'autodock'
suffname = 'tar.gz' suffname = 'tar.gz'
dirsname = os.path.join(source, 'hpcsoft', 'AutoDock') dirsname = os.path.join(source, 'hpcsoft', 'AutoDock')
verslist = self.getVersions(key=softname, suffix=suffname, dirs=dirsname) try:
verslist = self.getVersions(key=softname, suffix=suffname, dirs=dirsname)
except FileNotFoundError as e:
self.msg(str(e), 'a')
if len(args): if len(args):
version = args[0] version = args[0]

358
lib/sunhpc/core/app.py Normal file
View File

@@ -0,0 +1,358 @@
#
# Time for an initial checkin. Datastructure and general layout of the
# code is correct. Still need comparison code for File and RPM objects.
#
import os
import sys
import types
import sunhpc
import getopt
import sunhpc.invoke
import xml
from xml.sax import saxutils
from xml.sax import handler
from xml.sax import make_parser
from xml.sax._exceptions import SAXParseException
class Application:
def __init__(self, argv=None):
# Applets (code in the kickstart graph) doesn't pass sys.argv
# so pick it up anyway to keep everything working.
if not argv:
argv = sys.argv
self.args = []
self.caller_args = argv[1:]
self.usage_command = os.path.basename(argv[0])
self.usage_name = 'Application'
self.usage_version = 0
self.rcfileHandler = RCFileHandler
self.rcfileList = []
self.rcForce = []
self.projectName = 'sunhpc'
self.projectVersionName = 'base'
self.projectVersionMajor = sunhpc.version_major
self.projectVersionMinor = sunhpc.version_minor
self.projectVersionMicro = sunhpc.version_micro
self.getopt = sunhpc.core.utils.Struct()
self.getopt.s = [ 'h' ]
self.getopt.l = [ 'help',
'list-rcfiles',
'list-project-info',
'rcfile='
]
# Unset our local
try:
os.environ["LANG"]
except KeyError:
pass
def run(self):
sys.exit(-1)
def projectInfo(self):
return [ self.projectName,
self.projectVersionName,
int(self.projectVersionMajor),
int(self.projectVersionMinor),
int(self.projectVersionMicro) ]
def getArgs(self):
return self.args
def setArgs(self, argslist):
self.args = argslist
def parseArgs(self, rcbase=None):
"""Parses the command line arguments and all the relevant
resource-control (RC) files for this application. The usage_command
(generally argv[0]) will determine which the name of our rcfile,
unless overrided with the rcbase argument."""
# Save any existing options
args = self.getArgs()
# First pass to get rcfiles specified on the cmd line
self.setArgs(self.caller_args)
self.parseCommandLine(rcfile=1)
# Parse Resource Control files
self.setArgs([])
if not rcbase:
rcbase = self.usage_command
self.parseRC(rcbase)
for rc in self.rcForce:
self.parseRCFile(rc, rcbase)
# Command line options always win
self.setArgs(args + self.args + self.caller_args)
self.parseCommandLine()
def parseRC(self, rcbase, section=None):
rcfile = rcbase + 'rc'
if not section:
section = rcbase
# Where we look for resource-control files. First in
# the default 'etc' location, then HOME, finally in this dir.
# We use data from all three, such that later rc files take
# precedence.
dirList = [ os.path.join(os.sep,'opt', self.projectName, 'etc') ]
if 'HOME' in os.environ:
dirList.append(os.environ['HOME'])
dirList.append('.')
# Look for both hidden and visible rc files.
for dir in dirList:
self.parseRCFile(os.path.join(dir, '.' + rcfile), section)
self.parseRCFile(os.path.join(dir, rcfile), section)
def parseRCFile(self, filename, section):
if os.path.isfile(filename) and filename not in self.rcfileList:
self.rcfileList.append(filename)
file = open(filename, 'r')
parser = make_parser()
handler = self.rcfileHandler(self)
if section:
handler.setSection(section)
parser.setContentHandler(handler)
try:
parser.parse(file)
except SAXParseException as msg:
print (filename, "XML parse exception: ", msg)
file.close()
def parseCommandLine(self, rcfile=0):
"""Calls getopt to parse the command line flags. In
rcfile mode we just get --rcfile options."""
short = ''
for e in self.getopt.s:
if isinstance(e, tuple):
short = short + e[0]
else:
short = short + e
long = []
for e in self.getopt.l:
if isinstance(e, tuple):
long.append(e[0])
else:
long.append(e)
try:
opts, args = getopt.getopt(self.args, short, long)
except getopt.GetoptError as msg:
sys.stderr.write("error - %s\n" % msg)
self.usage()
sys.exit(1)
for c in opts:
if rcfile:
if c[0] != "--rcfile":
continue
self.parseArg(c)
if not rcfile:
self.args = args
def parseArg(self, c):
if c[0] in ('-h', '--help'):
self.help()
sys.exit(0)
elif c[0] == '--list-rcfiles':
print (self.rcfileList)
sys.exit(0)
elif c[0] == '--list-project-info':
print (self.projectInfo())
sys.exit(0)
elif c[0] == '--rcfile':
self.rcForce.append(c[1])
else:
return 0
return 1
def usage(self):
if 'COLUMNS' in os.environ:
cols = os.environ['COLUMNS']
else:
cols = 80
usagelist = [ 'Usage: ', self.usage_command, ' ' ]
# Build string of argument-free short options.
s = '[-'
for e in self.getopt.s:
if len(e) == 1:
s = s + e
s = s + ']'
if len(s) == 3:
s = ''
usagelist.append(s)
# Add the argument short options to the above string
for e in self.getopt.s:
if isinstance(e, tuple):
v = e[0]
h = e[1]
else:
v = e
h = 'arg'
if len(v) != 1:
usagelist.append(' [-' + v[:-1] + ' ' + h + ']')
# Add argument-free long options
for e in self.getopt.l:
if isinstance(e, tuple):
v = e[0]
else:
v = e
if v[len(v)-1] != '=':
usagelist.append(' [--' + v + ']')
# Add argument long options
for e in self.getopt.l:
if isinstance(e, tuple):
v = e[0]
h = e[1]
else:
v = e
h = 'arg'
if v[len(v)-1] == '=':
usagelist.append(' [--' + v[:-1] + ' ' + h + ']')
usagelist.append(self.usageTail())
# Print the usage, word wrapped to the correct screen size.
print (self.usage_name, '- version', self.usage_version)
l = 0
s = ''
for e in usagelist:
if l + len(e) <= cols:
s = s + e
l = l + len(e)
else:
print (s)
l = len(e)
s = e
if s:
print (s)
def help(self):
self.usage()
def usageTail(self):
return ''
def getArch(self):
return sunhpc.core.utils.getNativeArch()
class RCFileHandler(sunhpc.core.utils.ParseXML):
def __init__(self, application):
sunhpc.core.utils.ParseXML.__init__(self, application)
self.foundSection = 0
self.section = self.app.usage_command
def setSection(self, section):
self.section = section
def startElement(self, name, attrs):
#
# need to convert all the attributes to ascii strings.
# starting in python 2, the xml parser puts the attributes in
# unicode which causes problems with sunhpc apps classes, specifically
# those that append path names found in the attributes to the sys.path
#
newattrs = {}
for (aname, avalue) in attrs.items():
newattrs[aname] = str(attrs[aname])
if self.foundSection:
sunhpc.core.utils.ParseXML.startElement(self, name, newattrs)
elif name == self.section:
self.startElementSection(name, newattrs)
def endElement(self, name):
if self.foundSection and name == self.foundSection:
self.endElementSection(name)
if self.foundSection:
sunhpc.core.utils.ParseXML.endElement(self, name)
def getOptions(self):
return self.options
# <section parent="base">
def startElementSection(self, name, attrs):
parent = attrs.get('parent')
if parent:
self.app.parseRC(parent, parent)
self.foundSection = 1
def endElementSection(self, name, attrs):
self.foundSection = 0
# <usage>
def startElement_usage(self, name, attrs):
usageName = attrs.get('name')
usageVersion = attrs.get('version')
if usageName:
self.app.usage_name = usageName
if usageVersion:
self.app.usage_version = usageVersion
# <option>
def startElement_option(self, name, attrs):
argName = attrs.get('name')
# Will return None if value is not present.
argValue = attrs.get('value')
list = self.app.getArgs()
if len(argName) > 1:
flag = '--' + argName
# We differentiate between empty values and
# no value at all.
if argValue is not None:
list.append('%s=%s' % (flag, argValue))
else:
list.append(flag)
else:
flag = '-' + argName
if argValue:
list.append('%s %s' % (flag, argValue))
else:
list.append(flag)
self.app.setArgs(list)
# <project>
def startElement_project(self, name, attrs):
self.app.projectName = attrs.get('name')
self.app.projectVersionName = attrs.get('versionName')
self.app.projectVersionMajor = attrs.get('versionMajor')
self.app.projectVersionMinor = attrs.get('versionMinor')
self.app.projectVersionMicro = attrs.get('versionMicro')

View File

@@ -400,7 +400,7 @@ class DistributionBuilder(Builder):
# #
os.chdir(self.dist.getReleasePath()) os.chdir(self.dist.getReleasePath())
if self.calcmd5: if self.calcmd5:
cmd = '/usr/bin/md5sum `find -L . -type f | sed "s/^\.\///" | ' cmd = r'/usr/bin/md5sum `find -L . -type f | sed "s/^\.\///" | '
cmd += 'egrep -v "^build|^SRPMS|^force" | egrep -v "rpm$"` ' cmd += 'egrep -v "^build|^SRPMS|^force" | egrep -v "rpm$"` '
cmd += '> %s/packages.md5' % (productfilesdir) cmd += '> %s/packages.md5' % (productfilesdir)
else: else:

View File

@@ -162,9 +162,9 @@ class Tree:
os.path.islink(filepath): os.path.islink(filepath):
self.build(os.path.join(dir, f)) self.build(os.path.join(dir, f))
else: else:
if re.match('.*\.rpm$', f) != None: if re.match(r'.*\.rpm$', f) != None:
v.append(RPMFile(filepath)) v.append(RPMFile(filepath))
elif re.match('roll-.*\.iso$', f) != None: elif re.match(r'roll-.*\.iso$', f) != None:
v.append(RollFile(filepath)) v.append(RollFile(filepath))
else: else:
v.append(File(filepath)) v.append(File(filepath))
@@ -204,7 +204,7 @@ class RPMBaseFile(File):
def versionList(self, s): def versionList(self, s):
list = [] list = []
for e in re.split('\.+|_+', s): for e in re.split(r'\.+|_+', s):
l = [] l = []
num = '' num = ''
alpha = '' alpha = ''

View File

@@ -0,0 +1,371 @@
#
#coding:utf-8
#
#Author : QCSun
#Email : qcsun@sunhpc.com
#Times : 2023-04-14 05:21:02
#WebSite : https://www.sunhpc.com
import os
import re
import sys
import queue
import atexit
import textwrap
import readline
import itertools
from sunhpc.core.utils import SunhpcCliException
GLOBAL_OPTS = {}
def is_libedit():
return "libedit" in readline.__doc__
class BaseInterpreter(object):
history_file = os.path.expanduser("~/.history")
history_length = 100
global_help = ""
def __init__(self):
self.setup()
self.banner = ""
def preceding(self):
"""占位函数.在命令模块中覆盖此函数.可以预处理一些事情"""
pass
def setup(self):
""" Initialization of third-party libraries
Setting interpreter history.
Setting appropriate completer function.
:return:
"""
if not os.path.exists(self.history_file):
with open(self.history_file, "a+") as history:
if is_libedit():
history.write("_HiStOrY_V2_\n\n")
readline.read_history_file(self.history_file)
readline.set_history_length(self.history_length)
atexit.register(readline.write_history_file, self.history_file)
readline.parse_and_bind("set enable-keypad on")
readline.set_completer(self.complete)
readline.set_completer_delims(" \t\n;")
if is_libedit():
readline.parse_and_bind("bind ^I rl_complete")
else:
readline.parse_and_bind("tab: complete")
def parse_line(self, line):
""" Split line into command and argument.
:param line: line to parse
:return: (command, argument, named_arguments)
"""
kwargs = dict()
command, _, arg = line.strip().partition(" ")
args = arg.strip().split()
for word in args:
if '=' in word:
(key, value) = word.split('=', 1)
kwargs[key.lower()] = value
arg = arg.replace(word, '')
return command, ' '.join(arg.split()), kwargs
@property
def prompt(self):
""" Returns prompt string """
return ">>>"
def get_command_handler(self, command):
""" Parsing command and returning appropriate handler.
:param command: command
:return: command_handler
"""
try:
command_handler = getattr(self, "command_{}".format(command))
except AttributeError:
raise SunhpcCliException("Unknown command: '{}'".format(command))
return command_handler
def start(self):
""" Routersploit main entry point. Starting interpreter loop. """
print(self.banner)
self.preceding()
while True:
try:
command, args, kwargs = self.parse_line(input(self.prompt))
if not command:
continue
command_handler = self.get_command_handler(command)
command_handler(args, **kwargs)
except (EOFError, KeyboardInterrupt, SystemExit):
print("Sunhpc cli stopped")
break
def complete(self, text, state):
"""Return the next possible completion for 'text'.
If a command has not been entered, then complete against command list.
Otherwise try to call complete_<command> to get list of completions.
"""
if state == 0:
original_line = readline.get_line_buffer()
line = original_line.lstrip()
stripped = len(original_line) - len(line)
start_index = readline.get_begidx() - stripped
end_index = readline.get_endidx() - stripped
if start_index > 0:
cmd, args, _ = self.parse_line(line)
if cmd == "":
complete_function = self.default_completer
else:
try:
complete_function = getattr(self, "complete_" + cmd)
except AttributeError:
complete_function = self.default_completer
else:
complete_function = self.raw_command_completer
self.completion_matches = complete_function(text, line, start_index, end_index)
try:
return self.completion_matches[state]
except IndexError:
return None
def commands(self, *ignored):
""" Returns full list of interpreter commands.
:param ignored:
:return: full list of interpreter commands
"""
return [command.rsplit("_").pop() for command in dir(self) if command.startswith("command_")]
def raw_command_completer(self, text, line, start_index, end_index):
""" Complete command w/o any argument """
return [command for command in self.suggested_commands() if command.startswith(text)]
def default_completer(self, *ignored):
return []
def suggested_commands(self):
""" Entry point for intelligent tab completion.
Overwrite this method to suggest suitable commands.
:return: list of suitable commands
"""
return self.commands()
class SunhpcInterpreter(BaseInterpreter):
history_file = os.path.expanduser("~/.rsf_history")
global_help = """Global commands:
help Print this help menu
use <module> Select a module for usage
exec <shell command> <args> Execute a command in a shell
search <search term> Search for appropriate module
exit Exit RouterSploit"""
module_help = """Module commands:
run Run the selected module with the given options
back De-select the current module
set <option name> <option value> Set an option for the selected module
setg <option name> <option value> Set an option for all of the modules
unsetg <option name> Unset option that was set globally
show [info|options|devices] Print information, options, or target devices for a module
check Check if a given target is vulnerable to a selected module's exploit"""
def __init__(self, global_commands=[], sub_commands=[]):
super(SunhpcInterpreter, self).__init__()
self.current_keys = None
self.current_values = None
self.current_module = None
self.prompt_hostname = "sunhpc"
self.raw_prompt_template = None
self.module_prompt_template = None
self.base_global_commands = ['help', 'exit']
self.global_commands = ['show ', 'set ', 'check ']
if global_commands:
self.global_commands.extend(global_commands)
self.global_commands.extend(self.base_global_commands)
sorted(self.global_commands)
self.base_sub_commands = ['all', 'info', 'options']
self.sub_commands = ['wordlist', 'advanced']
if sub_commands:
self.sub_commands.extend(sub_commands)
self.sub_commands.extend(self.base_sub_commands)
sorted(self.sub_commands)
self.__parse_prompt()
self.banner = r"""
_____ _
/ ____| | |
======= | (___ _ _ _ __ | |__ _ __ ___
\ // \___ \| | | | '_ \| '_ \| '_ \ / __|
\ // ___ ) | |_| | | | | | | | |_) | (__
\// |_____/ \__,_|_| |_|_| |_| .__/ \___|
| |
Powered by HengPU Technology |_| By kylins
PlatName : HengPu High Performance Computing Platform
WeChat : xiubuzhe
Version : 1.0.0
Email : xiubuzhe@sina.com
GitPage : https://git.sunhpc.com - @kylins
BBSPage : https://bbs.sunhpc.com - @kylins
DocPage : https://doc.sunhpc.com - @kylins
Homepage : https://www.sunhpc.com - @kylins
Kelvin SunHPC Beta Program - https://www.sunhpc.com
"""
def __parse_prompt(self):
raw_prompt_default_template = "\001\033[4m\002{host}\001\033[0m\002 > "
raw_prompt_template = os.getenv("RSF_RAW_PROMPT", raw_prompt_default_template).replace('\\033', '\033')
self.raw_prompt_template = raw_prompt_template if '{host}' in raw_prompt_template else raw_prompt_default_template
module_prompt_default_template = "\001\033[4m\002{host}\001\033[0m\002 (\001\033[91m\002{module}\001\033[0m\002) > "
module_prompt_template = os.getenv("RSF_MODULE_PROMPT", module_prompt_default_template).replace('\\033', '\033')
self.module_prompt_template = module_prompt_template if all(map(lambda x: x in module_prompt_template, \
['{host}', "{module}"])) else module_prompt_default_template
@property
def prompt(self):
""" Returns prompt string based on current_module attribute.
Adding module prefix (module.name) if current_module attribute is set.
:return: prompt string with appropriate module prefix.
"""
if self.current_module:
try:
return self.module_prompt_template.format(host=self.prompt_hostname, module=self.module_metadata['name'])
except (AttributeError, KeyError):
return self.module_prompt_template.format(host=self.prompt_hostname, module="UnnamedModule")
else:
return self.raw_prompt_template.format(host=self.prompt_hostname)
def suggested_commands(self):
""" Entry point for intelligent tab completion.
Based on state of interpreter this method will return intelligent suggestions.
:return: list of most accurate command suggestions
"""
if self.current_keys and self.current_values:
# 将unsetg和current_keys列表组合后重新生成一个列表.(迭代器)
return sorted(itertools.chain(self.global_commands, ('unset ',)))
return self.global_commands
#
# show command functions
#
def command_show(self, *args, **kwargs):
sub_command = args[0]
try:
getattr(self, "_show_{}".format(sub_command))(*args, **kwargs)
except AttributeError:
# sunhpc debug
#raise
#self.msg("Unknown 'show' sub-command choices are:{}".format(self.sub_commands), 'w')
self.message('[-]', "Unknown 'show' sub-command choices are:", self.sub_commands)
def complete_show(self, text, *args, **kwargs):
if text:
return [command for command in self.sub_commands if command.startswith(text)]
else:
return self.sub_commands
def _show_all(self, *args, **kwargs):
self.__show_all()
#
# set command functions
#
def command_set(self, *args, **kwargs):
key, _, value = args[0].partition(" ")
if key in self.current_keys:
if kwargs.get('glob', False):
self.current_values[key] = value
self.dictOutput({key:value})
elif kwargs:
for k, v in kwargs.items():
self.current_values[k] = v
self.dictOutput(kwargs)
else:
print("You can't set option '{}'.Available options: {}".format(key, self.current_keys))
def complete_set(self, text, *args, **kwargs):
if text:
return ["=".join((keys, "")) for keys in self.current_keys if keys.startswith(text)]
else:
return self.current_keys
def command_unset(self, *args, **kwargs):
key, _, value = args[0].partition(' ')
try:
del self.current_values[key]
except KeyError:
self.msg("You can't unset option '{}'.Available options: {}".format(key, list(self.current_values.keys())), 'w')
else:
self.dictOutput({key: value})
def complete_unset(self, text, *args, **kwargs):
if text:
return [''.join((attr, "")) for attr in self.current_values.keys() if attr.startswith(text)]
else:
return list(self.current_values.keys())
def command_exit(self, *args, **kwargs):
raise EOFError

View File

@@ -34,10 +34,10 @@ class Security(object):
self.masters = [] self.masters = []
# A regex for our header search. # A regex for our header search.
pattern = "\n*(?P<comment>.*?)\$110id\$" pattern = r"\n*(?P<comment>.*?)\$110id\$"
self.header_pattern = re.compile(pattern) self.header_pattern = re.compile(pattern)
pattern = "<a href=.+>(?P<filename>.+)</a> +(?P<date>\d+.*) +(?P<size>\d+.*)" pattern = r"<a href=.+>(?P<filename>.+)</a> +(?P<date>\d+.*) +(?P<size>\d+.*)"
# Make the pattern matching engine case-insensitive. # Make the pattern matching engine case-insensitive.
self.dir_pattern = re.compile(pattern, re.I) self.dir_pattern = re.compile(pattern, re.I)

View File

@@ -29,6 +29,12 @@ class CommandError(SunhpcException):
something goes awry""" something goes awry"""
pass pass
class SunhpcCliException(Exception):
def __init__(self, msg: str = ""):
super(SunhpcCliException, self).__init__(msg)
class OptionValidationError(SunhpcCliException):
pass
class KickstartError(SunhpcException): class KickstartError(SunhpcException):
pass pass
@@ -191,7 +197,7 @@ def startSpinner(cmd):
w, r ,e = (p.stdin, p.stdout, p.stderr) w, r ,e = (p.stdin, p.stdout, p.stderr)
currLength = 0 currLength = 0
prevLength = 0 prevLength = 0
spinChars = '-\|/' spinChars = r'-\|/'
spinIndex = 0 spinIndex = 0
while 1: while 1:
line = e.readline() line = e.readline()

View File

@@ -2,9 +2,11 @@
import sunhpc import sunhpc
import sunhpc.core import sunhpc.core
import sunhpc.core.ip import sunhpc.core.ip
import sunhpc.core.app
import sunhpc.core.sql import sunhpc.core.sql
import sunhpc.core.dist import sunhpc.core.dist
import sunhpc.core.files import sunhpc.core.files
import sunhpc.core.build import sunhpc.core.build
import sunhpc.core.utils
import sunhpc.core.security import sunhpc.core.security
import sunhpc.core.partition import sunhpc.core.partition

46
sbin/check-port Executable file
View File

@@ -0,0 +1,46 @@
#!/opt/sunpy3/bin/python3
import os
import sys
import socket
import sunhpc.invoke
class App(sunhpc.core.app.Application):
def __init__(self, argv):
sunhpc.core.app.Application.__init__(self,argv)
self.usage_name = 'Check Port'
self.usage_version = '4.2'
self.node_name = 'localhost'
self.port_num = 5901
nodehelp = '(nodename default=%s)' % self.node_name
porthelp = '(port number default=%d)' % (self.port_num)
self.getopt.l.extend([ ('node=',nodehelp),('port=',porthelp) ])
self.getopt.s.extend([('n:',nodehelp),('p:',porthelp)])
def parseArg(self, c):
sunhpc.core.app.Application.parseArg(self,c)
key, val = c
if key in ('--port'):
self.port_num = int(val)
elif key in ('--node'):
self.node_name = val
def run(self):
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
s.connect((self.node_name,self.port_num))
except:
print ('Port(%s) is closed' % self.port_num)
sys.exit(1)
print ('Port(%s) is open' % self.port_num)
s.close()
sys.exit(0)
app = App(sys.argv)
app.parseArgs()
app.run()

100
share/pxeboot/default Normal file
View File

@@ -0,0 +1,100 @@
default vesamenu.c32
timeout 300
display boot.msg
menu clear
menu background splash.png
menu title CentOS and Rocky Linux Install
menu vshift 8
menu rows 18
menu margin 8
menu helpmsgrow 15
menu tabmsgrow 13
menu color border * #00000000 #00000000 none
menu color sel 0 #ffffffff #00000000 none
menu color title 0 #ff7ba3d0 #00000000 none
menu color tabmsg 0 #ff3a6496 #00000000 none
menu color unsel 0 #84b8ffff #00000000 none
menu color hotsel 0 #84b8ffff #00000000 none
menu color hotkey 0 #ffffffff #00000000 none
menu color help 0 #ffffffff #00000000 none
menu color scrollbar 0 #ffffffff #ff355594 none
menu color timeout 0 #ffffffff #00000000 none
menu color timeout_msg 0 #ffffffff #00000000 none
menu color cmdmark 0 #84b8ffff #00000000 none
menu color cmdline 0 #ffffffff #00000000 none
menu tabmsg Press Tab for full configuration options on menu items.
menu separator # insert an empty line
menu separator # insert an empty line
menu begin Install CentOS 7
menu title Install CentOS 7
label linux 7
menu label ^Auto Install CentOS 7 (Minimal)
kernel c7/vmlinuz
append initrd=c7/initrd.img inst.ks=http://ipaddress/ksfile/c7_min.conf quiet net.ifnames=0
label linux 7
menu label ^Auto Install CentOS 7 (^GUI)
kernel c7/vmlinuz
append initrd=c7/initrd.img inst.ks=http://ipaddress/ksfile/c7_gui.conf quiet net.ifnames=0
label linux 7
menu label ^Manual Install CentOS 7
kernel c7/vmlinuz
append initrd=c7/initrd.img inst.repo=http://ipaddress/redhat/c7 quiet net.ifnames=0
label linux 7
menu indent count 5
menu label ^Rescue CentOS 7 system
kernel c7/vmlinuz
append initrd=c7/initrd.img inst.repo=http://ipaddress/redhat/c7 rescue
menu separator # insert an empty line
label returntomain
menu label Return to ^main menu
menu exit
menu end
# Rockys options
menu begin Install Rocky 8
menu title Install Rocky 8
label linux 8
menu label ^Auto Install Rocky 8 (Minimal)
kernel r8/vmlinuz
append initrd=r8/initrd.img inst.ks=http://ipaddress/ksfile/r8_min.conf quiet net.ifnames=0
label linux 8
menu label ^Auto Install Rocky 8 (^GUI)
kernel r8/vmlinuz
append initrd=r8/initrd.img inst.ks=http://ipaddress/ksfile/r8_gui.conf quiet net.ifnames=0
label linux 8
menu label ^Manual Install Rocky 8
kernel r8/vmlinuz
append initrd=r8/initrd.img inst.repo=http://ipaddress/redhat/r8 quiet net.ifnames=0
label linux 8
menu indent count 5
menu label ^Rescue Rocky 8 system
kernel r8/vmlinuz
append initrd=r8/initrd.img inst.repo=http://ipaddress/redhat/r8 rescue
menu separator # insert an empty line
label returntomain
menu label Return to ^main menu
menu exit
menu end
menu separator # insert an empty line
label local
menu default
menu label Boot from ^local drive
localboot 0xffff
menu end

BIN
share/pxeboot/grubx64.efi Normal file

Binary file not shown.

View File

@@ -0,0 +1,49 @@
#version=RHEL8
# Use graphical install
install
keyboard 'us'
lang zh_CN
text
skipx
eula --agreed
firstboot --disable
selinux --disabled
timezone Asia/Shanghai
auth --useshadow --passalgo=sha512
url --url="http://ipaddress/redhat/c7"
#autopart --type=lvm
zerombr
bootloader --location=mbr
clearpart --all --initlabel
part /boot --fstype="ext4" --size=1024
part swap --fstype="swap" --size=4096
part / --fstype="xfs" --grow
reboot
rootpw --plaintext 123456
%post --interpreter=/usr/bin/bash
useradd admin
echo 123456 | passwd --stdin admin
sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
%end
%packages
@^infrastructure-server-environment
@base
@core
chrony
kexec-tools
%end
%addon com_redhat_kdump --disable --reserve-mb='auto'
%end
%anaconda
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
%end

View File

@@ -0,0 +1,50 @@
#version=RHEL8
# Use graphical install
install
keyboard 'us'
lang zh_CN
text
skipx
eula --agreed
firstboot --disable
selinux --disabled
timezone Asia/Shanghai
auth --useshadow --passalgo=sha512
url --url="http://ipaddress/redhat/c7"
#autopart --type=lvm
zerombr
bootloader --location=mbr
clearpart --all --initlabel
part /boot --fstype="ext4" --size=1024
part swap --fstype="swap" --size=4096
part / --fstype="xfs" --grow
reboot
rootpw --plaintext 123456
%post --interpreter=/usr/bin/bash
useradd admin
echo 123456 | passwd --stdin admin
sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
%end
%packages
@^infrastructure-server-environment
@base
@core
chrony
kexec-tools
%end
%addon com_redhat_kdump --disable --reserve-mb='auto'
%end
%anaconda
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
%end

View File

@@ -0,0 +1,51 @@
#version=RHEL8
# Use graphical install
graphical
%packages
@^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
%end
keyboard --xlayouts='us'
lang en_US.UTF-8
firstboot --enable
selinux --disabled
skipx
timezone Asia/Shanghai --isUtc --nontp
network --bootproto=dhcp --onboot=on --ipv6=auto
network --hostname=compute.local
clearpart --all --initlabel
#part /boot --fstype="ext4" --size=1024
#part swap --fstype="swap" --size=4096
#part / --fstype="xfs" --grow
autopart --type=lvm
url --url="http://172.16.2.1/redhat/r8"
#repo --name="AppStream" --baseurl=http://172.16.2.1/redhat/AppStream
#repo --name="BaseOS" --baseurl=http://172.16.2.1/redhat/BaseOS
rootpw --iscrypted $6$eT.sWNwV69wyvhaR$N5tY4rJn6Y2slOrwuejfUBq3MhC5SNe1gUfTSYmOACObwW4ckUK9fjkKwC9TgSPhwwlaGdbtn0EFg11TJmAbC1
user --name=admin --password=$6$0WN9CulSREVORA0S$FVWh6tkvdncbmSrsNPEb13GwxnGnEOKZliZLdL2IdY5E/fzLB8QmZAmgxyHh6ElSjObUCTbDEJ0l9.wRCRrsU. --iscrypted --gecos="admin"
%addon com_redhat_kdump --disable --reserve-mb='auto'
%end
%anaconda
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
%end

View File

@@ -0,0 +1,55 @@
#version=RHEL8
# Use graphical install
graphical
url --url="http://ipaddress/redhat/r8"
lang en_US.UTF-8
eula --agreed
keyboard --xlayouts='us'
firstboot --disable
selinux --disabled
timezone Asia/Shanghai --isUtc --nontp
skipx
zerombr
bootloader --location=mbr
clearpart --all --initlabel
part /boot --fstype="ext4" --size=1024
part swap --fstype="swap" --size=4096
part / --fstype="xfs" --grow
rootpw --plaintext 123456
reboot
%post --interpreter=/usr/bin/bash
useradd admin
echo 123456 | passwd --stdin admin
sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
%end
%packages
@^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
%end
%addon com_redhat_kdump --disable --reserve-mb='auto'
%end
%anaconda
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
%end

View File

@@ -0,0 +1,42 @@
#version=RHEL8
# Use graphical install
graphical
url --url="http://ipaddress/redhat/r8"
lang en_US.UTF-8
eula --agreed
keyboard --xlayouts='us'
firstboot --disable
selinux --disabled
timezone Asia/Shanghai --isUtc --nontp
skipx
zerombr
bootloader --location=mbr
clearpart --all --initlabel
part /boot --fstype="ext4" --size=1024
part swap --fstype="swap" --size=4096
part / --fstype="xfs" --grow
rootpw --plaintext 123456
reboot
%post --interpreter=/usr/bin/bash
useradd admin
echo 123456 | passwd --stdin admin
sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
%end
%packages
@^minimal-environment
%end
%addon com_redhat_kdump --disable --reserve-mb='auto'
%end
%anaconda
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
%end

BIN
share/pxeboot/ldlinux.c32 Normal file

Binary file not shown.

BIN
share/pxeboot/libcom32.c32 Normal file

Binary file not shown.

BIN
share/pxeboot/libutil.c32 Normal file

Binary file not shown.

BIN
share/pxeboot/menu.c32 Normal file

Binary file not shown.

BIN
share/pxeboot/pxelinux.0 Normal file

Binary file not shown.

BIN
share/pxeboot/shimx64.efi Normal file

Binary file not shown.

BIN
share/pxeboot/vesamenu.c32 Normal file

Binary file not shown.

0
var/nodes/database.xml Normal file
View File