openlava/LSF 用户组管理脚本
背景
在openlava运维中经常需要自动化一些常规操作,比如增加用户组以及组成员、删除用户组成员、删除用户组等。而openlava的配置文件需要手动修改,然后再通过badmin reconfig激活配置。因此开发脚本将手工操作自动化就很有必要。
通过将脚本中的UserGroup替换为HostGroup,就可以对主机组进行操作。
此脚本也适用于 LSF 用户组管理;不过LSF支持通过bconf修改配置,不再需要badmin reconfig激活。
功能
下面的脚本就可以对openlava中的用户组进行操作:
* 增加用户组成员,如果组不存在则自动创建用户组;
* 删除用户组成员,如果组内已没有成员则自动删除用户组;
* 删除用户组
* 检查用户组是否包含成员;
参数
在使用之前需要设置以下参数:
LSF_PROFILE="/openlava/etc/openlava.sh"
GROUP_FILE="/openlava/etc/lsb.users"
LOG_FILE="/openlava/log/lavaug.log"
ADMIN="lsfadmin"
使用方法
1. 检查用户组是否包含成员
lavaug checkmember <group> <member>
返回码:0 包含 非0 不包含
2. 增加用户组成员
lavaug addmember <group> <member>
返回码:0 添加成功 非0 添加失败
3. 删除用户组成员
lavaug rmmember <group> <member>
返回码:0 删除成功 非0 删除失败
4. 删除用户组
lavaug rmgroup <group>
返回码:0 删除成功 非0 删除失败
注:脚本会将操作以及错误写入日志文件,方便审记和排查错误。
源代码
#!/bin/bashlogger() {echo `date` $@ >> $LOG_FILE
}# 判断配置文件中组名是否存在
is_group_defined() {local group=$1local file=$2# 使用 awk 查找在 "Begin UserGroup" 和 "End UserGroup" 之间的组名local group=$(awk -v group="$group" '/Begin UserGroup/,/End UserGroup/ { if ($1 == group) print $1 }' "$file")if [ -n "$group" ]; thenreturn 0elsereturn 1fi
}# 判断配置文件中的组中是否包含指定成员
is_member_in_group() {local group=$1local member=$2local file=$3# 使用 awk 查找在 "Begin UserGroup" 和 "End UserGroup" 之间的组名用用户名local result=$(awk -v group="$group" -v member="$member" '/Begin UserGroup/,/End UserGroup/ {if ($1 == group && index($0, member)) {print member}}' "$file")if [ -n "$result" ]; thenreturn 0elsereturn 1fi
}# 在配置文件中添加新成员到组中
add_group_member() {local group=$1local member=$2local file=$3# 创建临时文件local tmp_file=$(mktemp)# 使用 awk 处理文件,找到组名并添加新成员,其他行保持不变,输出到临时文件awk -v group="$group" -v member="$member" '/Begin UserGroup/,/End UserGroup/ {# 在组名后的括号内添加新成员,确保不重复添加if ($1 == group && !index($0, member)) {sub(/)/, " " member ")")}}{ print }' "$file" > "$tmp_file"# 替换原文件mv "$tmp_file" "$file"chown "$ADMIN":"$ADMIN" "$file"is_member_in_group "$group" "$member" "$file"return $?
}# 在配置文件中删除组成员, 成员列表为空时删除组
rm_group_member() {local group=$1local member=$2local file=$3# 创建临时文件local tmp_file=$(mktemp)# 使用 awk 处理文件,找到组名并删除成员,其他行保持不变,输出到临时文件awk -v group="$group" -v member="$member" '/Begin UserGroup/,/End UserGroup/ {# 在成员列表中删除指定成员, 若成员为空则删除组if ($1 == group && index($0, member)) {gsub(" *" member " *", " ")if ($2 == "(" && $3 == ")") {next}}}{ print }' "$file" > "$tmp_file"# 替换原文件mv "$tmp_file" "$file"chown "$ADMIN":"$ADMIN" "$file"if ! is_member_in_group "$group" "$member" "$file" ; thenreturn 0elsereturn 1fi
}# 在配置文件中创建新组并添加新成员
create_group() {local group=$1local member=$2local file=$3# 创建临时文件local tmp_file=$(mktemp) # 使用 awk 处理文件,在 "End UserGroup" 前添加新组,如果 "Begin UserGroup" 和 "End UserGroup" 存在awk -v group="$group" -v member="$member" 'BEGIN { group_added = 0 }/Begin UserGroup/ {in_group = 1}/End UserGroup/ {if (!group_added) {print group " (" member ")"group_added = 1}in_group = 0}in_group { print }!in_group { print }' "$file" > "$tmp_file"# 如果没有找到 "Begin UserGroup" 和 "End UserGroup",则直接在文件末尾添加if ! is_group_defined "$group" "$tmp_file"; thenecho -e "\nBegin UserGroup\n"$group" ("$member")\nEnd UserGroup" >> "$tmp_file"fi# 替换原文件mv "$tmp_file" "$file"chown "$ADMIN":"$ADMIN" "$file"is_member_in_group "$group" "$member" "$file"return $?
}# 在配置文件中删除组
rm_group() {local group=$1local file=$2# 创建临时文件local tmp_file=$(mktemp)# 使用 awk 处理文件,找到组名并添加新成员,其他行保持不变,输出到临时文件awk -v group="$group" '/Begin UserGroup/,/End UserGroup/ {# 在组名后的列表中删除成员if ($1 == group) {next}}{ print }' "$file" > "$tmp_file"# 替换原文件mv "$tmp_file" "$file"chown "$ADMIN":"$ADMIN" "$file"if ! is_group_defined "$group" "$file"; thenreturn 0elsereturn 1fi
}# 检查系统内组是否存在
group_exist() {local group=$1bugroup $group > /dev/null 2>>$LOG_FILEreturn $?
}# 检查系统内组是否存在
group_missing() {local group=$1bugroup $group > /dev/null 2>>$LOG_FILEif [ $? -eq 0 ]; thenreturn 1elsereturn 0fi
}# 检查系统内用户是否存在于指定组
member_exist() {local group=$1local member=$2bugroup $group 2>>$LOG_FILE| grep -w $member >/dev/nullreturn $?
}# 检查系统内用户是否存在于指定组
member_missing() {local group=$1local member=$2bugroup $group 2>>$LOG_FILE| grep -w $member >/dev/nullif [ $? -eq 0 ]; thenreturn 1elsereturn 0fi
}# 激活配置文件中的变更
activate_change() {echo -e "y\nn\n" | badmin reconfig >> $LOG_FILE 2>&1return $?
}run() {# 检查 LSF 环境变量是否已加载if [ ! -f "$LSF_PROFILE" ]; thenlogger [ERRO] "LSF_PROFILE not found: $LSF_PROFILE"exit 1fi# 检查用户文件是否存在if [ ! -f "$GROUP_FILE" ]; thenlogger [ERROR] "User file not found: $GROUP_FILE"exit 1fi# 加载 LSF 环境变量. $LSF_PROFILEgroupfile="$GROUP_FILE"action="$1"group="$2"member="$3"logger [INFO] request: $@case "$action" in"checkmember")member_exist "$group" "$member"ret=$?[ $ret -eq 0 ] && logger [INFO] "Found $member in $group" || logger [WARN] "Not found $member in $group"exit $ret;;"addmember")# 检查组名是否在指定范围内if is_group_defined "$group" "$groupfile"; thenif is_member_in_group "$group" "$member" "$groupfile"; thenmember_exist "$group" "$member"if [ $? -eq 0 ]; thenlogger [INFO] $member already in group $groupexit 0elseactivate_change && sleep 5 && member_exist "$group" "$member"ret=$?[ $ret -eq 0 ] && logger [INFO] "Add $member into $group succeeded" || logger [WARN] "Add $member into $group failed"exit $retfielse# 组名存在,但成员不存在,添加新成员add_group_member "$group" "$member" "$groupfile" && activate_change && sleep 5 && member_exist "$group" "$member"ret=$?[ $ret -eq 0 ] && logger [INFO] "Add $member into $group succeeded" || logger [WARN] "Add $member into $group failed"exit $retfielse# 组名不存在,创建新组并添加新成员create_group "$group" "$member" "$groupfile" && activate_change && sleep 5 && member_exist "$group" "$member"ret=$?[ $ret -eq 0 ] && logger [INFO] "Add $member into $group succeeded" || logger [WARN] "Add $member into $group failed"exit $retfi;;"rmmember")# 检查组名是否在指定范围内if is_group_defined "$group" "$groupfile"; thenif is_member_in_group "$group" "$member" "$groupfile"; thenmember_exist "$group" "$member"if [ $? -eq 0 ]; thenrm_group_member "$group" "$member" "$groupfile" && activate_change && sleep 5 && member_missing "$group" "$member"ret=$?[ $ret -eq 0 ] && logger [INFO] "Remove $member from $group succeeded" || logger [WARN] "Remove $member from $group failed"exit $retelse# 组名存在,但成员不存在logger [INFO] "$member is not in $group"exit 0fielse# 组名存在,但成员不存在logger [WARN] "Not found $group"exit 0fielse# 组名不存在logger [WARN] "Not found $group"exit 0fi;;"rmgroup")if is_group_defined "$group" "$groupfile"; thenrm_group "$group" "$groupfile" && activate_change && sleep 5 && group_missing "$group"ret=$?[ $ret -eq 0 ] && logger [INFO] "Remove $group succeeded" || logger [WARN] "Remove $group failed"exit $retelif group_exist "$group"; then# 文件中没有组名,但系统中还有activate_change && sleep 5 && group_missing "$group"ret=$?[ $ret -eq 0 ] && logger [INFO] "Remove $group succeeded" || logger [WARN] "Remove $group failed"exit $retelselogger [WARN] "Not found $group"exit 0fi;;*)logger [WARN] "Invalid action: $action"exit 1;;esac
}##########################
#### Main Entry Start ####
########################### Please modify the LSF_PROFILE, GROUP_FILE, ADMIN accordingly
LSF_PROFILE="/openlava/etc/openlava.sh"
GROUP_FILE="/openlava/etc/lsb.users"
LOG_FILE="/openlava/log/lavaug.log"
ADMIN="lsfadmin"run $@
相关文章:

