#!/bin/bash

# @firewall_config
# If ENVIRONMNET VARIABLE FIREWALLD configed with `on`  then open port in default zone.
# If ENVIRONMENT VARIABLE FIREWALLD configed with `off` then disable firewalld.service.
# example ports:
# 2377/tcp 7946/tcp 7946/udp 4789/tcp 4789/udp 80/tcp 443/tcp 9000/tcp 5001/tcp 6789/tcp 6800-7300/tcp 7480/tcp 8080/tcp 7000/tcp
function firewall_config() {
    case $FIREWALLD in
    "on")
        ports=(2377/tcp 7946/tcp 7946/udp 4789/tcp 4789/udp 80/tcp 443/tcp 9000/tcp 5001/tcp 6789/tcp 6800-7300/tcp 7480/tcp 8080/tcp 7000/tcp)
        for _p in $ports; do
            firewall-cmd --permanent --add-port=$_p
        done
        firewall-cmd --reload
        ;;
    "off")
        systemctl stop firewalld
        systemctl disable firewalld
        ;;
    *)
        echo "Invalid value. Please set it on or off"
        exit 10001
        ;;
    esac
}

# @system_kernel_paramater_conifg
# Config system kernel paramaters
# examples:
# 内核参数说明参考 kernel version: 3.10 , 更高版本内核下参数表现可能不一致
# vm.dirty_writeback_centisecs 表示内核刷新脏页到磁盘的时间间隔,默认值500, 1/100s 周期计算为 vm.dirty_writeback_centisecs/100 如果设置为0,则禁用回写
# vm.dirty_background_ratio 表示在触发回写之后允许保留的脏页数据百分比或者说回写进程只会清理超出background_ratio%的数据 默认值10
# vm.dirty_expire_centisecs 内存中脏页数据的时间超过此间隔将在下次刷新线程唤醒时被写出到磁盘,默认值3000,单位 1/100s 周期计算为 vm.dirty_expire_centisecs/100
# vm.dirty_ratio 当数据超过dirty_ratio是写入会被阻塞,该值以系统总内存为参照, 脏页数据大小/总内存 > dirty_ratio时写入操作会被阻塞,默认值30,单位%
# vm.vfs_cache_pressure 用于控制内核回收缓存目录和inode对象的内存 默认值100
# fs.inotify.max_user_watches 设置inotifywait或inotifywatch命令可以监视的文件数量,默认值1048576
# fs.file-max 限制内核打开文件数量,默认为 以kb为单位的总内存的10%
# vm.max_map_count 单个进程可以有多少个内存区域，默认值65536
# vm.min_free_kbytes 代表系统所保留空闲内存的最低限，默认最小为128K,最大64M
# net.core.somaxconn 表示socket监听队列上限 默认128
# vm.swappiness 物理机内存剩余多少(%)可用时使用swap,默认30

# fs.inotify.max_user_watches=262144
# vm.max_map_count=262144
# vm.min_free_kbytes=1024000
# net.core.somaxconn=2048
# vm.swappiness=0
# net.ipv4.ip_local_port_range=1024 65300
function system_kernel_paramater_config() {
    declare -a system_paramaters=("fs.inotify.max_user_watches=262144" "vm.max_map_count=262144" "vm.min_free_kbytes=1024000" "net.core.somaxconn=2048" "vm.swappiness=0")
    for item in ${system_paramaters[@]}; do
        local key=$(echo $item | awk 'BEGIN{FS="="} {print $1}')
        if ! grep $key /etc/sysctl.conf; then
            eval echo "$item" >>/etc/sysctl.conf
        fi
    done
    if ! grep ip_local_port_range /etc/sysctl.conf; then
        echo "net.ipv4.ip_local_port_range=1024 65300" >>/etc/sysctl.conf
    fi
    sysctl -p
}

# @is_system_mini
# Require RH 7 serise, centos 7.8+ system and minimal installtion.
# IF NOT EXIT INSTALL PROGRESS.
function is_system_mini() {
    install_cfg="/root/anaconda-ks.cfg"
    if ! cat $install_cfg | sed -n '/%packages/,/^$/ p;/^repo/p' | grep -i minimal &>/dev/null; then
        exit 1002
    fi
}

# @set_date_timezone
# Set date time zone to Asia/Shanghai
function set_date_timezone() {
    log_info "Host: [$LocalIP]: Set date timezone."
    /usr/bin/cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    log_info "Host: [$LocalIP]: Set date timzeon done."
}

# @selinux_config
# Set selinux disabled
function selinux_config() {
    SELINUX_STATUS=$(getenforce)
    if [ "${SELINUX_STATUS}" == "Enforcing" ]; then
        setenforce 0
    fi

    SELINUX_CONFIG_STATUS=$(grep "^SELINUX=" /etc/selinux/config)
    if [ "${SELINUX_CONFIG_STATUS}" = "SELINUX=enforcing" ]; then
        sed -i '/^SELINUX/s/enforcing/disabled/g' /etc/selinux/config
    fi
}

# @networkmanager_config
# If system not RH 8 release version then disable NetworkManager.service
function networkmanager_config() {
    system_release_version=$(cat /etc/redhat-release | awk -F "[ |.]" '{print $4}')
    if [ "$system_release_version"x == "8"x ]; then
        return
    elif [ -z $system_release_version ]; then
        return
    fi
    systemctl stop NetworkManager
    systemctl disable NetworkManager
}

# @limit_config
# Set all user ulimit 655300
# Set all progress ulimit 65500
function limit_config() {
    if ! grep -E "*\s+-\s+nofile\s+655300" /etc/security/limits.conf &>/dev/null; then
        echo '* - nofile 655300' >>/etc/security/limits.conf
    fi
    if ! grep -E "*\s+-\s+nproc\s+65500" /etc/security/limits.conf &>/dev/null; then
        echo '* - nproc 65500' >>/etc/security/limits.conf
    fi
    limit_file=($(ls /etc/security/limits.d/))
    for f in $limit_file; do
        now_limit=$(awk '/*/ && /proc/{print $NF}' /etc/security/limits.d/$f)
        eval sed -i "s/$now_limit/65500/g" /etc/security/limits.d/$f
    done
}

# @history_command_config
# config user history command format like "2022-02-17 10:58:22 root ls"
function history_command_config() {
    cat >>/etc/profile <<EOF

export HISTTIMEFORMAT="%F %T \`whoami\` "
export HISTSIZE=10000
export HISTFILESIZE=10000
EOF
}

# @disable_yumrepo
# disable yum all repo
function disable_yumrepo() {
    cd /etc/yum.repos.d/
    for i in $(ls *.repo 2>/dev/null); do
        rename .repo .repo.bak $i
    done
    cd -
}

function system_env_config() {
    # deploy flush cache
    mkdir /opt/scripts
    cp scripts/clean-cache.sh /opt/scripts/
    cp scripts/clean-container.sh /opt/scripts/
    echo '1 */1 * * * /bin/bash /opt/scripts/clean-cache.sh &> /dev/null' >/var/spool/cron/root
    echo '0 0 * * * /bin/bash /opt/scripts/clean-container.sh' >>/var/spool/cron/root

    # config system
    firewall_config
    system_kernel_paramater_config
    is_system_mini
    set_date_timezone
    selinux_config
    networkmanager_config
    limit_config
    history_command_config
    disable_yumrepo
}
