From: vados-dev <192440777+vados-dev@users.noreply.github.com> Date: Thu, 12 Mar 2026 03:06:27 +0000 (+0300) Subject: Add files X-Git-Url: https://git.vados.ru/gitweb.cgi?a=commitdiff_plain;h=f8337d080e24a3cd102ca0a63f688ef739cd122e;p=Mikrotiks%2FMikrotiks.git Add files --- diff --git a/.bak/Makefile b/.bak/Makefile new file mode 100644 index 0000000..7f1bb20 --- /dev/null +++ b/.bak/Makefile @@ -0,0 +1,86 @@ +# Makefile + +MK_PATH:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) +WORKSPACE_LOC:=$(MK_PATH)../../ + +WorkFiles := checksums.json AM-GlobalFunc.rsc +WORK_DIR := /var/www/ros.vados.ru + +DATE ?= $(shell (date '+%T %d.%m.%Y')) +DTSTAMP ?= $(shell (date '+%Y%d%m%H%M%S')) +VERSION ?= $(shell git symbolic-ref --short HEAD 2>/dev/null)/$(shell git rev-list --count HEAD 2>/dev/null)/$(shell git rev-parse --short=8 HEAD 2>/dev/null) +OWNER ?= $(shell whoami) + +#SEDCMD ?= $(shell sed -e "/^:global CommitId/c :global CommitId \"${COMMITID:-unknown}\";")/$(shell sed ) + +all: $(WorkFiles) + +.PHONY: $(WorkFiles) + +checksums.json : ALL_RSC := $(wildcard *.rsc */*.rsc) +AM-GlobalFunc.rsc : COMMITID := $(VERSION) +AM-GlobalFunc.rsc : COMMITINFO := "$(DATE) - Commit owner: $(OWNER)" + +ifeq ($@,AM-GlobalFunc.rsc) +define sed-cmd = + cd $(WORK_DIR) && \ + sed \ + -e "/^:global CommitId/c :global CommitId \"${COMMITID:-unknown}\";" \ + -e "/^:global CommitInfo/c :global CommitInfo \"${COMMITINFO:-unknown}\";" \ + < "./html/${1}" + endef +endif + +ifeq ($@,checksums.json) + define get-sums = + cd $(WORK_DIR)/html && \ + md5sum $(find -name '*.rsc' | sort) | \ + sed -e "s| \./||" -e 's|.rsc$||' | \ + jq --raw-input --null-input '[ inputs | split (" ") | { (.[1]): (.[0]) }] | add' > $@ + endef +endif + +$(WorkFiles): +ifeq ($@,checksums.json) + $(get-sums) $(ALL_RSC); > $@ +endif + +checksums: checksums.json + cd $(WORK_DIR)/html + +checksums.json: $(WORK_DIR)/bin/checksums.sh $(ALL_RSC) + $(WORK_DIR)/bin/checksums.sh > $(WORK_DIR)/html/$@ + + +$(FuncFile): ./html/$@ + $(sed-cmd) $< > $<~ + mv $<~ $< + +#$(WORK_DIR)/html/AM-GlobalFunc.rsc +# cd $(WORK_DIR)/html && $(WORK_DIR)/bin/commitinfo.sh $< > $<~ +# mv $<~ $< + +#commitinfo: push +# $(WORK_DIR)/bin/$@.sh +#clean + +#checkout: git checkout HEAD . + +#push: +# git $@ origin + +#ifeq (git,$(firstword $(MAKECMDGOALS))) +# # Remaining arguments form the commit string +# GIT_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) +# # ...and turn them into do-nothing targets +# $(eval $(GIT_ARGS):;@:) +#endif + +# git function to push to repo +#git: +# git add . && git commit -m "$(GIT_ARGS)" && git push + + +#clean: +# rm -f $(HTML) checksums.json +# make -C tmpl/ clean diff --git a/.bak/ROSdiff.sh b/.bak/ROSdiff.sh new file mode 100644 index 0000000..f1f4e7c --- /dev/null +++ b/.bak/ROSdiff.sh @@ -0,0 +1,153 @@ +#!/bin/bash +# +# https://dzen.ru/a/ZXWKq1L35Em2EHex?ysclid=mlt10qkrsb471483043 +# +# Use: ./ROSdiff.sh RoutrName SSH_IP SSH_Port +# Last Backups: ls -l $backuppath +# History: ls -l $backuppath/history +# Add to cron +# crontab -e +# 0 20 * * * /var/www/ros.vados.ru/Mikrotiks/.bin/ROSdiff.sh MikroMaster 10.30.30.81 2222 +# + +routers=( 10.30.30.10 10.30.30.81 ) + +date=$(date +%d-%m-%Y) +time=$(date +%H-%M) + +GEN_DATE=$(date '+%Y-%m-%d %H:%M:%S %z') +DTStamp=$(date '+%Y%m%d%H%M%S') + +SSHhost="undefined" +SSHport="2222" +SSHuser="mikro_bak" +SSHpassword="Peskar55" + +BaseDir="/var/www/ros.vados.ru/Mikrotiks" +#$HOME + +HostsFile="${BaseDir}/.mikrotiks" +BackupDir="${BaseDir}/backups" +BackTemp="${BackupDir}/tmp" + +Log="undefined" +RouterName="undefined" + +SSH_KEY=$BaseDir"/.ssh/id_rsa" +SSH_OPTS="-i $SSH_KEY -o PasswordAuthentication=no -p $SSHport" +# Require router-specific SSH key +if [ ! -f "$SSH_KEY" ]; then + echo "Error: SSH key not found at $SSH_KEY" + echo "Run ./setup-ssh-keys.sh to generate the key" + exit 1 +fi +############################### +# Backup listing +############################### +# Get Names Addresses and Ports +# for SSHhost in $( cat $HostsFile ); do +#IFS=$'\n' # make newlines the only separator +readarray -t lines < $HostsFile +set -f +for HR in "${lines[@]}"; do +while IFS=$' ' read -a line || [ -n "$line" ]; do +[[ -z ${line[0]} ]] && continue +${BaseDir}/.bin/rdiff.sh ${line[0]} ${SSHuser} ${line[1]} ${line[2]} +#echo ${line[0]} +#echo ${SSHuser} +#echo ${line[1]} +#echo ${line[2]} +#readarray -t lines < $HostsFile + +#while IFS=" " read -r "${lines[@]}" -a line ; do + +#for line in "${lines[@]}"; +#do +# echo "$line" +done <<<"$(echo -e $HR)" +done +exit 0 + +#cat $HostsFile | while IFS=" " read -a line ; do +# || [ -n "$line" ]; do +#[[ -z ${line[0]} ]] && continue + +for SSHhost in ${routers[@]}; do +RouterName=$(ssh ${SSH_OPTS} ${SSHuser}@${SSHhost} /system/identity/get name | echo $1); +# awk '{print $2}'); +sleep 2 +echo $RouterName +#${BaseDir}/.bin/rdiff.sh ${RouterName} ${SSHuser} ${SSHhost} ${SSHport} +# ${line[0]} ${line[1]} ${line[2]} + +done +exit 0 + +for SSHhost in ${routers[@]}; do + +RouterName=$(ssh ${SSH_OPTS} ${SSHuser}@${SSHhost} system identity print | awk '{print $2}'); + +RouterDir="${BackupDir}/${RouterName}" +HistoryDir="${RouterDir}history" +echo $HistoryDir +RouterTemp="${BackTemp}/${RouterName}" +Log="${RouterTemp}log.txt" +echo $Log +echo ${RouterName} + +precedent_export_name=${RouterName}"-config-export-precedent.rsc" +pen=${RouterName}'-config-export-precedent.rsc' +echo ${pen} + +current_export_name="$RouterName-config-export-current.rsc" +current_backup_name="$routername-config-backup-current.backup" +diff_export_name="$routername-config-export-diff.rsc" + +current_export_name_history="$routername-$(date +%Y-%m-%d-%H-%M)-config-export-current.rsc" +current_backup_name_history="$routername-$(date +%Y-%m-%d-%H-%M)-config-backup-current.backup" +diff_export_name_history="$routername-$(date +%Y-%m-%d-%H-%M)-config-export-diff.rsc" +exit 0 + +echo "Create tmp directory..." +mkdir -p $routertmp +echo "tmp directory created $routername $routertmp ($time)." >> $routerlog +echo +echo "Create backup directory..." +mkdir -p $routerpath +echo "Backups directory created $routername $routerpath ($time)." >> $routerlog +echo +echo "Create history directory..." +mkdir -p $routerhistory +echo "Backups directory created $routername $routerhistory ($time)." >> $routerlog +echo + +cd $routerpath +echo "SSH connect to $routername..." +echo "Create configuration $routername..." +#ssh $SSH_OPTS $username"@"$i" /export file=export.rsc"; +sshpass -p $sshpassword ssh -o StrictHostKeyChecking=no $sshuser@$sshhost -p $sshport export >$current_export_name +echo + +diff -I "RouterOS" $current_export_name $routerpath/$precedent_export_name > $diff_export_name + +if [ "$?" -ne "0" ]; then +sshpass -p $sshpassword ssh -o StrictHostKeyChecking=no $sshuser@$sshhost -p $sshport export file=$current_export_name +sshpass -p $sshpassword ssh -o StrictHostKeyChecking=no $sshuser@$sshhost -p $sshport system backup save name=$current_backup_name +sshpass -p $sshpassword sftp -o StrictHostKeyChecking=no -oPort=$sshport $sshuser@$sshhost:$current_backup_name + +rm -f $precedent_export_name + +cp $current_export_name $backuppath"/history/"$current_export_name_history +cp $current_backup_name $backuppath"/history/"$current_backup_name_history +mv $diff_export_name $backuppath"/history/"$diff_export_name_history + +mv -f $current_export_name $precedent_export_name +rm -f $diff_export_name +#exit 1 +fi + +mv -f $current_export_name $precedent_export_name +rm -f $diff_export_name + +#exit 0 +done diff --git a/.bak/get_backups.sh b/.bak/get_backups.sh new file mode 100644 index 0000000..8924bf4 --- /dev/null +++ b/.bak/get_backups.sh @@ -0,0 +1,109 @@ +#!/bin/bash +date=$(date +%d-%m-%Y) +time=$(date +%H-%M) +username="mikro_bak" +mikrotik=$HOME"/.mikrotiks" +backup_path=$HOME"/backups" +tmp=$HOME"/tmp" +log=$tmp"/log.txt" +SSH_KEY="$HOME/.ssh/id_rsa" +SSH_OPTS="-i $SSH_KEY -o PasswordAuthentication=no -p 2222" +#-------------------------------# +smb_path_backup="//192.168.1.2/Backups" +domain="WORKGROUP" +usrname="backuper" +passwd="root.mikrots.backuper" +# Require router-specific SSH key +if [ ! -f "$SSH_KEY" ]; then + echo "Error: SSH key not found at $SSH_KEY" + echo "Run ./setup-ssh-keys.sh to generate the key" + exit 1 +fi +################ +# Backup listing +################ +# Get addresses +for i in $( cat $mikrotik ); do +mkdir -p $tmp"/"$i +# Get Devices Names +#ssh $SSH_OPTS "$ROUTER_USER@$ROUTER_IP" +RESULT=$(ssh $SSH_OPTS $username"@"$i" /system/identity print" | awk ' {print $2} '); +#RESULT=$(ssh $username"@"$i" -p 2222 system identity print" | awk ' {print $2} '); +echo "Start backup Devices" +echo "Start backup Devices Mikrotiks ($time) $RESULT" > $log +echo "Create Backup $i..." +ssh $SSH_OPTS $username"@"$i" /system/backup save name=binary.backup"; +#ssh $username"@"$i" -p 2222 system backup save name=binary.backup"; +if [ $? -eq 0 ]; then +echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" +echo "Create Backup $i success ($time)" >> $log +echo +else +echo -n "$(tput hpa $(tput cols))$(tput cub 6)[ERROR]" +echo "Createbackup $i failed ($time)" >> $log +echo +fi + +echo "Create configuration $i..." +#ssh $SSH_OPTS $username"@"$i" /export file=export.rsc;" +#ssh $username"@"$i" -p 2222 export file=export.rsc"; +ssh $SSH_OPTS $username"@"$i" export file=export.rsc; delay 3s;" +if [ $? -eq 0 ]; then +echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" +echo "Create configuration $i success ($time)" >> $log +echo +else +echo -n "$(tput hpa $(tput cols))$(tput cub 6)[ERROR]" +echo "Create configuration $i failed ($time)" >> $log +echo +fi +echo "Create backups directory..." +mkdir -p $tmp/$i/$date/ +echo "Backups directory created $i ($time)" >> $log +echo +echo "Download backup files $i..." +sftp $SSH_OPTS "sftp://"$username"@"$i"/binary.backup" $tmp/$i/$date/$i"-"$time".backup"; +scp $SSH_OPTS "$username@$i:export.rsc" $tmp/$i/$date/$i"-"$time".rsc"; +#sftp "ssh://"$username"@"$i":2222/binary.backup" $tmp/$i/$date/$i"-"$time".backup"; +#sftp "ssh://"$username"@"$i":2222/export.rsc" $tmp/$i/$date/$i"-"$time".rsc"; +if [ $? -eq 0 ]; then +echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" +echo "Download backups $i success ($time)" >> $log +echo +else +echo -n "$(tput hpa $(tput cols))$(tput cub 6)[ERROR]" +echo "Download backups $i failed ($time)" >> $log +echo +fi + +echo "Compress backups..." +cd $tmp/$i/ +RESULT=$(tar -czvf $date".tar.gz" $date) +echo "Backups compressed ($time)" >> $log + +#echo "Connect to network share $smb_path_backup..." +#RESULT=$(cat /home/Mikrotiks/sudos | sudo -S -u root mount -t cifs $smb_path_backup /mnt/samba -o username=$usrname,password=$passwd,domain=$domain) +#echo "Networkshare $smb_path_backup connected ($time)" >> $log + +echo "Create directory for backups device $i..." +#RESULT=$(cat /home/Mikrotiks/sudos | sudo -S -u root mkdir -p /mnt/samba/Mikrotik/$i) +RESULT=$(mkdir -p $backup_path"/"$i) +echo "Directory for backup device $i created in network share ($time)" >> $log + +echo "Place backups in network share" +#RESULT=$(cat /home/Mikrotiks/sudos | sudo -S -u root mv $tmp/$i/$date".tar.gz" "/mnt/samba/Mikrotik/$i/$date.tar.gz") +RESULT=$(mv $tmp/$i/$date".tar.gz" $backup_path"/"$i"/"$date".tar.gz") +echo "Backups $i moved to $backup_path"/"$i ($time)" >> $log +echo "" >> $log + +#RESULT=$(cat /home/Mikrotiks/sudos | sudo -S -u root mv $log "/mnt/samba/MIkrotik/$i/$date.log.txt") +RESULT=$(mv $log $backup_path"/"$i/$date".log.txt") + +echo "Remove local backup files device $i" +ssh $SSH_OPTS "$username@$i /file remove binary.backup"; +ssh $SSH_OPTS "$username@$i /file remove export.rsc"; +#rm -r -f $tmp + +#cat /home/Mikrotiks/sudos | sudo -S -u root umount $smb_path_backup +#cat /home/Mikrotiks/sudos | sudo -S -u root umount $smb_path_backup +done diff --git a/.bak/test.sh b/.bak/test.sh new file mode 100644 index 0000000..d42de8f --- /dev/null +++ b/.bak/test.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +while IFS=" " read -a line -r || [ -n "$line" ]; do + + + +date=$(date +%d-%m-%Y) +time=$(date +%H-%M) + +sshuser="mikro_bak" +sshpassword="Peskar55" + +homepath="/var/www/ros.vados.ru/Mikrotiks" + +mikrotik_file=$homepath"/.mikrotiks" +backuppath=$homepath"/backups" +tmp="." +log=$tmp"/log.txt" + +SSH_KEY=$homepath"/.ssh/id_rsa" +# Require router-specific SSH key +if [ ! -f "$SSH_KEY" ]; then + echo "Error: SSH key not found at $SSH_KEY" + echo "Run ./setup-ssh-keys.sh to generate the key" + exit 1 +fi +#export IFS=" " +SSH_OPTS="-i "$SSH_KEY" -o PasswordAuthentication=no -p 2222" + +RESULT=$(ssh $SSH_OPTS $sshuser@10.30.30.10 system identity print | awk ' {print $2} '); +echo +echo $RESULT +echo +exit 0 +#RESULT=(ssh $SSH_OPTS $sshuser"@10.30.30.10" /system/identity print") >> ./ident.txt +# | awk ' {print $2} ' >> ./ident.txt + +#readarray -t lines < "$mikrotik_file" +cat $mikrotik_file | while read -r lines ; do +for line in "${lines}" ; do +echo +#echo $line[$1] +#echo $line[$2] +echo $1 +echo +done +done +exit 0 + +#for i in $( cat $mikrotik_file ) ; do +#cat $mikrotik_file | while read -r line ; do +#-a HR ; do +# [[ -z $0 ]] && continue # skip empty lines +set -- $line +echo +echo "line = "$line +echo +# [[ -z ${line[0]} ]] && continue # skip empty lines +echo $@ +echo +routername=$1 +#${HR[0]} +sshhost=$2 +#${HR[1]} +sshport=$3 +#${HR[2]} + +SSH_OPTS="-i "$SSH_KEY" -o PasswordAuthentication=no -p "$sshport" "$sshuser"@"$sshhost + +current_export_name=$routername"-config-export-current.rsc" + +echo +echo $routername +echo +echo $current_export_name +echo + + +#echo "Get current export file ($time) "$RESULT +# >> $log +#sshpass -p $sshpassword ssh -o StrictHostKeyChecking=no $sshuser@$sshhost -p $sshport export >$current_export_name +ssh $SSH_OPTS " export file="$current_export_name"; delay 3s;" && continue +if [ $? -eq 0 ]; then +echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" +echo "Create configuration $routername success ($time)" +# >> $log +echo +else +echo -n "$(tput hpa $(tput cols))$(tput cub 6)[ERROR]" +echo "Create configuration $i failed ($time)" +# >> $log +echo +fi + +done +#done +#exit 0 +# cat $mikrotik_file | while read -a HR ; do +# [[ -z ${HR[0]} ]] && continue # skip empty lines +#while IFS=" " read -a line -r || [ -n "$line" ]; do +#echo $line +#echo ${line[0]} +#echo ${line[1]} +#echo ${line[2]} +#echo ${line[3]} +#RouterName=${line[0]} +#SSHhost=${line[1]} +#SSHport=${line[2]} + +#SSH_OPTS="-i $SSH_KEY -o PasswordAuthentication=no -p $SSHport" +#current_export_name="$RouterName-config-export-current.rsc" +#ssh $SSH_OPTS $SSHuser@$SSHhost export >$current_export_name +# 2>&1 +# "; delay 3s;" && continue +# sshpass -p $SSHpassword ssh -o StrictHostKeyChecking=no $SSHuser@$SSHhost -p $SSHport export >$current_export_name + +# Escape backslashes, dollar signs, and quotes +# line=$(echo "$line" | sed 's/\\/\\\\/g' | sed 's/\$/\\$/g' | sed 's/"/\\"/g') +# if [ -z "$SCRIPT_CONTENT" ]; then +# SCRIPT_CONTENT="$line" +# else +# SCRIPT_CONTENT="$SCRIPT_CONTENT\\n$line" +# fi +#continue +#done < "$HostsFile" +exit 0 + diff --git a/.bak/tmp/Makefile b/.bak/tmp/Makefile new file mode 100644 index 0000000..f9aa32a --- /dev/null +++ b/.bak/tmp/Makefile @@ -0,0 +1,149 @@ +# Makefile + +BUILD_DIR = $(shell pwd) + +BIN_DIR = bin +commitinfo.sh := $(wildcard bin/commitinfo.sh) + +HTML_DIR = html +ALL_RSC := $(wildcard html/*.rsc html/*/*.rsc) +GLOB_RSC := $(wildcard html/AM-GlobalFunc.rsc) + +DATE ?= $(shell (date '+%T %d.%m.%Y')) +DTSTAMP_FMT ?= "+%Y%m%d%H%M" +DTSTAMP ?= $(shell (date $(DTSTAMP_FMT))) +VERSION ?= $(shell git symbolic-ref --short HEAD 2>/dev/null)/$(shell git rev-list --count HEAD 2>/dev/null)/$(shell git rev-parse --short=8 HEAD 2>/dev/null) +RUN_OWNER := $(shell whoami 2>/dev/null) +COMM_REPO := $(shell git rev-parse --show-toplevel | rev | cut -d/ -f1 | rev 2>/dev/nul) +COMM_BRANCH := $(shell git symbolic-ref --short HEAD 2>/dev/null) + +COMM_TAG := $(shell git rev-list --abbrev-commit --tags --max-count=1) +# `2>/dev/null` suppress errors and `|| true` suppress the error codes. +TAG := $(shell git describe --abbrev=0 --tags ${COMM_TAG} 2>/dev/null || true) +# here we strip the version prefix +TAG_VERS :=$(TAG:v%=%) +# get the latest commit hash in the short form +COMM_HASH := $(shell git rev-parse --short=8 HEAD 2>/dev/null) # Get short commit hash +#COMMIT := $(shell git rev-parse --short HEAD) +# get the latest commit date in the form of YYYYmmddHHMM ($(DTSTAMP_FMT)) +COMM_DATE := $(shell git log -1 --format=%cd --date=format:$(DTSTAMP_FMT)) +ifneq ($(COMM_HASH), $(COMM_TAG)) + TAG_VERS :=$(TAG_VERS)-next-$(COMM_HASH)-$(COMM_DATE) +endif +ifeq ($(TAG_VERS), ) + TAG_VERS :=$(COMM_HASH)-$(COMM_DATE) +endif +ifneq ($(shell git status --porcelain), ) + TAG_VERS :=$(TAG_VERS)-dirty +endif + +COMMIT_ID := $(VERSION) +COMM_INFO := $(shell echo -e "Autocommit in repo: $(COMM_REPO), generated by owner: $(RUN_OWNER), in $(DATE)." 2>/dev/null) + +export BUILD_DIR BIN_DIR HTML_DIR DATE DTSTAMP VERSION COMMIT_ID COMM_TAG COMM_HASH COMM_INFO + +SHELL := /bin/bash + +export BUILD_DIR BIN_DIR HTML_DIR DATE DTSTAMP VERSION COMMIT_ID COMM_TAG COMM_HASH COMM_INFO COMM_DATE + +.ONESHELL: + +.DEFAULT_GOAL := run + +export BUILD_DIR BIN_DIR HTML_DIR DATE DTSTAMP VERSION COMMIT_ID COMM_TAG COMM_HASH COMM_INFO + +include $(BUILD_DIR)/.config/config.mk + +.PHONY: run check notify checksums commitinfo test + +run: check + @echo "[run] start main flow" + checksums + commitinfo + @echo "[run] done" + +check: + @bash bin/check_repo.sh + +notify: + @bash bin/notify_telegram.sh "manual notify from make" + +checksums: checksums.json + +checksums.json: bin/checksums.sh $(ALL_RSC) + bin/checksums.sh > html/tmp/$@ + +test: + @bash -n bin/check_repo.sh + @bash -n bin/notify_telegram.sh + @bash -n bin/checksums.sh + @bash -n bin/commitinfo.sh + @echo "syntax ok" + + +.DEFAULT_GOAL := all +#.PHONY: all checksums git-check commitinfo clean +#all: checksums git-check commitinfo + + +gitcheck: $(BUILD_DIR) + cd $ && + @if git diff --quiet && git diff --cached --quiet && [ -z "$$(git ls-files --others --exclude-standard)" ]; then \ + echo "The first checks have been passed, the repo seems to be clean... But... Still, let's check a little more!"; \ + git add . && \ + if [[ -n "$$(git status --porcelain)" ]]; then \ + echo "Uncommitted changes detected! Commit it..."; \ +# git commit -m "$(COMM_INFO)"; \ +# git push; \ + exit 1; \ + else \ + echo "repo clean"; \ + fi \ + else \ + @echo "Warning: Uncommitted changes detected! Go to autocommit steps..."; \ + git branch -v; \ +# git commit -am "$(COMM_INFO)"; \ +# git push; \ + fi + + +#@if [ -n "$$(git diff --quiet)" ] && [ -n "$$(git diff --cached --quiet)" ] && [ -n "$$(git ls-files --others --exclude-standard)" ]; then \ +#[ -n "$$(git status --porcelain)" ] + +check-uncommitted: + @if [ -n "$$(git diff --quiet)" ] && [ -n "$$(git diff --cached --quiet)" ] && [ -n "$$(git ls-files --others --exclude-standard)" ]; then \ + echo "Warning: Uncommitted changes detected! Go to autocommit steps..."; \ + else \ + echo "The first checks have been passed, the repo seems to be clean... But... Still, let's check a little more!"; \ + if git status --porcelain; then \ + echo "Repository is clean (no uncommitted or untracked changes). Exit 0."; \ + exit 0; \ + else \ + echo "Error! Git status is not porcelain! Check it mannualy. Exit 1."; \ + exit 1; \ + fi \ + fi + + +# if [[ -n "`$(rungit) status --porcelain`" ]];: then \ + echo "Warning: Uncommitted changes detected! Go to autocmmit..."; \ + git commit -m "$(COMM_INFO)"; \ + git push origin $(COMM_BANCH); \ + else \ + echo "Repository is clean (no uncommitted or untracked changes). Exit 0."; \ + exit 0; \ + fi + +commitinfo: $(commitinfo.sh) + +.PHONY: $(commitinfo.sh) +$(commitinfo.sh): $(GLOB_RSC) + $(commitinfo.sh) $< > $<~ + mv $<~ $< + + +clean: + git checkout HEAD -- . + +# rm -f $(HTML) checksums.json +# make -C contrib/ clean diff --git a/.bashrc b/.bashrc new file mode 100644 index 0000000..701dfd0 --- /dev/null +++ b/.bashrc @@ -0,0 +1,127 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return;; +esac + +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# make less more friendly for non-text input files, see lesspipe(1) +[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color|*-256color) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +#force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +fi +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# colored GCC warnings and errors +#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + +# some more ls aliases +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' + +# Add an "alert" alias for long running commands. Use like so: +# sleep 10; alert +alias alert='n8otify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi + +# Terminal Prompt full paths +export PROMPT_DIRTRIM=5 +export force_color_prompt=yes +export GIT_SSH=$(which ssh) +#'"c:\WINDOWS\System32\OpenSSH\ssh.exe" -T' +eval $(ssh-agent) +ssh-add +GPG_TTY=`tty` +export GPG_TTY diff --git a/.config/.mikrotiks b/.config/.mikrotiks new file mode 100644 index 0000000..53a2c1b --- /dev/null +++ b/.config/.mikrotiks @@ -0,0 +1,3 @@ +MikroNUC 10.30.30.10 2222 mikro_bak Peskar55 +MikroMaster 10.30.30.81 2222 mikro_bak Peskar55 +MikroYellow 10.30.30.86 2222 mikro_bak Peskar55 diff --git a/.config/mc/hotlist b/.config/mc/hotlist new file mode 100644 index 0000000..e69de29 diff --git a/.config/mc/ini b/.config/mc/ini new file mode 100644 index 0000000..3152b04 --- /dev/null +++ b/.config/mc/ini @@ -0,0 +1,165 @@ +[Midnight-Commander] +verbose=true +shell_patterns=true +auto_save_setup=true +preallocate_space=false +auto_menu=false +use_internal_view=true +use_internal_edit=true +clear_before_exec=true +confirm_delete=true +confirm_overwrite=true +confirm_execute=false +confirm_history_cleanup=true +confirm_exit=false +confirm_directory_hotlist_delete=false +confirm_view_dir=false +safe_delete=false +safe_overwrite=false +use_8th_bit_as_meta=false +mouse_move_pages_viewer=true +mouse_close_dialog=false +fast_refresh=false +drop_menus=true +wrap_mode=true +old_esc_mode=true +cd_symlinks=true +show_all_if_ambiguous=false +use_file_to_guess_type=true +alternate_plus_minus=false +only_leading_plus_minus=true +show_output_starts_shell=false +xtree_mode=false +file_op_compute_totals=true +classic_progressbar=true +use_netrc=true +ftpfs_always_use_proxy=false +ftpfs_use_passive_connections=true +ftpfs_use_passive_connections_over_proxy=false +ftpfs_use_unix_list_options=true +ftpfs_first_cd_then_ls=true +ignore_ftp_chattr_errors=true +editor_fill_tabs_with_spaces=false +editor_return_does_auto_indent=false +editor_backspace_through_tabs=false +editor_fake_half_tabs=true +editor_option_save_position=true +editor_option_auto_para_formatting=false +editor_option_typewriter_wrap=false +editor_edit_confirm_save=true +editor_syntax_highlighting=true +editor_persistent_selections=true +editor_drop_selection_on_copy=true +editor_cursor_beyond_eol=false +editor_cursor_after_inserted_block=false +editor_visible_tabs=true +editor_visible_spaces=true +editor_line_state=false +editor_simple_statusbar=false +editor_check_new_line=false +editor_show_right_margin=false +editor_group_undo=true +editor_state_full_filename=true +editor_ask_filename_before_edit=false +nice_rotating_dash=true +mcview_remember_file_position=false +auto_fill_mkdir_name=true +copymove_persistent_attr=true +pause_after_run=2 +mouse_repeat_rate=100 +double_click_speed=250 +old_esc_mode_timeout=1000000 +max_dirt_limit=10 +num_history_items_recorded=60 +vfs_timeout=60 +ftpfs_directory_timeout=900 +ftpfs_retry_seconds=30 +fish_directory_timeout=900 +editor_tab_spacing=8 +editor_word_wrap_line_length=72 +editor_option_save_mode=0 +editor_backup_extension=~ +editor_filesize_threshold=64M +editor_stop_format_chars=-+*\\,.;:&> +mcview_eof= +skin=default + +filepos_max_saved_entries=1024 +shadows=true +shell_directory_timeout=900 + +[Layout] +output_lines=0 +left_panel_size=118 +top_panel_size=0 +message_visible=false +keybar_visible=false +xterm_title=true +command_prompt=true +menubar_visible=false +free_space=true +horizontal_split=false +vertical_equal=true +horizontal_equal=true + +[Misc] +timeformat_recent=%b %e %H:%M +timeformat_old=%b %e %Y +ftp_proxy_host=gate +ftpfs_password=anonymous@ +display_codepage=ASCII +source_codepage=ASCII +autodetect_codeset= +spell_language=en +clipboard_store= +clipboard_paste= + +[Colors] +base_color= +xterm-256color= +color_terminals= +linux= +xterm= + +[Panels] +simple_swap=false +show_mini_info=true +kilobyte_si=false +mix_all_files=false +show_backups=true +show_dot_files=true +fast_reload=false +fast_reload_msg_shown=false +mark_moves_down=true +reverse_files_only=true +auto_save_setup_panels=false +navigate_with_arrows=true +panel_scroll_pages=true +panel_scroll_center=false +mouse_move_pages=true +filetype_mode=true +permission_mode=false +torben_fj_mode=false +quick_search_mode=2 +select_flags=6 + +[FindFile] +file_case_sens=true +file_shell_pattern=true +file_find_recurs=true +follow_symlinks=true +file_skip_hidden=false +file_all_charsets=false +content_case_sens=true +content_regexp=false +content_first_hit=false +content_whole_words=false +content_all_charsets=false +ignore_dirs_enable=true +ignore_dirs= + +[Panelize] +Find *.orig after patching=find . -name \\*.orig -print +Find rejects after patching=find . -name \\*.rej -print +Modified git files=git ls-files --modified +Find SUID and SGID programs=find . \\( \\( -perm -04000 -a -perm /011 \\) -o \\( -perm -02000 -a -perm /01 \\) \\) -print diff --git a/.config/mc/panels.ini b/.config/mc/panels.ini new file mode 100644 index 0000000..92992b2 --- /dev/null +++ b/.config/mc/panels.ini @@ -0,0 +1,35 @@ +[New Left Panel] +display=listing +reverse=false +case_sensitive=true +exec_first=false +sort_order=name +list_mode=full +brief_cols=2 +user_format=half type name | size | perm +user_status0=half type name | size | perm +user_status1=half type name | size | perm +user_status2=half type name | size | perm +user_status3=half type name | size | perm +user_mini_status=false +list_format=full + +[New Right Panel] +display=listing +reverse=false +case_sensitive=true +exec_first=false +sort_order=name +list_mode=full +brief_cols=2 +user_format=half type name | size | perm +user_status0=half type name | size | perm +user_status1=half type name | size | perm +user_status2=half type name | size | perm +user_status3=half type name | size | perm +user_mini_status=false +list_format=full + +[Dirs] +current_is_left=true +other_dir=/mnt/d/dst/D41/vbmeta-tools diff --git a/.gitconfig b/.gitconfig new file mode 100644 index 0000000..1d9bed2 --- /dev/null +++ b/.gitconfig @@ -0,0 +1,25 @@ +[user] + name = vados-dev + email = vados@vados.ru + signingkey = 1FD2694762FCE438 +[color] + ui = auto +[safe] + directory = /home/vados/sl8541e_cus_go + directory = /var/www/ros.vados.ru + directory = /var/www/ros.vados.ru/html + directory = /var/www/ros.vados.ru/Mikrotiks + directory = /var/www/ros.vados.ru/Mikrotiks/backups + directory = /.data/nfs/repos/Mikrotiks + directory = /.data/nfs/repos/Mikrotiks/Mikrotiks.git + directory = /.data/nfs/repos/Mikrotiks/ros.vados.ru.git +[init] + defaultBranch = main +[core] + autocrlf = false +[protocol] + version = 2 +[commit] + gpgsign = true +[gpg] + program = gpg2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d4e18e1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# folder for backups repo +backups/ +backups/** +bin/logs/ +.gnupg/ +.local/ +.cache/ +oxidized/ +upload/ +test/ +.cache/ +.docker/ +.gnupg/ +.local/ +.ssh/ +.vscode/ +**/Precedent-Config.rsc + +.bash_history +#.bak +# backup and temporary files +*~ +# patches and related files +*.orig +*.patch +*.rej diff --git a/.lesshst b/.lesshst new file mode 100644 index 0000000..4d1c30b --- /dev/null +++ b/.lesshst @@ -0,0 +1 @@ +.less-history-file: diff --git a/.profile b/.profile new file mode 100644 index 0000000..52115e0 --- /dev/null +++ b/.profile @@ -0,0 +1,31 @@ +# ~/.profile: executed by the command interpreter for login shells. +# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login +# exists. +# see /usr/share/doc/bash/examples/startup-files for examples. +# the files are located in the bash-doc package. + +# the default umask is set in /etc/profile; for setting the umask +# for ssh logins, install and configure the libpam-umask package. +#umask 022 + +# if running bash +if [ -n "$BASH_VERSION" ]; then + # include .bashrc if it exists + if [ -f "$HOME/.bashrc" ]; then + . "$HOME/.bashrc" + fi +fi + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/bin" ] ; then + PATH="$HOME/bin:$PATH" +fi + +if [ -d "$HOME/.bin" ] ; then + PATH="$HOME/.bin:$PATH" +fi + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/.local/bin" ] ; then + PATH="$HOME/.local/bin:$PATH" +fi diff --git a/.repo_.gitconfig.json b/.repo_.gitconfig.json new file mode 100644 index 0000000..8631e7a --- /dev/null +++ b/.repo_.gitconfig.json @@ -0,0 +1,20 @@ +{ + "user.name": [ + "vados-dev" + ], + "user.email": [ + "vados@vados.ru" + ], + "color.ui": [ + "auto" + ], + "safe.directory": [ + "/var/www/ros.vados.ru/Mikrotiks" + ], + "init.defaultbranch": [ + "main" + ], + "core.autocrlf": [ + "false" + ] +} \ No newline at end of file diff --git a/.selected_editor b/.selected_editor new file mode 100644 index 0000000..dbc0072 --- /dev/null +++ b/.selected_editor @@ -0,0 +1,2 @@ +# Generated by /usr/bin/select-editor +SELECTED_EDITOR="/usr/bin/mcedit" diff --git a/.wget-hsts b/.wget-hsts new file mode 100644 index 0000000..33cdbf5 --- /dev/null +++ b/.wget-hsts @@ -0,0 +1,5 @@ +# HSTS 1.0 Known Hosts database for GNU Wget. +# Edit at your own risk. +# +github.com 0 1 1771536570 31536000 +codeload.github.com 0 0 1771536571 31536000 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..49bd3bb --- /dev/null +++ b/Makefile @@ -0,0 +1,110 @@ +# Makefile + +BUILD_DIR = $(shell pwd) +REPO_DIR ?= $(BUILD_DIR) + +ALL_RSC := $(wildcard html/*.rsc html/*/*.rsc) +commitinfo.sh := $(wildcard bin/commitinfo.sh) +GLOB_RSC := $(wildcard html/AM-GlobalFunc.rsc) + +SHELL := /bin/bash + +include ../.config/config.mk + +COMM_TAG := $(shell git rev-list --abbrev-commit --tags --max-count=1) +# `2>/dev/null` suppress errors and `|| true` suppress the error codes. +TAG := $(shell git describe --abbrev=0 --tags ${COMM_TAG} 2>/dev/null || true) +# here we strip the version prefix +TAG_VERS :=$(TAG:v%=%) +# get the latest commit hash in the short form +COMM_HASH := $(shell git rev-parse --short=8 HEAD 2>/dev/null) # Get short commit hash +#COMMIT := $(shell git rev-parse --short HEAD) +# get the latest commit date in the form of YYYYmmddHHMM ($(DTSTAMP_FMT)) +COMM_DATE := $(shell git log -1 --format=%cd --date=format:$(DTSTAMP_FMT)) +ifneq ($(COMM_HASH), $(COMM_TAG)) + TAG_VERS :=$(TAG_VERS)-next-$(COMM_HASH)-$(COMM_DATE) +endif +ifeq ($(TAG_VERS), ) + TAG_VERS :=$(COMM_HASH)-$(COMM_DATE) +endif +ifneq ($(shell git status --porcelain), ) + TAG_VERS :=$(TAG_VERS)-dirty +endif + +.ONESHELL: + +export BUILD_DIR REPO_DIR ALL_RSC GLOB_RSC + +.DEFAULT_GOAL := all + +.PHONY: all check commit notify test + +all: + @$(MAKE) check; rc=$$?; \ + if [ $$rc -eq 0 ]; then \ + echo "[add] check $$rc, go to commit..."; \ + $(MAKE) commit; cm=$$?; \ + if [ $$cm -eq 0 ]; then \ + echo "[all] commit exit $$cm. Exit Ok."; \ + else \ + $(MAKE) notify MSG="[all] commit exit $$cm. Check it!"; \ + fi \ + else \ + echo "[all] check exit $$rc, repo is clean exit Ok."; \ + fi + @echo "[all] done" + +run: + @$(MAKE) check; rc=$$?; \ + if [ $$rc -eq 0 ]; then \ + echo "[run] check $$rc, go to commitinfo.sh..."; \ + $(MAKE) $(commitinfo.sh); ci=$$?; \ + if [ $$ci -eq 0 ]; then \ + echo "[run] commitinfo.sh exit $$ci. Go to checksums.sh..."; \ + $(MAKE) checksums; cs=$$?; \ + if [ $$cs -eq 0 ]; then \ + echo "[run] checksums.sh exit $$cs. Do git add commit and push..."; \ + git add .; \ + git commit -m '$(COMM_INFO)'; \ + git push; \ + else \ + $(MAKE) notify MSG="[run] checksums.sh exit $$cs, check it!"; \ + fi \ + else \ + $(MAKE) notify MSG="[run] commitinfo.sh exit $$ci, check it!"; \ + fi \ + else \ + echo "[run] check exit $$rc, repo is clean exit Ok."; \ + fi + @echo "[run] done" + +check: + @bash bin/check_repo.sh + +commit: + cd $(BUILD_DIR) + git add . + git commit -m '$(COMM_INFO)' + git push + +notify: + @bash bin/notify_telegram.sh "$(MSG)" + +checksums: checksums.json + +checksums.json: bin/checksums.sh $(ALL_RSC) + bin/checksums.sh > html/tmp/$@ + +$(commitinfo.sh): $(GLOB_RSC) + $(commitinfo.sh) $< > $<~ + mv $<~ $< + +test: + @bash -n bin/check_repo.sh + @bash -n bin/notify_telegram.sh + @bash -n bin/checksums.sh + @bash -n bin/commitinfo.sh + @echo "syntax ok" + +#clean: +# git checkout HEAD -- . diff --git a/bin/bash-progress-indicator/LICENSE b/bin/bash-progress-indicator/LICENSE new file mode 100644 index 0000000..830c241 --- /dev/null +++ b/bin/bash-progress-indicator/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Leandro Nunes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/bin/bash-progress-indicator/README.md b/bin/bash-progress-indicator/README.md new file mode 100644 index 0000000..8bbeb1a --- /dev/null +++ b/bin/bash-progress-indicator/README.md @@ -0,0 +1,28 @@ +# bash-progress-indicator +Pure Bash script progress indicators + +## Usage +``` +chmod +x main.sh +./main.sh {progress_indicator_type} +``` + +## progress_indicator_type +#### progress +![type_progress](https://user-images.githubusercontent.com/2450417/37887129-6a7fafec-3096-11e8-8bc0-7768e958119e.gif) + +#### progress_advanced +![type_progress_advanced](https://user-images.githubusercontent.com/2450417/37887130-6ddce736-3096-11e8-9696-25b86becbce3.gif) + +#### spinner1 +![type_spinner1](https://user-images.githubusercontent.com/2450417/37887236-0e8ccf0c-3097-11e8-9c6d-c6f4fc60b712.gif) +#### spinner2 +![type_spinner2](https://user-images.githubusercontent.com/2450417/37887241-12e1c814-3097-11e8-91b2-e43e96ff8cd0.gif) +#### spinner3 +![type_spinner3](https://user-images.githubusercontent.com/2450417/37887242-13012e98-3097-11e8-80cb-ebca61da3109.gif) + +## I wrote an article about this technique [pt-br] +[Medium - [Bash] Construindo indicador de progresso](https://medium.com/meninunes/bash-construindo-indicador-de-progresso-8de94c37683) + +## License +[MIT License](LICENSE) © [Leandro Nunes](https://lnfnunes.com.br) diff --git a/bin/bash-progress-indicator/main.sh b/bin/bash-progress-indicator/main.sh new file mode 100644 index 0000000..cf565e7 --- /dev/null +++ b/bin/bash-progress-indicator/main.sh @@ -0,0 +1,30 @@ +#!/bin/bash -e +# shellcheck disable=SC1091 + +declare -rx STEPS=( + 'pre-install' + 'install' + 'post-install' +) +declare -rx CMDS=( + 'sleep 10' + 'sleep 10' + 'sleep 10' +) + +case $1 in + progress) + . 'progress.sh' + ;; + progress_advanced) + . 'progress_advanced.sh' + ;; + spinner*) + . 'spinner.sh' + ;; + *) + echo "Invalid option $1!" + exit 1 +esac + +start diff --git a/bin/bash-progress-indicator/progress.sh b/bin/bash-progress-indicator/progress.sh new file mode 100644 index 0000000..b5ca26e --- /dev/null +++ b/bin/bash-progress-indicator/progress.sh @@ -0,0 +1,23 @@ +#!/bin/bash -e + +declare -rx BAR_SIZE="##########" +declare -rx CLEAR_LINE="\\033[K" + +start() { + local MAX_STEPS=${#STEPS[@]} + local MAX_BAR_SIZE="${#BAR_SIZE}" + + tput civis -- invisible + + echo -ne "\\r[${BAR_SIZE:0:0}] 0 %$CLEAR_LINE" + for step in "${!STEPS[@]}"; do + ${CMDS[$step]} + + perc=$(((step + 1) * 100 / MAX_STEPS)) + percBar=$((perc * MAX_BAR_SIZE / 100)) + echo -ne "\\r[${BAR_SIZE:0:percBar}] $perc %$CLEAR_LINE" + done + echo "" + + tput cnorm -- normal +} diff --git a/bin/bash-progress-indicator/progress_advanced.sh b/bin/bash-progress-indicator/progress_advanced.sh new file mode 100644 index 0000000..ad4f151 --- /dev/null +++ b/bin/bash-progress-indicator/progress_advanced.sh @@ -0,0 +1,27 @@ +#!/bin/bash -e + +start() { + local MAX_STEPS=${#STEPS[@]} + local BAR_SIZE="##########" + local MAX_BAR_SIZE="${#BAR_SIZE}" + local CLEAR_LINE="\\033[K" + + tput civis -- invisible + + for step in "${!STEPS[@]}"; do + perc=$((step * 100 / MAX_STEPS)) + percBar=$((perc * MAX_BAR_SIZE / 100)) + echo -ne "\\r- ${STEPS[step]} [ ]$CLEAR_LINE\\n" + echo -ne "\\r[${BAR_SIZE:0:percBar}] $perc %$CLEAR_LINE" + + ${CMDS[$step]} + + perc=$(((step + 1) * 100 / MAX_STEPS)) + percBar=$((perc * MAX_BAR_SIZE / 100)) + echo -ne "\\r\\033[1A- ${STEPS[step]} [✔]$CLEAR_LINE\\n" + echo -ne "\\r[${BAR_SIZE:0:percBar}] $perc %$CLEAR_LINE" + done + echo "" + + tput cnorm -- normal +} diff --git a/bin/bash-progress-indicator/spinner.sh b/bin/bash-progress-indicator/spinner.sh new file mode 100644 index 0000000..b68cf89 --- /dev/null +++ b/bin/bash-progress-indicator/spinner.sh @@ -0,0 +1,82 @@ +#!/bin/bash -e + +declare -x FRAME +declare -x FRAME_INTERVAL + +set_spinner() { + case $1 in + spinner1) + FRAME=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏") + FRAME_INTERVAL=0.1 + ;; + spinner2) + FRAME=("-" "\\" "|" "/") + FRAME_INTERVAL=0.25 + ;; + spinner3) + FRAME=("◐" "◓" "◑" "◒") + FRAME_INTERVAL=0.5 + ;; + spinner4) + FRAME=(":(" ":|" ":)" ":D") + FRAME_INTERVAL=0.5 + ;; + spinner5) + FRAME=("◇" "◈" "◆") + FRAME_INTERVAL=0.5 + ;; + spinner6) + FRAME=("⚬" "⚭" "⚮" "⚯") + FRAME_INTERVAL=0.25 + ;; + spinner7) + FRAME=("░" "▒" "▓" "█" "▓" "▒") + FRAME_INTERVAL=0.25 + ;; + spinner8) + FRAME=("☉" "◎" "◉" "●" "◉") + FRAME_INTERVAL=0.1 + ;; + spinner9) + FRAME=("❤" "♥" "♡") + FRAME_INTERVAL=0.15 + ;; + spinner10) + FRAME=("✧" "☆" "★" "✪" "◌" "✲") + FRAME_INTERVAL=0.1 + ;; + spinner11) + FRAME=("●" "◕" "☯" "◔" "◕") + FRAME_INTERVAL=0.25 + ;; + *) + echo "No spinner is defined for $1" + exit 1 + esac +} + +start() { + local step=0 + +# tput civis -- invisible + + while [ "$step" -lt "${#CMDS[@]}" ]; do + ${CMDS[$step]} & pid=$! + + while ps -p $pid &>/dev/null; do + echo -ne "\\r[ ] ${STEPS[$step]} ..." + + for k in "${!FRAME[@]}"; do + echo -ne "\\r[ ${FRAME[k]} ]" + sleep $FRAME_INTERVAL + done + done + + echo -ne "\\r[ ✔ ] ${STEPS[$step]}\\n" + step=$((step + 1)) + done + +# tput cnorm -- normal +} + +set_spinner "$1" diff --git a/bin/check_repo.sh b/bin/check_repo.sh new file mode 100755 index 0000000..1ecb927 --- /dev/null +++ b/bin/check_repo.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +cd "${REPO_DIR:-.}" + +dirty="$(git ls-files -u || true)" +lsfiles="$(git ls-files --others --exclude-standard || true)" + +# Conflict or unresolved state: stop and notify. +if [[ -n "$dirty" ]]; then + echo "[check_repo] repo has conflicts, stop" + echo "[check_repo] unmerged files:" + printf "%s\n" "$dirty" + echo "[check_repo] resolve conflicts and run: git add && git commit" + bash bin/notify_telegram.sh "STOP: repo conflicts in $(pwd)" + exit 1 +fi + +# Exit 0 only when repo is NOT clean to allow autocommit flow. +if git diff --quiet && git diff --cached --quiet && [[ -z "$lsfiles" ]]; then + echo "[check_repo] repo clean. Exit 1 from check_repo.sh." + exit 1 +else + echo "[check_repo] repo not clean. Exit 0 from check_repo.sh." + exit 0 +fi diff --git a/bin/logs b/bin/logs new file mode 120000 index 0000000..927bfe5 --- /dev/null +++ b/bin/logs @@ -0,0 +1 @@ +/var/log/Mikrotiks \ No newline at end of file diff --git a/bin/ros-conf/README.md b/bin/ros-conf/README.md new file mode 100644 index 0000000..973a2a7 --- /dev/null +++ b/bin/ros-conf/README.md @@ -0,0 +1,41 @@ +# RouterOS Configuration Scripts + +Personal RouterOS configuration scripts for home network management. + +## Overview + +This repository contains RouterOS scripts to configure and diagnose a MikroTik router. Configuration scripts set up router modes (routing, bridging, NAT, DHCP). Check scripts display router settings and diagnostics. + +## Quick Start + +### Running Scripts + +Run scripts on the router using forward slashes: + +```routeros +/system script run config/firewall +/system script run check/nat +``` + +## Network Configuration + +The `combo1` port is renamed to `combo1-WAN` for routing mode or `combo1-bridge` for switching mode. The `bridge` interface is used for the internal network. + +The WAN interface uses `192.168.200.2/24` with gateway `192.168.200.1`. The bridge interface uses `192.168.88.1/24` as the gateway for the internal network. DHCP serves addresses from `192.168.88.100-192.168.88.199`. + +## Hardware + +These scripts are tested on CRS106, a MikroTik switch/router. + +## Repository Structure + +```text +routeros-config/ +├── scripts/ +│ ├── config/ # Configuration scripts +│ ├── check/ # Diagnostic scripts +│ └── README.md # Format and syntax guidelines +└── README.md # This file +``` + +For format and syntax guidelines, see [scripts/README.md](scripts/README.md). diff --git a/bin/ros-conf/setup-ssh-keys.sh b/bin/ros-conf/setup-ssh-keys.sh new file mode 100644 index 0000000..6653373 --- /dev/null +++ b/bin/ros-conf/setup-ssh-keys.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Setup SSH keys for RouterOS router + +ROUTER_IP="10.30.30.81" +ROUTER_USER="mikro_bak" +KEY_NAME=$ROUTER_USER"_rsa@"$ROUTER_IP +KEY_PATH="$HOME/.ssh/$KEY_NAME" + +# Check/create .ssh directory +if [ ! -d "$HOME/.ssh" ]; then + mkdir -p "$HOME/.ssh" + chmod 700 "$HOME/.ssh" +fi + +# Generate SSH key if it doesn't exist +if [ ! -f "$KEY_PATH" ]; then + ssh-keygen -t rsa -b 2048 -f "$KEY_PATH" -N "" -C "$ROUTER_USER@$ROUTER_IP" +fi + +# Upload and import key on router +scp "$KEY_PATH.pub" "$ROUTER_USER@$ROUTER_IP -p 2222":/ +ssh "$ROUTER_USER@$ROUTER_IP -p 2222" "/user ssh-keys import public-key-file=$KEY_NAME.pub user=$ROUTER_USER" + +# Verify key works +if ! ssh -i "$KEY_PATH" -o PasswordAuthentication=no "$ROUTER_USER@$ROUTER_IP -p 2222" "/system identity print" >/dev/null 2>&1; then + echo "Error: SSH key authentication failed" + exit 1 +fi diff --git a/bin/ros-conf/sync-script.sh b/bin/ros-conf/sync-script.sh new file mode 100644 index 0000000..ca4c1de --- /dev/null +++ b/bin/ros-conf/sync-script.sh @@ -0,0 +1,139 @@ +#!/bin/bash +# Upload all scripts and sync to RouterOS + +ROUTER_IP="10.30.30.10" +ROUTER_USER="mikro_bak" +SSH_KEY="$HOME/.ssh/mikro_bak_rsa" +RSC_FILE="import_scripts.rsc" + +# Require router-specific SSH key +if [ ! -f "$SSH_KEY" ]; then + echo "Error: SSH key not found at $SSH_KEY" + echo "Run ./setup-ssh-keys.sh to generate the key" + exit 1 +fi + +SSH_OPTS="-i $SSH_KEY -o PasswordAuthentication=no" + +# Generate .rsc import file +echo "Generating import file..." + +# Get git commit hash and dirty status +GIT_HASH=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") +if [ -z "$(git status --porcelain 2>/dev/null)" ]; then + GIT_STATUS="$GIT_HASH" +else + GIT_STATUS="$GIT_HASH-dirty" +fi + +# Get current date with timezone offset +GEN_DATE=$(date '+%Y-%m-%d %H:%M:%S %z') + +# Write header +cat > "$RSC_FILE" << RSC_HEADER +# RouterOS script import file +# Generated by sync-script.sh +# Date: $GEN_DATE +# Git: $GIT_STATUS + +RSC_HEADER + +# Write header for creating scripts section +printf ':put "=== Creating scripts ==="\n' >> "$RSC_FILE" +printf '\n' >> "$RSC_FILE" + +# Create function for script creation +printf ':global createScriptIfMissing do={\n' >> "$RSC_FILE" +printf ' :if ([/system script print count-only where name=$scriptName] = 0) do={\n' >> "$RSC_FILE" +printf ' :put ("Creating script: " . $scriptName);\n' >> "$RSC_FILE" +printf ' /system script add name=$scriptName\n' >> "$RSC_FILE" +printf ' }\n' >> "$RSC_FILE" +printf '}\n\n' >> "$RSC_FILE" + +# Write all add commands first +for SCRIPT_FILE in scripts/config/*.rsc scripts/check/*.rsc; do + if [ ! -f "$SCRIPT_FILE" ]; then + continue + fi + + SCRIPT_NAME=$(sed -n '1p' "$SCRIPT_FILE" | sed 's/^# //') + POLICY=$(sed -n '3p' "$SCRIPT_FILE" | sed -n 's/^# policy=\(.*\)/\1/p') + + if [ -z "$POLICY" ]; then + echo "Error: Missing policy in $SCRIPT_FILE (line 3 should be '# policy=read,write')" + exit 1 + fi + + # Call function with script name + printf '$createScriptIfMissing scriptName="%s"\n' "$SCRIPT_NAME" >> "$RSC_FILE" +done + +# Empty line between sections +printf '\n' >> "$RSC_FILE" +printf ':put ""\n' >> "$RSC_FILE" +printf ':put "=== Updating scripts ==="\n' >> "$RSC_FILE" +printf '\n' >> "$RSC_FILE" + +# Write all set commands +for SCRIPT_FILE in scripts/config/*.rsc scripts/check/*.rsc; do + if [ ! -f "$SCRIPT_FILE" ]; then + continue + fi + + SCRIPT_NAME=$(sed -n '1p' "$SCRIPT_FILE" | sed 's/^# //') + COMMENT=$(sed -n '2p' "$SCRIPT_FILE" | sed 's/^# //') + POLICY=$(sed -n '3p' "$SCRIPT_FILE" | sed -n 's/^# policy=\(.*\)/\1/p') + + # Escape comment for RouterOS (escape quotes) + ESCAPED_COMMENT=$(echo "$COMMENT" | sed 's/"/\\"/g') + + # Read script content and escape for RouterOS .rsc format + # Loop through file line by line, escape special chars, join with \n + SCRIPT_CONTENT="" + while IFS= read -r line || [ -n "$line" ]; do + # Escape backslashes, dollar signs, and quotes + line=$(echo "$line" | sed 's/\\/\\\\/g' | sed 's/\$/\\$/g' | sed 's/"/\\"/g') + if [ -z "$SCRIPT_CONTENT" ]; then + SCRIPT_CONTENT="$line" + else + SCRIPT_CONTENT="$SCRIPT_CONTENT\\n$line" + fi + done < "$SCRIPT_FILE" + + # Write set command directly to file + printf ':put "Updating script: %s"; /system script set "%s" source="' "$SCRIPT_NAME" "$SCRIPT_NAME" >> "$RSC_FILE" + echo "$SCRIPT_CONTENT" | sed 's/\\n/\\n\\\n /g' >> "$RSC_FILE" + printf '" comment="%s" policy=%s\n\n' "$ESCAPED_COMMENT" "$POLICY" >> "$RSC_FILE" +done + +# Delete the helper function +printf '\n:set createScriptIfMissing;\n' >> "$RSC_FILE" + +# Print all scripts (excluding source/contents) +printf ':put ""\n:put "=== All system scripts ==="\n/system script print proplist=name,comment,owner,policy,dont-require-permissions,run-count,last-started,invalid\n' >> "$RSC_FILE" + +# Show generated .rsc file and ask for confirmation +echo "" +echo "=== Generated import file ($RSC_FILE) ===" +head -20 "$RSC_FILE" +echo "..." +echo "" +read -p "Upload and import this file? (y/N): " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Aborted" + rm -f "$RSC_FILE" + exit 1 +fi + +# Upload .rsc file +echo "Uploading import file..." +scp $SSH_OPTS "$RSC_FILE" "$ROUTER_USER@$ROUTER_IP":/ + +# Import on router +echo "Importing scripts..." +ssh $SSH_OPTS "$ROUTER_USER@$ROUTER_IP" "/import file-name=$RSC_FILE" + +# Cleanup +rm -f "$RSC_FILE" +echo "Done!" diff --git a/bin/ros-diff.sh b/bin/ros-diff.sh new file mode 100755 index 0000000..be2c8c6 --- /dev/null +++ b/bin/ros-diff.sh @@ -0,0 +1,665 @@ +#!/bin/bash +#set +e -u +#o pipefail +# Add to cron +# crontab -e +#*/20 * * * * /var/www/ros.vados.ru/Mikrotiks/.bin/ros-diff.sh +#set +eo pipefail +#set -x +#GEN_DATE=$(date '+%Y-%m-%d %H:%M:%S %z') +#GEN_DATE_TIME=$(date '+%d.%m.%Y %T %Z') +# +#ASK_NEXT=true +#ask_forNext() { +# local ask $1 +# local item $2 +# echo -n $ask +#read item +#case "$item" in +# y|Y) echo "Enter «y», continue..." +# ;; +# n|N) echo "Enter «n», exit..." +# exit 0 +# ;; +# *) echo "Nothing was entered. We perform the default action..." +# ;; +#esac +#} +#${CMD_SSH} ${SSH_OPTS} ${SSHuser}@${SSHhost} system script run MkTmpfs; +# +#### Utils ############################################################################################# +CMD_FIND=$(which find) +CMD_MV=$(which mv) +CMD_GZ=$(which gzip) +CMD_CHO=$(which chown) +CMD_CHM=$(which chmod) +CMD_MKD=$(which mkdir)" -p " +CMD_RM=$(which rm) +CMD_DATE=$(date +%Y%m%d_%H%M) # date in format YYYYMMDD_HHmm +CMD_SSL=$(which openssl) +CMD_SSH=$(which ssh) +CMD_SCP=$(which scp) +CMD_SFTP=$(which sftp) + +ScriptName=$(basename -- "$0") +# HomeDir=$HOME +HomeDir="/var/www/ros.vados.ru/Mikrotiks" +HostsFile=${HomeDir}"/.config/.mikrotiks" +BinDir=${HomeDir}"/bin" +GitDir=${HomeDir}"/backups" + +# Set SSH defaults: +DEFAULT_SSH_PORT="22" +DEFAULT_SSH_USER="admin" +DEFAULT_CONNECT_ATTEMPTS=5 +DEFAULT_CONNECT_TIMEOUT=5 +DEFAULT_SSH_KEY=${HomeDir}"/.ssh/id_rsa" +# Set default diff args: +DEFAULT_DIFF_ARGS=("-I \"RouterOS\"") +# +# Set debug and log options: +DEBUG_OUT=true +SAVE_LOG=true +# Set default LogFile: +DEFAULT_LOG="/var/log/Mikrotiks/ros-diff.log" +# +# Default backup variables: +DEFAULT_BIN_CRYPT=true +DEFAULT_BINPWD="BinPwd123" +DEFAULT_EXP_CRYPT=false +DEFAULT_EXPPWD="ExpPwd321" + +# Handy tput commands: +#tput bold - Bold effect #'\033[1m' +#tput rev - Display inverse colors +#tput sgr0 - Reset everything #'\033[0m' +#tput setaf {CODE}- Set foreground color, see color {CODE} below +#tput setab {CODE}- Set background color, see color {CODE} below +# Colors: +#0 Black +#1 Red #'\033[1;31m' +#2 Green #'\033[1;32m' +#3 Yellow #'\033[1;33m' +#4 Blue # '\033[1;34m' +#5 Magenta # '\033[1;35m' +#6 Cyan # '\033[1;36m' +#7 White # '\033[1;37m' +if [ -t 1 ] && $DEBUG_OUT; then + reset=$(tput sgr0) + bold=$(tput bold) + red=$(tput setaf 1) + green=$(tput setaf 2) + yellow=$(tput setaf 3) + blue=$(tput setaf 4) + magenta=$(tput setaf 5) + cyan=$(tput setaf 6) + white=$(tput setaf 7) + toend=$(tput hpa $(tput cols))$(tput cub 6) +else + reset='' bold='' red='' green='' yellow='' blue='' magenta='' cyan='' white='' toend='' +fi + +info() { + echo -e "\n${blue}ℹ $*${reset}" +} +success() { + echo -e "\n${green}✅ $*${reset}" +} +error() { + echo -e "\n${red}❌ $*${reset}" >&2 +} +warning() { + echo -e "${yellow}⚠ $*${reset}" >&2 +} +section() { + echo -e "\n${magenta}................[$(tput rev) $* ${reset}${magenta}]................${reset}\n" +} + +FRAME=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏") +FRAME_INTERVAL=0.1 + +start() { + local step=0 + while [ "$step" -lt "${#CMDS[@]}" ]; do + ${CMDS[$step]} & pid=$! + while ps -p $pid &>/dev/null; do + echo -ne "\\r[ ] ${STEPS[$step]} ..." + for k in "${!FRAME[@]}"; do + echo -ne "\\r[ ${FRAME[k]} ]" + sleep $FRAME_INTERVAL + done + done + echo -ne "\\r[ ✔ ] ${STEPS[$step]}\\n" + step=$((step + 1)) + done +} +#echo '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏' +spinner() +{ + local pid=$! + local delay=0.75 + local spinstr='|/-\' + #'⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏' + while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do + local temp=${spinstr#?} + printf " [%c] " "${spinstr}" + local spinstr=$temp${spinstr%"$temp"} + sleep $delay + printf "\b\b\b\b\b\b" + done + printf " \b\b\b\b" +} + +save_log() { + local log="${DEFAULT_LOG}" + if [ -n "${LogFile}" ]; then + log="${LogFile}" + fi + if ${SAVE_LOG}; then + echo "$(date '+%b %d %T') - $*" >> ${log} + return 0 + else + return 1 + fi +} + +get_connections_str() { + local opts + local log_msg + local host + local ssh_str + local scp_str + +# Require router-specific SSH key + if [ -n "$DEFAULT_SSH_KEY" ]; then + opts=("-i ${DEFAULT_SSH_KEY}" "-o PasswordAuthentication=no") + else + log_msg="- Error: SSH key not found at $DEFAULT_SSH_KEY\nRun ./setup-ssh-keys.sh to generate the key" + if [ -t 1 ] && ${DEBUG_OUT}; then + error "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + exit 1 + fi +# if [ -n "$DEFAULT_CONNECT_ATTEMPTS" ]; then +# opts+=("-o ConnectionAttempts=${DEFAULT_CONNECT_ATTEMPTS}") +# fi +# if [ -n "$DEFAULT_CONNECT_TIMEOUT" ]; then +# opts+=("-o ConnectTimeout=${DEFAULT_CONNECT_TIMEOUT}") +# fi + #opts+=("-o PreferredAuthentications=publickey" "-o StrictHostKeyChecking=no" "-o UserKnownHostsFile=/dev/null" \ + #"-o GlobalKnownHostsFile=/dev/null" "-o CheckHostIP=no") +SSH_OPTS="${opts[*]}" + +# Require router host IP + if [ -n "${SSHhost}" ]; then + host="${SSHhost}" + else + log_msg="- Error! SSH Host not found. Exit 1." + if [ -t 1 ] && ${DEBUG_OUT}; then + error "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + exit 1 + fi + + ssh_str=("$CMD_SSH" "-2" "-4") + scp_str=("${CMD_SCP}" "-2" "-4" "-B ${SSH_OPTS}") + + if [ -n "${SSHport}" ]; then + ssh_str+=("-p ${SSHport}") + scp_str+=("-P ${SSHport}") + else + ssh_str+=("-p ${DEFAULT_SSH_PORT}") + scp_str+=("-P ${DEFAULT_SSH_PORT}") + fi + + if [ -n "${SSHuser}" ]; then + ssh_str+=("-l ${SSHuser}") + scp_str+=("${SSHuser}@${host}") + else + ssh_str+=("-l ${DEFAULT_SSH_USER}") + scp_str+=("${DEFAULT_SSH_USER}@${host}") + fi + + ssh_str+=("${host}") + +ssh_str+=("${SSH_OPTS}") +SSH_STR="${ssh_str[*]}" +SCP_STR="${scp_str[*]}" +#SFTP_STR="${sftp_str[*]}" +#SFTP_OPTS="-i ${DEFAULT_SSH_KEY} -o PasswordAuthentication=no -oPort=${SSHport}" +} + +#>/dev/null 2>&1 +############################### +# Backup listing +############################### +# Get Names Addresses and Ports in $HostsFile +#declare -rx STEPS=( +# 'download' +# 'check' +# 'backup' +#) +#IFS=$'\n' +run_ssh_cmd() { + local run="${1}" + warning "${run}" + if ${SSH_STR} ${run}; then + return 0 + else + return 1 + fi +} + +download_config() { + local conf="${1}" + local log_msg + + if ${SSH_STR} export >${conf}; then + log_msg="- Config download success!" + if [ -t 1 ] && $DEBUG_OUT; then + success "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + return 0 + else + log_msg="- Config download ${conf} error! Exit Error 1." + if [ -t 1 ] && $DEBUG_OUT; then + error "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + exit 1 + fi +} + +compare_config() { + local config_file="${1}" + local precedent_file="${2}" + local diff_file="${3}" + local diff_args=${DEFAULT_DIFF_ARGS} + local log_msg + + diff ${diff_args} ${config_file} ${precedent_file} >${diff_file} + if [ "$?" -ne "0" ]; then + log_msg="- There is a difference! Create backup..." + if [ -t 1 ] && $DEBUG_OUT; then + section " CREATE BACKUP " + sleep 1 + info "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + return 0 + else + log_msg="- The files are identical. No backup is required." + if [ -t 1 ] && $DEBUG_OUT; then + section " START CLEANUP " + sleep 1 + info "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + log_msg="- Remove ${diff_file} file." + if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + ${CMD_RM} -f ${diff_file} + log_msg="- Remove ${config_file} file." + if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + ${CMD_RM} -f ${config_file} + + return 1 + fi +} + +check_directory() { + local chk_dir="${1}" + local log_msg + + if [[ -d ${chk_dir} && -r ${chk_dir} ]] + then + return 0 + else + if $CMD_MKD ${chk_dir}; then + log_msg="- Direcory ${chk_dir} created." + if [ -t 1 ] && $DEBUG_OUT; then + success "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + return 0 + else + log_msg="- Error create direcory ${chk_dir}! Exit 1." + if [ -t 1 ] && $DEBUG_OUT; then + error "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + exit 1 + fi +# This script must be run by a special user in his home directory. +# Therefore, the following lines are not needed. +# $CMD_CHO root:root $dir +# $CMD_CHM 755 $ST_FULL + fi +} + +#${SSH_STR} /system script environment get [find name=BackupPassword] value; +#exit 0 +backup_binary() { + local bin_name="${1}" + local crypt="${2:-$DEFAULT_BIN_CRYPT}" + local bin_pass="${3:-$DEFAULT_BINPWD}" + local log_msg + local crypt_str + #${SSH_STR} :put [/system script environment get [find name=BackupPassword] value]; + + if ${SSH_STR} /system/script environment find where name=BackupEncrypt && ${SSH_STR} /system/script environment find where name=BackupPassword; then + + bin_pass=${SSH_STR} /system/script/environment/get ([ /system/script/environment find name='BackupPassword' ]->value); + crypt_str="dont-encrypt=no password=${bin_pass}" + warning "${crypt_str}" + else + if [ -n ${crypt} ] && [ -n {passwd} ]; then + crypt_str="dont-encrypt=no password=${passwd}" + else + crypt_str="dont-encrypt=yes" + fi + + fi + # if [ -n $]; then + +# local BKPSTR="system backup save name=${bin_name} dont-encrypt=no password=$BKP_BINPWD" +# T_BKPCLN="file remove [find name=$TGT_BKPNAME_BIN]" +} + +readarray -t lines < $HostsFile +#declare -r STEPS=($lines) +#declare -r MAX_STEPS=${#lines[@]} +#declare -r BAR_SIZE="##########" +#declare -r MAX_BAR_SIZE=${#BAR_SIZE} + +for HR in "${lines[@]}"; do +# perc=$(((HR + 1) * 100 / MAX_STEPS)) +# percBar=$((perc * MAX_BAR_SIZE / 100)) +# declare -rx CMDS=( +# "${CMD_SSH} ${SSH_OPTS} ${SSHuser}@${SSHhost} export >$current_config" +# 'sleep 10' +# 'sleep 1' +#) +while IFS=$' ' read -a HR ; do +#|| [ -n "$HR" ]; do +[[ -z ${HR[0]} ]] && continue + +DStamp=$(date '+%Y%m%d') +DTStamp=$(date '+%Y%m%d%H%M%S') + +RouterName=${HR[0]} +SSHhost=${HR[1]} +SSHport=${HR[2]} +SSHuser=${HR[3]} +SSHpassword=${HR[4]} + +get_connections_str +backup_binary "BinaryTest.backup" + +exit 0 +#warning "SSH_STR = ${SSH_STR}" +#warning "SCP_STR = ${SCP_STR}" +#exit 0 + +BaseDir=${HomeDir}"/backups/${RouterName}/" +TempDir=${BaseDir}"tmp/" +HistoryDir=${BaseDir}"history/" +LogFile="/var/log/Mikrotiks/${RouterName}.log" +log_msg="undefined" + +log_msg="- Start backup script ${ScriptName} for ${RouterName}" +if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" + echo +fi +save_log "${log_msg}" + +log_msg="- Check and creatre services directories for ${RouterName} if not exsist..." +if [ -t 1 ] && $DEBUG_OUT; then + section " CHECK DIRS " + info "${RouterName} ${log_msg}" +fi +save_log "${log_msg}" + +CheckDirs=("${BaseDir}" "${TempDir}" "${HistoryDir}") +for dir in "${CheckDirs[@]}"; do +(check_directory "${dir[@]}") +done + +log_msg="All Directories for ${RouterName} was created sucessfully!" +if [ -t 1 ] && $DEBUG_OUT; then + success "${log_msg}" +fi +save_log "- ${log_msg}" + +log_msg="Set variables for ${RouterName}..." +if [ -t 1 ] && $DEBUG_OUT; then + info "${log_msg}" +fi +save_log "- ${log_msg}" + +precedent_config=${BaseDir}"Precedent-Config.rsc" +current_config=${TempDir}"Config.rsc" +diff_config=${TempDir}"Diff-Config.rsc" +current_backup="Binary.backup" + +log_msg="Set variables for ${RouterName} success!" +if [ -t 1 ] && $DEBUG_OUT; then + success "${log_msg}" +fi +save_log "- ${log_msg}" + +section " CHECK CONFIG " +log_msg="- Download ${current_config} file to Temp Directory..." +if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" +fi +save_log "- ${log_msg}" + +download_config "${current_config}" + +log_msg="- Comparing with the previous config..." +if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" +fi +save_log "- ${log_msg}" + +if compare_config ${current_config} ${precedent_config} ${diff_config} ${RouterName} ${LogFile}; then + BackupDir=${BaseDir}"${DStamp}/" + ${CMD_MKD} ${BackupDir} + + save_config=${BackupDir}"${DTStamp}-Config.rsc" + save_backup=${BackupDir}"${DTStamp}-Binary.backup" + + log_msg="- Copy ${current_config} file to ${BackupDir} directory..." + if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" + fi + save_log "- ${log_msg}" + + cp ${current_config} ${save_config} + + ${CMD_RM} -f ${precedent_config} + + ${CMD_MV} -f ${current_config} ${precedent_config} + + log_msg="- Copy configuration to ${BackupDir}/${save_config} and ${precedent_config} success." + if [ -t 1 ] && $DEBUG_OUT; then + success "${RouterName} ${log_msg}" + fi + save_log "- ${log_msg}" + + log_msg="Create ${current_backup} file on ${RouterName}..." + if [ -t 1 ] && $DEBUG_OUT; then + info "${log_msg}" + fi + save_log "- ${log_msg}" +# if [ $? -eq 0 ]; then + if ${SSH_STR} system backup save name=${current_backup}; then + log_msg="Create binary backup ${current_backup} on ${RouterName} success." + if [ -t 1 ] && $DEBUG_OUT; then + success "${log_msg}" + fi + save_log "- ${log_msg}" + + log_msg="- Start download ${current_backup} file to ${BackupDir}..." + if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" + fi + save_log "- ${log_msg}" + +# if ${SFTP_STR}:$current_backup; then + # ${CMD_SFTP} ${SFTP_OPTS} ${SSHuser}@${SSHhost}:$current_backup + if ${SCP_STR}:/${current_backup} ${save_backup}; then + sleep 2 + log_msg="- Binary Backup download complete!" + if [ -t 1 ] && $DEBUG_OUT; then + success "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + else + log_msg="- Error! Save binary backup on ${RoutrName} failed!" + if [ -t 1 ] && $DEBUG_OUT; then + error "${log_msg}" + fi + save_log "${log_msg}" + fi + else + log_msg="Error create binary backup ${current_backup} on ${RouterName}!" + if [ -t 1 ] && $DEBUG_OUT; then + error "${log_msg}" + fi + save_log "- ${log_msg}" + fi + + log_msg="- Remove ${current_backup} file on ${RouterName}." + if [ -t 1 ] && $DEBUG_OUT; then + section "CLEANUP" + info "${log_msg}" + fi + save_log "- ${log_msg}" + + if ${SSH_STR} /file remove ${current_backup}; then + log_msg="- Remove ${current_backup} file on ${RouterName} complete succesfully!" + if [ -t 1 ] && $DEBUG_OUT; then + success "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + else + log_msg="- Error Remove ${current_backup} file on ${RouterName}!" + if [ -t 1 ] && $DEBUG_OUT; then + error "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + fi + + cd "${BaseDir}" + + CurrentHistoryDir=${HistoryDir}"${DStamp}/" + ${CMD_MKD} -p ${CurrentHistoryDir} + diff_config_history=${CurrentHistoryDir}"${DTStamp}-Diff-Config.rsc" + log_msg="- Move ${diff_config} file to ${CurrentHistoryDir}." + if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + + if ${CMD_MV} -f ${diff_config} ${diff_config_history}; then + log_msg="- Move ${diff_config} file to ${CurrentHistoryDir} complete succesfully!" + if [ -t 1 ] && $DEBUG_OUT; then + success "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + else + log_msg="- Error move ${diff_config} file to ${CurrentHistoryDir}!" + if [ -t 1 ] && $DEBUG_OUT; then + error "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + fi + + log_msg="- Go to Git directory (${GitDir}), add backups files and commit him." + if [ -t 1 ] && $DEBUG_OUT; then + section " COMMIT " + info "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + cd "${GitDir}/" + git add . + log_msg="- Git add commit..." + if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + if git commit -m "Backup for ${RouterName} sucessfully creatd at $(date '+%b %d %T')."; then + log_msg=" - Git add commit success." + if [ -t 1 ] && $DEBUG_OUT; then + success "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + else + log_msg="- Git add commit Error!" + if [ -t 1 ] && $DEBUG_OUT; then + error "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + fi + log_msg="- Git push commit..." + if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + if git push origin main; then + log_msg=" - Git push commit success." + if [ -t 1 ] && $DEBUG_OUT; then + success "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + else + log_msg="- Git push commit Error!" + if [ -t 1 ] && $DEBUG_OUT; then + error "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" + fi +else + log_msg="- ${RouterName} backup complete!" + if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" + fi + save_log "${log_msg}" +fi + +log_msg="- Remove Temp directory." +if [ -t 1 ] && $DEBUG_OUT; then + info "${RouterName} ${log_msg}" +fi + save_log "${log_msg}" + +${CMD_RM} -d ${TempDir} +log_msg="- backup complete!" +if [ -t 1 ] && $DEBUG_OUT; then + success "${RouterName} ${log_msg}" +fi +save_log "${log_msg}" + +done <<<"$(echo -e $HR)" +LogFile="${DEFAULT_LOG}" +# echo -ne "\\r[${BAR_SIZE:0:percBar}] $perc %" +#echo "[] $perc %" +done +log_msg="All Done! Exit 0." +if [ -t 1 ] && $DEBUG_OUT; then + section " DONE " + success "${log_msg}" +fi +save_log "${log_msg}" +exit 0 diff --git a/bin/scripts/mktmpfs.rsc b/bin/scripts/mktmpfs.rsc new file mode 100644 index 0000000..dbe979c --- /dev/null +++ b/bin/scripts/mktmpfs.rsc @@ -0,0 +1,3 @@ +:global MkDir; +:put [($MkDir /usb1/tmpfs)]; +:log warning ("\$MkDir = " . $MkDir . "."); diff --git a/bin/test.sh b/bin/test.sh new file mode 100644 index 0000000..67b9dd5 --- /dev/null +++ b/bin/test.sh @@ -0,0 +1,237 @@ +#!/bin/bash +# Add to cron +# crontab -e +#*/20 * * * * /var/www/ros.vados.ru/Mikrotiks/.bin/ros-diff.sh +#set +eo pipefail +#set -x +# +DEBUG_OUT=true +if [ -t 1 ] && $DEBUG_OUT; then + reset='\033[0m' + bold=$(tput bold) + #'\033[1m' + red=$(tput setaf 7)$(tput setab 1) + #'\033[1;31m' + green=$(tput setaf 4)$(tput setab 7)$(tput bold) + #'\033[1;32m' + yellow='\033[1;33m' + blue='\033[1;34m' + magenta='\033[1;35m' + cyan='\033[1;36m' + white='\033[1;37m' +else + reset='' bold='' red='' green='' yellow='' blue='' cyan='' magenta='' white='' +fi + +info() { + if $DEBUG_OUT; then + echo -e "${blue}ℹ $*${reset}" + fi +} +success() { + if $DEBUG_OUT; then + echo -e "${bold}${green}✅ $*${reset}" + fi +} +error() { + if $DEBUG_OUT; then + echo -e "${red}❌ Error: $*${reset}" >&2 + fi +} +warning() { + if $DEBUG_OUT; then + echo -e "${yellow}⚠ $*${reset}" >&2 + fi +} +section() { + if $DEBUG_OUT; then + echo -e "\n${magenta}====$*====${reset}" + fi +} +toend=$(tput hpa $(tput cols))$(tput cub 6) +toend_ok() { + if $DEBUG_OUT; then + echo -n "${toend}${white}[${green}OK${white}]" + fi +} +toend_error() { + if $DEBUG_OUT; then + echo -n "${toend}${white}[${red}ERROR${white}]" + fi +} +BR() { + if $DEBUG_OUT; then + echo -e "\n" + fi +} + +error "error" +success "success" +exit 0 + +# HomeDir=$HOME +HomeDir="/var/www/ros.vados.ru/Mikrotiks" +HostsFile=${HomeDir}"/.config/.mikrotiks" +BinDir=${HomeDir}"/.bin" +GitDir=${HomeDir}"/backups" + +SSH_KEY=${HomeDir}"/.ssh/id_rsa" +# Require router-specific SSH key +if [ ! -f "$SSH_KEY" ]; then + error "Error: SSH key not found at $SSH_KEY" + error "Run ./setup-ssh-keys.sh to generate the key" + exit 1 +fi + +############################### +# Backup listing +############################### +# Get Names Addresses and Ports in $HostsFile + +readarray -t lines < $HostsFile + +for HR in "${lines[@]}"; do +while IFS=$' ' read -a HR ; do +#|| [ -n "$HR" ]; do +[[ -z ${HR[0]} ]] && continue + +#GEN_DATE=$(date '+%Y-%m-%d %H:%M:%S %z') +GEN_DATE=$(date '+%d.%m.%Y') +GEN_TIME=$(date '+%b %d %T') +GEN_DATE_TIME=$(date '+%d.%m.%Y %T %Z') +DStamp=$(date '+%Y%m%d') + +RouterName=${HR[0]} +SSHhost=${HR[1]} +SSHport=${HR[2]} +SSHuser=${HR[3]} +SSHpassword=${HR[4]} + +BaseDir=${HomeDir}"/backups/"${RouterName} +TempDir=${BaseDir}"/tmp" +HistoryDir=${BaseDir}"/history" +LogFile="/var/log/Mikrotiks/"${RouterName}".log" + +SSH_OPTS="-i $SSH_KEY -o PasswordAuthentication=no -p ${SSHport}" +SFTP_OPTS="-i $SSH_KEY -o PasswordAuthentication=no -oPort=${SSHport}" +echo "${GEN_DATE_TIME} - Start backup script ${ARGV[0]} for ${RouterName}" >> ${LogFile} +section "Create dirs" +info "Create servise directories for ${RouterName}..." +echo "${GEN_TIME} - Create services directories for ${RouterName}..." >> ${LogFile} +mkdir -p ${BaseDir} +mkdir -p ${TempDir} +mkdir -p ${HistoryDir} +echo "${GEN_TIME} - All Directories for ${RouterName} was created sucessfully!" >> ${LogFile} +success "All directories for ${RouterName} was created sucessfully!" +echo "${GEN_TIME} - Set variables for ${RouterName}..." >> ${LogFile} +info "Set variables for ${RouterName}..." +precedent_config=${BaseDir}"/Precedent-Config.rsc" +current_config="Config.rsc" +current_backup="Binary.backup" +diff_config=${TempDir}"/Diff-Config.rsc" +echo "${GEN_TIME} - Set variables for ${RouterName} success!" >> ${LogFile} +success "Set variables for ${RouterName} success!" +#ssh ${SSH_OPTS} ${SSHuser}@${SSHhost} system script run MkTmpfs; +cd ${TempDir} +section "" +BR +section "Start checkout process" +info "Download ${current_config} file to Temp Directory..." +echo "${GEN_TIME} - Download ${current_config} file to ${TempDir}" >> ${LogFile} +ssh ${SSH_OPTS} ${SSHuser}@${SSHhost} export >$current_config +if [ $? -eq 0 ]; then +echo +toend_ok +echo +echo "${GEN_TIME} - Download complete!" >> ${LogFile} +else +echo +toend_error +echo +echo "${GEN_TIME} - Download ${current_config} failed!" >> ${LogFile} +exit 1 +fi +info "Comparing with the previous config..." +echo "${GEN_TIME} - Comparing with the previous config..." >> ${LogFile} +diff -I "RouterOS" ${current_config} ${precedent_config} >${diff_config} +if [ "$?" -ne "0" ]; then +echo "${GEN_TIME} - There is a difference! Create backup..." >> ${LogFile} +section "Create backup for ${RouterName}" +BackupDir=${BaseDir}"/"${DStamp} +mkdir -p ${BackupDir} +DTStamp=$(date '+%Y%m%d%H%M%S') +save_config=${DTStamp}"-Config.rsc" +save_backup=${DTStamp}"-Binary.backup" +diff_config_history=${DTStamp}"-Diff-Config.rsc" +echo "${GEN_TIME} - Copy ${current_config} file to ${BackupDir} directory..." >> ${LogFile} +cd ${TempDir} +rm -f ${precedent_config} +cp ${current_config} ${BackupDir}"/"${save_config} +mv -f ${current_config} ${precedent_config} +echo "${GEN_TIME} - Copy configuration to ${BackupDir}/${save_config} and ${precedent_config} success." >> ${LogFile} +success "Copy configuration to ${BackupDir}/${save_config} and ${precedent_config} success." +info "Create ${current_backup} file on ${RouterName}..." +echo "${GEN_TIME} - Create ${current_backup} file on ${RouterName}..." >> ${LogFile} +ssh ${SSH_OPTS} ${SSHuser}@${SSHhost} system backup save name=${current_backup} +if [ $? -eq 0 ]; then +echo +toend_ok +echo +echo "${GEN_TIME} - Create binary backup ${current_backup} on ${RouterName} success." >> ${LogFile} +info "Start download ${current_backup} file to ${BackupDir}..." +echo "${GEN_TIME} - Start download ${current_backup} file to ${BackupDir}..." >> ${LogFile} +sftp ${SFTP_OPTS} ${SSHuser}@${SSHhost}:$current_backup +sleep 1 +success "Download complete!" +echo "${GEN_TIME} - Download complete!" >> ${LogFile} +cd ${BackupDir} +sleep 2 +mv -f ${TempDir}"/"${current_backup} ${save_backup} +echo "${GEN_TIME} - Remove ${current_backup} file on ${RouterName}." >> ${LogFile} +ssh ${SSH_OPTS} ${SSHuser}@${SSHhost} /file remove ${current_backup} +else +echo +toend_error +echo +echo "${GEN_TIME} - Create binary backup ${current_backup} failed!" >> ${LogFile} +ssh ${SSH_OPTS} ${SSHuser}@${SSHhost} /file remove $current_backup +exit 1 +fi +cd ${TempDir} +CurrentHistoryDir=${HistoryDir}"/"${DStamp} +mkdir -p ${CurrentHistoryDir} +echo "${GEN_TIME} - Move ${diff_config} file to ${CurrentHistoryDir}." >> ${LogFile} +mv -f ${diff_config} ${CurrentHistoryDir}"/"${diff_config_history} +echo "${GEN_TIME} - Move ${diff_config} file to ${CurrentHistoryDir} complete." >> ${LogFile} +echo "${GEN_TIME} - Go to Git directory (${GitDir}), add backups files and commit him." >> ${LogFile} +rm -d ${TempDir} +cd ${GitDir} +git add . +echo "${GEN_TIME} - Git add commit..." >> ${LogFile} +git commit -m "Backup for ${RouterName} sucessfully creatd at ${GEN_TIME}." +echo "${GEN_TIME} - Done." >> ${LogFile} +echo "${GEN_TIME} - Git push..." >> ${LogFile} +git push origin main +echo "${GEN_TIME} - Done." >> ${LogFile} +echo "${GEN_TIME} - ${RouterName} backup complete!" >> ${LogFile} +success "${RouterName} backup complete!" +fi +section "The files are identical. No backup is required." +echo "${GEN_TIME} - The files are identical. No backup is required." >> ${LogFile} +echo "${GEN_TIME} - Remove ${diff_config} file." >> ${LogFile} +info "Remove ${diff_config} file." +rm -f ${diff_config} +echo "${GEN_TIME} - Remove ${current_config} file." >> ${LogFile} +info "Remove ${current_config} file." +rm -f ${current_config} +echo "${GEN_TIME} - Remove Temp directory." >> ${LogFile} +info "Remove Temp directory." +rm -d ${TempDir} +section "" +success "${RouterName} backup complete!" +echo "${GEN_TIME} - ${RouterName} backup complete!" >> ${LogFile} +done <<<"$(echo -e $HR)" +done +section "All Done!" +echo "All Done!" >> ${LogFile} +exit 0