openlava/LSF 用户组管理脚本
背景 在openlava运维中经常需要自动化一些常规操作,比如增加用户组以及组成员、删除用户组成员、删除用户组等。而openlava的配置文件需要手动修改,然后再通过badmin reconfig激活配置。因此开发脚本将手工操作自动化就很有必要。 通过将脚本中的User…...

数据结构与算法之贪心: LeetCode 649. Dota2 参议院 (Ts版)
Dota2 参议院 https://leetcode.cn/problems/dota2-senate/ 描述 Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇) Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。…...

西藏酥油茶:高原上的醇香温暖
西藏酥油茶:高原上的醇香温暖 在西藏高原,有一种饮品,它不仅滋养了一代又一代的藏民,还承载着丰富的文化与历史,它就是西藏酥油茶。酥油茶,藏语称为“恰苏玛”,意为搅动的茶,是藏族人民日常生活中不可或缺的一部分,更是待客、祭祀等活动中的重要礼仪物品。 历史与文化渊源 酥…...

【模型】RNN模型详解
1. 模型架构 RNN(Recurrent Neural Network)是一种具有循环结构的神经网络,它能够处理序列数据。与传统的前馈神经网络不同,RNN通过将当前时刻的输出与前一时刻的状态(或隐藏层)作为输入传递到下一个时刻&…...

