11 Commits
v1.0.0 ... main

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 syslog
import shutil
import readline
import sunhpc.invoke
if sys.getdefaultencoding() != 'utf-8':
reload(sys)
sys.setdefaultencoding('utf-8')
def ttySize():
try:
(width, heigh) = shutil.get_terminal_size()
except:
width = 80
return width
os.environ['COLUMNS'] = str(ttySize())
os.environ['COLUMNS'] = str(sunhpc.commands.get_help_width())
syslog.openlog('SunhpcCMD', syslog.LOG_PID, syslog.LOG_LOCAL0)
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 struct
import sqlite3
import termios
import argparse
import textwrap
import datetime
@@ -38,10 +37,8 @@ DEFAULT_HELP_WIDTH = 8
def get_help_width():
try:
data = fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, '1234')
columns = int(struct.unpack('hh', data)[1])
(columns, heigh) = shutil.get_terminal_size()
except (IOError, ValueError) as e:
print ("terminal size detection failed, using default width.")
return DEFAULT_HELP_WIDTH
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 %s" % (msg))
def message(self, msg, tag='[+]', end=''):
def message(self, tag='[+]', msg=' ', end=' '):
header = '\033[92m%s\033[0m' % tag
ender = '\033[95m%s\033[0m' % end
msger = '\033[31m%s\033[0m' % msg
result = '%s %s %s' % (header, msger, ender)
return result
print (result)
def abort(self, msg):
@@ -773,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)
@@ -785,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() ]
@@ -856,7 +868,7 @@ class Command(object):
w, r ,e = (p.stdin, p.stdout, p.stderr)
currLength = 0
prevLength = 0
spinChars = '-\|/'
spinChars = r'-\|/'
spinIndex = 0
while 1:
line = e.readline().decode()
@@ -977,17 +989,17 @@ class Command(object):
def getText(self):
return self.text
def dictOutput(self, strDict, sep='\t'):
def dictOutput(self, strDict, sep=' '):
maxlen = max(map(len, strDict.keys()))
for k in strDict:
strings = str(strDict[k])
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']:
value = '|\033[1;31m %s \033[0m' % strings.upper()
value = '\033[1;31m %s \033[0m' % strings.upper()
else:
value = '| %s' % strings
print ('\t\033[1;95m%s\033[0m %s \033[1;96m%s\033[0m' % (k.ljust(maxlen), sep, value))
value = '%s' % strings
print ('\t\033[1;95m%s\033[0m %s = \033[1;96m%s\033[0m' % (k.ljust(maxlen), sep, value))
def beginFmtOutput(self, header=[]):
self.fmtOutput = prettytable.PrettyTable(header)
@@ -1255,8 +1267,22 @@ class Command(object):
o.runWrapper(n, args)
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):
# 删除所有空值和None.
args = self.remove_empty_values(args)
username = pwd.getpwuid(os.geteuid())[0]
if args:
command = '%s %s' % (name, ' '.join(args))
@@ -1269,7 +1295,7 @@ class Command(object):
pdict = {}
plist = []
nparams = 0
flagpattern=re.compile("^[a-zA-z0-9\-_+]+=")
flagpattern=re.compile(r"^[a-zA-z0-9\-_+]+=")
for arg in args:
tokens = arg.split()
if tokens[0] == 'select':
@@ -1543,7 +1569,7 @@ class DocStringHandler(
s += '*[%s]*' % name
else:
s += '*{%s}*' % name
txt = txt.replace('*', '\*')
txt = txt.replace('*', '\\*')
s += '\n%s\n' % txt.replace('\t', ' ')
if self.section['param']:
s += '\n**Parameters:**\n\n'
@@ -1553,12 +1579,12 @@ class DocStringHandler(
s += '*[%s=%s]*' % (name, type)
else:
s += '*{%s=%s}*' % (name, type)
txt = txt.replace('*', '\*')
txt = txt.replace('*', '\\*')
s += '\n%s\n' % txt.replace('\t', ' ')
if self.section['example']:
s += '\n**Examples:**\n'
for (cmd, txt) in self.section['example']:
txt = txt.replace('*', '\*')
txt = txt.replace("*", "\\*")
s += '%s::\n\n' % txt.replace('\t',' ')
s += ' %s sunhpc %s\n' % (prompt, cmd)
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

@@ -133,7 +133,7 @@ class Command(sunhpc.commands.create.command):
mirrors = distro.getMirrors()
fullmirror = mirrors[0].getRollsPath()
# 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):
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):
(subdir, cols) = self.fillParams([('subdir', ), ('cols', 80) ], params)
if subdir:
filepath = os.path.join(sunhpc.commands.__path__[0], subdir)
modpath = 'sunhpc.commands.%s' % '.'.join(subdir.split(os.sep))

View File

@@ -12,7 +12,10 @@ class RollHandler(object):
self.cmd = cmd
self.clean = clean
self.mntdir = mnt
self.repodirs = ''
self.rinfo = None
self.isoname = 'unknown'
self.foreign = False
def is_mounted(self):
cmd = 'mount |grep %s' % self.mntdir
@@ -22,12 +25,13 @@ class RollHandler(object):
def mount_iso(self, iso):
subprocess.run('mount -r %s %s' % (iso, self.mntdir), shell=True, check=True)
self.isoname = iso
def umount_iso(self):
subprocess.run('umount %s' % self.mntdir, shell=True)
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)
try:
roll = sunhpc.core.files.RollInfoFile(ret['o'].strip())
@@ -36,7 +40,25 @@ class RollHandler(object):
pass
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):
self.read_iso()
@@ -47,11 +69,20 @@ class RollHandler(object):
def copy_roll(self):
# self.rinfo是经过file.RollInfoFile处理过的,返回相应的类对象.
if self.foreign:
roll_name = self.rinfo.name
roll_vers = self.rinfo.version
roll_arch = self.rinfo.arch
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存放位置
cmd = '/opt/sunhpc/bin/sunhpc report distro'
@@ -59,9 +90,15 @@ class RollHandler(object):
distro = line[:-1]
# /export/sunhpc/install/rolls
if self.foreign:
rolls_dir = '%s/repos' % (distro)
else:
rolls_dir = '%s/rolls' % (distro)
# /export/sunhpc/install/rolls/kernel......
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:
@@ -75,7 +112,7 @@ class RollHandler(object):
os.makedirs(specific_roll_dir)
cwd = os.getcwd()
os.chdir(os.path.join(self.mntdir, roll_name))
os.chdir(roll_path)
# 计算一下大小
cmd = 'du -sh %s' % self.mntdir
@@ -104,7 +141,7 @@ class RollHandler(object):
os.chdir(os.path.join(self.mntdir, roll_name))
# 修改所有目录权限,确保所有人能够访问,例如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信息到数据库,如果存在则放弃插入.
rows = self.cmd.db.search('select * from rolls where' \
@@ -122,6 +159,7 @@ class RollHandler(object):
# 如果是引导roll,需要使用软件Kylins create distro重新部署.
# 重新创建images,stage2,和相关连接相关任务.
self.cmd.msg('Copy the %s finished.' % roll_name)
self.repodirs = roll_dir
def clean_dirs(self, dirs):
for root, dirs, files in os.walk(dirs, topdown=False):
@@ -202,6 +240,9 @@ class Command(command):
roll_handler.copy_iso()
roll_handler.umount_iso()
if roll_handler.foreign:
sys.exit(0)
if pxesrv:
self.configSRV(q)
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.
#
[appstream]
[baseos]
name=Rocky Linux $releasever - BaseOS
%s
gpgcheck=1
@@ -131,7 +131,7 @@ class Command(sunhpc.commands.report.command):
#
# Generated by sunhpc report yumrepos commands.
#
[appstream]
[rockyextras]
name=Rocky Linux $releasever - Extras
%s
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'
suffname = 'tar.gz'
dirsname = os.path.join(source, 'hpcsoft', 'AutoDock')
try:
verslist = self.getVersions(key=softname, suffix=suffname, dirs=dirsname)
except FileNotFoundError as e:
self.msg(str(e), 'a')
if len(args):
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())
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 += '> %s/packages.md5' % (productfilesdir)
else:

View File

@@ -162,9 +162,9 @@ class Tree:
os.path.islink(filepath):
self.build(os.path.join(dir, f))
else:
if re.match('.*\.rpm$', f) != None:
if re.match(r'.*\.rpm$', f) != None:
v.append(RPMFile(filepath))
elif re.match('roll-.*\.iso$', f) != None:
elif re.match(r'roll-.*\.iso$', f) != None:
v.append(RollFile(filepath))
else:
v.append(File(filepath))
@@ -204,7 +204,7 @@ class RPMBaseFile(File):
def versionList(self, s):
list = []
for e in re.split('\.+|_+', s):
for e in re.split(r'\.+|_+', s):
l = []
num = ''
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 = []
# A regex for our header search.
pattern = "\n*(?P<comment>.*?)\$110id\$"
pattern = r"\n*(?P<comment>.*?)\$110id\$"
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.
self.dir_pattern = re.compile(pattern, re.I)

View File

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

View File

@@ -2,9 +2,11 @@
import sunhpc
import sunhpc.core
import sunhpc.core.ip
import sunhpc.core.app
import sunhpc.core.sql
import sunhpc.core.dist
import sunhpc.core.files
import sunhpc.core.build
import sunhpc.core.utils
import sunhpc.core.security
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