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/bash

logger() {
    echo `date` $@ >>  $LOG_FILE
}

# 判断配置文件中组名是否存在
is_group_defined() {
    local group=$1
    local 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" ]; then
        return 0
    else
        return 1
    fi
}

# 判断配置文件中的组中是否包含指定成员
is_member_in_group() {
    local group=$1
    local member=$2
    local 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" ]; then
        return 0
    else
        return 1
    fi
}

# 在配置文件中添加新成员到组中
add_group_member() {
    local group=$1
    local member=$2
    local 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=$1
    local member=$2
    local 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" ; then
        return 0
    else
        return 1
    fi
}

# 在配置文件中创建新组并添加新成员
create_group() {
    local group=$1
    local member=$2
    local 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"; then
        echo -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=$1
    local 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"; then
        return 0
    else
        return 1
    fi
}

# 检查系统内组是否存在
group_exist() {
    local group=$1
    bugroup $group > /dev/null 2>>$LOG_FILE
    return $?
}

# 检查系统内组是否存在
group_missing() {
    local group=$1
    bugroup $group > /dev/null 2>>$LOG_FILE
    if [ $? -eq 0 ]; then
        return 1
    else
        return 0
    fi
}

# 检查系统内用户是否存在于指定组
member_exist() {
    local group=$1
    local member=$2
    bugroup $group 2>>$LOG_FILE| grep -w $member >/dev/null
    return $?
}

# 检查系统内用户是否存在于指定组
member_missing() {
    local group=$1
    local member=$2
    bugroup $group 2>>$LOG_FILE| grep -w $member >/dev/null
    if [ $? -eq 0 ]; then
        return 1
    else
        return 0
    fi
}

# 激活配置文件中的变更
activate_change() {
    echo -e "y\nn\n" | badmin reconfig  >> $LOG_FILE 2>&1
    return $?
}

run() {
    # 检查 LSF 环境变量是否已加载
    if [ ! -f "$LSF_PROFILE" ]; then
        logger [ERRO] "LSF_PROFILE not found: $LSF_PROFILE"
        exit 1
    fi

    # 检查用户文件是否存在
    if [ ! -f "$GROUP_FILE" ]; then
        logger [ERROR] "User file not found: $GROUP_FILE"
        exit 1
    fi

    # 加载 LSF 环境变量
    . $LSF_PROFILE

    groupfile="$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"; then
                if is_member_in_group "$group" "$member" "$groupfile"; then
                    member_exist "$group" "$member"
                    if [ $? -eq 0 ]; then
                        logger [INFO] $member already in group $group
                        exit 0
                    else
                        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 $ret
                    fi
                else
                    # 组名存在,但成员不存在,添加新成员
                    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 $ret
                fi
            else
                # 组名不存在,创建新组并添加新成员
                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 $ret
            fi
            ;;
        "rmmember")
            # 检查组名是否在指定范围内
            if is_group_defined "$group" "$groupfile"; then
                if is_member_in_group "$group" "$member" "$groupfile"; then
                    member_exist "$group" "$member"
                    if [ $? -eq 0 ]; then
                        rm_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 $ret
                    else
                        # 组名存在,但成员不存在
                        logger [INFO] "$member is not in $group"
                        exit 0
                    fi
                else
                    # 组名存在,但成员不存在
                    logger [WARN] "Not found $group"
                    exit 0
                fi
            else
                # 组名不存在
                logger [WARN] "Not found $group"
                exit 0
            fi
            ;;
        "rmgroup")
            if is_group_defined "$group" "$groupfile"; then
                rm_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 $ret
            elif 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 $ret
            else
                logger [WARN] "Not found $group"
                exit 0
            fi
            ;;
        *)
            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 $@

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/959612.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

js/ts数值计算精度丢失问题及解决方案

文章目录 概念及问题问题分析解决方案方案一方案二方案其它——用成熟的库 概念及问题 js中处理浮点数运算时会出现精度丢失。js中整数和浮点数都属于Number数据类型&#xff0c;所有的数字都是以64位浮点数形式存储&#xff0c;整数也是如此。所以打印x.00这样的浮点数的结果…

SSM框架探秘:Spring 整合 SpringMVC 框架

搭建和测试 SpringMVC 的开发环境&#xff1a; web.xml 元素顺序&#xff1a; 在 web.xml 中配置 DisPatcherServlet 前端控制器&#xff1a; <!-- 配置前端控制器 --> <servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>…

算法11(力扣496)-下一个更大元素I

1、问题 nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。 给你两个 没有重复元素 的数组 nums1 和 nums2 &#xff0c;下标从 0 开始计数&#xff0c;其中nums1 是 nums2 的子集。 对于每个 0 < i < nums1.length &#xf…

2024年博客之星主题创作|2024年蓝桥杯与数学建模年度总结与心得

引言 2024年&#xff0c;我在蓝桥杯编程竞赛和数学建模竞赛中投入了大量时间和精力&#xff0c;这两项活动不仅加深了我对算法、数据结构、数学建模方法的理解&#xff0c;还提升了我的解决实际问题的能力。从蓝桥杯的算法挑战到数学建模的复杂应用&#xff0c;我在这些竞赛中…

Spring FatJar写文件到RCE分析

背景 现在生产环境部署 spring boot 项目一般都是将其打包成一个 FatJar&#xff0c;即把所有依赖的第三方 jar 也打包进自身的 app.jar 中&#xff0c;最后以 java -jar app.jar 形式来运行整个项目。 运行时项目的 classpath 包括 app.jar 中的 BOOT-INF/classes 目录和 BO…

初阶数据结构:链表(二)