C++----STL(list)
介绍 list的数据结果是一个带头双向链表。 使用 有了前面string、vector的基础,后续关于list使用的讲解主要提及与string和vector的不同之处。 使用文档:cplusplus.com/reference/list/list/?kwlist 迭代器问题 insert以后迭代器不失效 #include…...

数据结构——AVL树的实现
Hello,大家好,这一篇博客我们来讲解一下数据结构中的AVL树这一部分的内容,AVL树属于是数据结构的一部分,顾名思义,AVL树是一棵特殊的搜索二叉树,我们接下来要讲的这篇博客是建立在了解搜索二叉树这个知识点…...

知识图谱在个性化推荐中的应用:赋能智能化未来
目录 前言1. 知识图谱的基本概念2. 个性化推荐的挑战与知识图谱的优势2.1 个性化推荐的主要挑战2.2 知识图谱在个性化推荐中的优势 3. 知识图谱赋能推荐系统的具体实现3.1 数据增强与关系建模3.2 嵌入技术的应用3.3 图神经网络(GNN)的应用3.4 多模态数据…...

C语言自定义数据类型详解(一)——结构体类型(上)
什么是自定义数据类型呢?顾名思义,就是我们用户自己定义和设置的类型。 在C语言中,我们的自定义数据类型一共有三种,它们分别是:结构体(struct),枚举(enum),联合(union)。接下来,我…...