目录 一、前言 二、带头双向循环链表 1.带头双向循环链表的结构 &#xff08;1)什么是带头&#xff1f; (2)什么是双向呢&#xff1f; &#xff08;3&#xff09;那什么是循环呢&#xff1f; 2.带头双向循环链表的实现 &#xff08;1&#xff09;节点结构 &#xff08;2…

Java Web-Request与Response

在 Java Web 开发中&#xff0c;Request 和 Response 是两个非常重要的对象&#xff0c;用于在客户端和服务器之间进行请求和响应的处理&#xff0c;以下是详细介绍&#xff1a; Request&#xff08;请求对象&#xff09; Request继承体系 在 Java Web 开发中&#xff0c;通…

mysql 学习2 MYSQL数据模型,mysql内部可以创建多个数据库,一个数据库中有多个表;表是真正放数据的地方,关系型数据库 。

在第一章中安装 &#xff0c;启动mysql80 服务后&#xff0c;连接上了mysql&#xff0c;那么就要 使用 SQL语句来 操作mysql数据库了。那么在学习 SQL语言操作 mysql 数据库 之前&#xff0c;要对于 mysql数据模型有一个了解。 MYSQL数据模型 在下图中 客户端 将 SQL语言&…

微信小程序date picker的一些说明

微信小程序的picker是一个功能强大的组件&#xff0c;它可以是一个普通选择器&#xff0c;也可以是多项选择器&#xff0c;也可以是时间、日期、省市区选择器。 官方文档在这里 这里讲一下date picker的用法。 <view class"section"><view class"se…

【学习笔记】计算机网络(二)

第2章 物理层 文章目录 第2章 物理层2.1物理层的基本概念2.2 数据通信的基础知识2.2.1 数据通信系统的模型2.2.2 有关信道的几个基本概念2.2.3 信道的极限容量 2.3物理层下面的传输媒体2.3.1 导引型传输媒体2.3.2 非导引型传输媒体 2.4 信道复用技术2.4.1 频分复用、时分复用和…

总结8..

#include <stdio.h> // 定义结构体表示二叉树节点&#xff0c;包含左右子节点编号 struct node { int l; int r; } tree[100000]; // 全局变量记录二叉树最大深度&#xff0c;初始为0 int ans 0; // 深度优先搜索函数 // pos: 当前节点在数组中的位置&#xff0c…

多智能体中的理论与传统智能体理论有何异同?

多智能体系统与传统单智能体理论在多个方面存在异同&#xff0c;多智能体系统在理论上扩展了单智能体系统的研究范畴&#xff0c;强调智能体之间的交互和协作。随着人工智能、人机智能、人机环境系统智能的发展&#xff0c;多智能体系统在机器人群体、分布式计算、资源管理等领…

RKNN_C++版本-YOLOV5

1.背景 为了实现低延时&#xff0c;所以开始看看C版本的rknn的使用&#xff0c;确实有不足的地方&#xff0c;请指正&#xff08;代码借鉴了rk官方的仓库文件&#xff09;。 2.基本的操作流程 1.读取模型初始化 // 设置基本信息 // 在postprocess.h文件中定义&#xff0c;详见…

FlinkSql使用中rank/dense_rank函数报错空指针

问题描述 在flink1.16(甚至以前的版本)中&#xff0c;使用rank()或者dense_rank()进行排序时&#xff0c;某些场景会导致报错空指针NPE(NullPointerError) 报错内容如下 该报错没有行号/错误位置&#xff0c;无法排查 现状 目前已经确认为bug&#xff0c;根据github上的PR日…

csapp2.4节——浮点数

目录 二进制小数 十进制小数转二进制小数 IEEE浮点表示 规格化表示 非规格化表示 特殊值 舍入 浮点运算 二进制小数 类比十进制中的小数&#xff0c;可定义出二进制小数 例如1010.0101 小数点后的权重从-1开始递减。 十进制小数转二进制小数 整数部分使用辗转相除…

【2024年华为OD机试】 (A卷,200分)- 开放日活动、取出尽量少的球(JavaScriptJava PythonC/C++)

一、问题描述 题目描述 某部门开展Family Day开放日活动,其中有个从桶里取球的游戏,游戏规则如下: 有N个容量一样的小桶等距排开。每个小桶默认装了数量不等的小球,记录在数组 bucketBallNums 中。游戏开始时,要求所有桶的小球总数不能超过 SUM。如果小球总数超过 SUM,…

《安富莱嵌入式周报》第349期:VSCode正式支持Matlab调试,DIY录音室级麦克风,开源流体吊坠,物联网在军工领域的应用,Unicode字符压缩解压

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; 《安富莱嵌入式周报》第349期&#xff1a;VSCode正式支持Matlab调试&#xff0c;DIY录音室级麦克风…

nacos(基于docker最详细安装)

1、什么是Spring Cloud Spring Cloud是一系列框架的集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发&#xff0c;如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等&#xff0c;都可以用Spring Boot的开发风格做到一键启动和部署。…

李沐vscode配置+github管理+FFmpeg视频搬运+百度API添加翻译字幕

终端输入nvidia-smi查看cuda版本 我的是12.5&#xff0c;在网上没有找到12.5的torch&#xff0c;就安装12.1的。torch&#xff0c;torchvision&#xff0c;torchaudio版本以及python版本要对应 参考&#xff1a;https://blog.csdn.net/FengHanI/article/details/135116114 创…

Java Web-Tomcat Servlet

Web服务器-Tomcat Web服务器简介 Web 服务器是一种软件程序&#xff0c;它主要用于在网络上接收和处理客户端&#xff08;如浏览器&#xff09;发送的 HTTP 请求&#xff0c;并返回相应的网页内容或数据。以下是关于 Web 服务器的详细介绍&#xff1a; 功能 接收请求&#…