使用 Tailwind CSS + PostCSS 实现响应式和可定制化的前端设计
随着前端开发框架和工具的不断更新,设计和样式的管理已经成为前端开发中的一项核心任务。传统的 CSS 编写方式往往让样式的复用和可维护性变得困难,而 Tailwind CSS 和 PostCSS 作为当下流行的工具,提供了强大的功能来简化开发过程࿰…...

巧用多目标识别能力,帮助应用实现智能化图片解析
为了提升用户体验,各类应用正通过融合人工智能技术,致力于提供更智能、更高效的服务。应用不仅能通过文字和语音的方式与用户互动,还能深入分析图片内容,为用户提供精准的解决方案。 在解析图片之前,应用首先需要准确识…...

算法中的移动窗帘——C++滑动窗口算法详解
1. 滑动窗口简介 滑动窗口是一种在算法中常用的技巧,主要用来处理具有连续性的子数组或子序列问题。通过滑动窗口,可以在一维数组或字符串上维护一个固定或可变长度的窗口,逐步移动窗口,避免重复计算,从而提升效率。常…...

AcWing 3585:三角形的边 ← sort() 函数
【题目来源】 给定三个已知长度的边,确定是否能够构成一个三角形,这是一个简单的几何问题。 我们都知道,这要求两边之和大于第三边。 实际上,并不需要检验所有三种可能,只需要计算最短的两个边长之和是否大于最大那个就…...

阿里云-银行核心系统转型之业务建模与技术建模
业务领域建模包括业务建模和技术建模,整体建模流程图如下: 业务建模包括业务流程建模和业务对象建模 业务流程建模:通过对业务流程现状分析,结合目标核心系统建设能力要求,参考行业建 模成果,形成结构化的…...

MySQL核心知识:春招面试数据库要点
在前文中,我们深入剖析了MyBatis这一优秀的持久层框架,了解了它如何实现SQL语句与Java对象的映射,以及其缓存机制等重要内容。而作为数据持久化的核心支撑,数据库的相关知识在Java开发中同样至关重要。MySQL作为最流行的开源关系型…...

Hive之加载csv格式数据到hive
场景: 今天接了一个需求,将测试环境的hive数据导入到正式环境中。但是不需要整个流程的迁移,只需要迁移ads表 解决方案: 拿到这个需求首先想到两个方案: 1、将数据通过insert into语句导出,然后运行脚本 …...

Java web与Java中的Servlet
一。前言 Java语言大多用于开发web系统的后端,也就是我们是的B/S架构。通过浏览器一个URL去访问系统的后端资源和逻辑。 当我在代码里看到这个类HttpServletRequest 时 让我想到了Servlet,Servlet看上去多么像是Java的一个普通类,但是它确实…...

kafka常用目录文件解析
文章目录 1、消息日志文件(.log)2、消费者偏移量文件(__consumer_offsets)3、偏移量索引文件(.index)4、时间索引文件( .timeindex)5、检查点引文件( .checkpoint&#x…...

RV1126+FFMPEG推流项目源码
源码在我的gitee上面,感兴趣的可以自行了解 nullhttps://gitee.com/x-lan/rv126-ffmpeg-streaming-projecthttps://gitee.com/x-lan/rv126-ffmpeg-streaming-project...

ANSYS SimAI
ANSYS SimAI 是 ANSYS 公司推出的一款基于人工智能(AI)的仿真解决方案,旨在通过机器学习技术加速仿真流程,降低计算资源需求,并为用户提供更高效的工程决策支持。其核心目标是简化复杂仿真过程,帮助工程师快…...

hedfs和hive数据迁移后校验脚本
先谈论校验方法,本人腾讯云大数据工程师。 1、hdfs的校验 这个通常就是distcp校验,hdfs通过distcp迁移到另一个集群,怎么校验你的对不对。 有人会说,默认会有校验CRC校验。我们关闭了,为什么关闭?全量迁…...

蓝桥杯单片机(八)定时器的基本原理与应用
模块训练: 当有长定时情况时,也就是定时长度超过65.5ms时,采用多次定时累加 一、定时器介绍 1.单片机的定时/计数器 2.定时器工作原理 3.定时器相关寄存器 二、定时器使用程序设计 1.程序设计思路 与写中断函数一样,先写一个初…...

刷题总结 回溯算法
为了方便复习并且在把算法忘掉的时候能尽量快速的捡起来 刷完回溯算法这里需要做个总结 回溯算法的适用范围 回溯算法是深度优先搜索(DFS)的一种特定应用,在DFS的基础上引入了约束检查和回退机制。 相比于普通的DFS,回溯法的优…...

C++ 静态变量static的使用方法
static概述: static关键字有三种使用方式,其中前两种只指在C语言中使用,第三种在C中使用。 静态局部变量(C) 静态全局变量/函数(C) 静态数据成员/成员函数(C) 静态局部变量 静态局部变量&…...

Langchain+文心一言调用
import osfrom langchain_community.llms import QianfanLLMEndpointos.environ["QIANFAN_AK"] "" os.environ["QIANFAN_SK"] ""llm_wenxin QianfanLLMEndpoint()res llm_wenxin.invoke("中国国庆日是哪一天?") print(…...

20250124 Flink中 窗口开始时间和結束時間
增量聚合的 ProcessWindowFunction # ProcessWindowFunction 可以与 ReduceFunction 或 AggregateFunction 搭配使用, 使其能够在数据到达窗口的时候进行增量聚合。当窗口关闭时,ProcessWindowFunction 将会得到聚合的结果。 这样它就可以增量聚合窗口的…...

Android Studio安装配置
一、注意事项 想做安卓app和开发板通信,踩了大坑,Android 开发不是下载了就能直接开发的,对于新手需要注意的如下: 1、Android Studio版本,根据自己的Android Studio版本对应决定了你所兼容的AGP(Android…...

设计模式Python版 单例模式
文章目录 前言一、单例模式二、单例模式实现方式三、单例模式示例四、单例模式在Django框架的应用 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模…...

7-Zip高危漏洞CVE-2025-0411:解析与修复
7-Zip高危漏洞CVE-2025-0411:解析与修复 免责声明 本系列工具仅供安全专业人员进行已授权环境使用,此工具所提供的功能只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利…...

python实现http文件服务器访问下载
//1.py import http.server import socketserver import os import threading import sys# 获取当前脚本所在的目录 DIRECTORY os.path.dirname(os.path.abspath(__file__))# 设置服务器的端口 PORT 8000# 自定义Handler,将根目录设置为脚本所在目录 class MyHTT…...

《一文讲透》第4期:KWDB 数据库运维(6)—— 容灾与备份
一、KWDB 容灾 WAL 概述 KWDB 采用预写式日志(Write-Ahead Logging,WAL),记录每个时序表的模式变更和数据变更,以实现时序数据库的数据灾难恢复、时序数据的一致性和原子性。 KWDB 默认会将保存在 WAL 日志缓存中的…...