📜 ⬆️ ⬇️

Centralized package update system in Ubuntu

Hello,

What to do if analogs are paid or not adapted to our conditions? Of course, write yourself.

Condition:


Task:

  1. Obtaining information about the availability of update packages on remote client stations.
  2. Logging versions of packages available for update.
  3. Remote update of one / all client stations.

Solution options:


Since my knowledge is limited to one programming language, bash, it will be implemented on it.
What we need:

How it will work:
ssh adm @ IP -> collect the necessary information -> write to the log on the server -> exit.
')
How it looks in practice:

When you start the program displays information about users and available packages for updating. There is a possibility of manual control through the menu. Ps real names and IP replaced for anonymity . The following is an example of the first paragraph:

Brief information about the system, the list of packages available for updating.
Examples of log files created by the program can be downloaded here.

Implementation:
/ root / uuman - program root folder.
../uuman/log is a folder with log files (also known as a network balloon).
../../log/.menu_log is a hidden folder with brief information about the remote machine.
setup - initial setup file of remote machines.
#!/usr/bin/expect -f set IP $argv #   set timeout -1 #     spawn ssh-copy-id -i /root/.ssh/id_rsa.pub adm@$IP expect -re "(yes/no)" # YES send "yes\r" #    expect -re "Password:" #  send "YOU_PASSWORD\r" #   expect -re "expecting." #  ssh spawn ssh adm@$IP expect -re "\\$ $" #  sudo  send "sudo -K\r" expect -re "\\$ $" # root send "sudo su\r" expect -re "password for" send "YOU_SUDO_PASSWORD\r" expect -re "# $" #  (  samba    nfs-common  cifs-utils) send "apt-get install -y apt-show-versions nfs-common\r" expect -re "# $" send "exit\r" expect -re "\\$ $" exit 0 

update - file for collecting information about available packages.
 #!/usr/bin/expect -f set IP [lrange $argv 0 0] set USERN [lrange $argv 1 1] set DATES [exec date "+%Y.%m.%d/%H:%M:%S"] #  ssh (adm    ) spawn ssh adm@$IP #   $ expect -re "\\$ $" #     sudo send "sudo -K\r" expect -re "\\$ $" # root send "sudo su\r" expect -re "password for" send "YOU_SUDO_PASSWORD\r" #   # expect -re "# $" #  ,    send "mkdir -m 777 /tmp/share > /dev/null 2>&1\r" expect -re "# $" # nfs  ( samba    ) send "mount.nfs 192.168.0.1:/root/uuman/log /tmp/share\r" expect -re "# $" #    send "date > /tmp/share/$IP.log\r" expect -re "# $" # ,      send "uname -a >> /tmp/share/$IP.log\r" expect -re "# $" #    send "echo Username:$USERN >> /tmp/share/$IP.log\r" expect -re "# $" #IP   send "echo IP:$IP >> /tmp/share/$IP.log\r" expect -re "# $" #    send "(echo -n Hostname:;hostname) >> /tmp/share/$IP.log\r" expect -re "# $" # Ubuntu   send "(cat /etc/issue.net) >> /tmp/share/$IP.log\r" expect -re "# $" #           send "(echo -n Count of packages for update:;apt-show-versions -u | wc -l) >> /tmp/share/$IP.log\r" expect -re "# $" #  send "echo >> /tmp/share/$IP.log\r" expect -re "# $" #       send "apt-show-versions -u | column -t >> /tmp/share/$IP.log\r" expect -re "# $" #     (  | IP | ubuntu_version | -  |  ) send "(echo -n $USERN;echo -n ' |' $IP '| ';cat /etc/issue.net | sed 's/ /_/g';echo -n AvailableUpdates\:;apt-show-versions -u | wc -l ;echo -n $DATES) > /tmp/share/.menu_log/$IP.log\r" expect -re "# $" #  send "umount -f /tmp/share\r" expect -re "# $" #  root send "history -c\r" expect -re "# $" #  root send "exit\r" expect -re "\\$ $" exit 0 

package - a file for updating client machines.
 #!/usr/bin/expect -f set IP [lrange $argv 0 0] set USERN [lrange $argv 1 1] set DATES [exec date "+%Y.%m.%d/%H:%M:%S"] #    set timeout -1 spawn ssh adm@$IP expect -re "\\$ $" send "sudo -K\r" expect -re "\\$ $" send "sudo su\r" expect -re "password for" send "YOU_SUDO_PASSWORD\r" expect -re "# $" #  send "apt-get -y upgrade\r" expect -re "# $" #    send "mkdir -m 777 /tmp/share > /dev/null 2>&1\r" expect -re "# $" send "mount.nfs 192.168.0.1:/root/uuman/log /tmp/share\r" expect -re "# $" send "date > /tmp/share/$IP.log\r" expect -re "# $" send "uname -a >> /tmp/share/$IP.log\r" expect -re "# $" send "echo IP:$IP >> /tmp/share/$IP.log\r" expect -re "# $" send "(echo -n Hostname:;hostname) >> /tmp/share/$IP.log\r" expect -re "# $" send "(cat /etc/issue.net) >> /tmp/share/$IP.log\r" expect -re "# $" send "(echo -n Count of packages for update:;apt-show-versions -u | wc -l) >> /tmp/share/$IP.log\r" expect -re "# $" send "echo >> /tmp/share/$IP.log\r" expect -re "# $" send "apt-show-versions -u | column -t >> /tmp/share/$IP.log\r" expect -re "# $" send "(echo -n $USERN;echo -n ' |' $IP '| ';cat /etc/issue.net | sed 's/ /_/g';echo -n AvailableUpdates\:;apt-show-versions -u | wc -l ;echo -n $DATES) > /tmp/share/.menu_log/$IP.log\r" expect -re "# $" send "umount /tmp/share\r" expect -re "# $" send "apt-get -y upgrade\r" expect -re "# $" send "history -c\r" expect -re "# $" send "exit\r" expect -re "\\$ $" exit 0 

uuman.sh - startup file (main file).
 #!/bin/bash #   DATE=`date "+%Y.%m.%d/%H:%M:%S"` #   LOCAL="/root/uuman/log" #   WORKD="/root/uuman" #[\]  spinner() { local pid=$1 local delay=0.25 while [ $(ps -eo pid | grep $pid) ]; do for i in \| / - \\; do printf ' [%c]\b\b\b\b' $i sleep $delay done done printf '\b\b\b\b' } #      UPDATEA() { #2012_11_23 DATEFN=`date "+%Y_%m_%d"` #     .     nfs chown -R nfsnobody:nfsnobody $LOCAL i=0 #    cat $WORKD/ip.txt | while read line; do USERN=`echo $line` # IP   IP=`echo $line | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'` #  if ping -c 1 -s 1 -W 1 $IP > /dev/null 2>&1; then i=`expr $i + 1` #    screen screen -A -m -d -S "upd$i" expect $WORKD/update $IP $USERN #     #screen -A -m -d -S "upd$i" expect $WORKD/setup $IP else #         #    echo "$DATE" >> $LOCAL/err.txt echo "$USERN - not connected" >> $LOCAL/err.txt echo >> $LOCAL/err.txt #    echo "$DATE | $USERN - not connected" >> $LOCAL/upd.txt echo >> $LOCAL/upd.txt #     echo "$DATE | $USERN - not connected" >> $LOCAL/UPD-$DATEFN.txt echo >> $LOCAL/UPD-$DATEFN.txt #  -   ,    not connected   NT=`cat $LOCAL/.menu_log/$IP.log | grep "AvailableUpdates"` if [ -z "$NT" ]; then echo -n "$USERN | Unknown | NotConnected | $DATE" > $LOCAL/.menu_log/$IP.log fi fi done #      ls $LOCAL | grep .log | while read TXT; do paste $LOCAL/$TXT >> $LOCAL/upd.txt echo >> $LOCAL/upd.txt #     paste $LOCAL/$TXT >> $LOCAL/UPD-$DATEFN.txt echo >> $LOCAL/UPD-$DATEFN.txt done } #     PACKAGEA() { #2012_11_23 DATEFN=`date "+%Y_%m_%d"` #     .     nfs chown -R nfsnobody:nfsnobody $LOCAL i=0 #    cat $WORKD/ip.txt | while read line; do USERN=`echo $line` # IP   IP=`echo $line | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'` #  if ping -c 1 -s 1 -W 1 $IP > /dev/null 2>&1; then i=`expr $i + 1` #    screen screen -A -m -d -S "upd$i" expect $WORKD/package $IP $USERN else #         #    echo "$DATE" >> $LOCAL/err.txt echo "$USERN - not connected" >> $LOCAL/err.txt echo >> $LOCAL/err.txt #    echo "$DATE | $USERN - not connected" >> $LOCAL/upd.txt echo >> $LOCAL/upd.txt #     echo "$DATE | $USERN - not connected" >> $LOCAL/UPD-$DATEFN.txt echo >> $LOCAL/UPD-$DATEFN.txt #  -   ,    not connected   NT=`cat $LOCAL/.menu_log/$IP.log | grep "AvailableUpdates"` if [ -z "$NT" ]; then echo -n "$USERN | Unknown | NotConnected | $DATE" > $LOCAL/.menu_log/$IP.log fi fi done #      ls $LOCAL | grep .log | while read TXT; do paste $LOCAL/$TXT >> $LOCAL/upd.txt echo >> $LOCAL/upd.txt #     paste $LOCAL/$TXT >> $LOCAL/UPD-$DATEFN.txt echo >> $LOCAL/UPD-$DATEFN.txt done } #   -   () MAIN() { rm -rf $LOCAL/MENU.txt ls $LOCAL/.menu_log | grep .log | while read MENU; do #    (    ) TEXT=`paste -s -d '|' $LOCAL/.menu_log/$MENU | sed 's/|/ | /g;s/-/|/g'` echo $TEXT >> $LOCAL/MENU.txt done #      clear && cat $LOCAL/MENU.txt | column -t } #  MENU() { echo echo "1.Get update-information for Ubuntu-host (by custom IP-address)" echo "2.Get update-information for all Ubuntu-hosts (uses file with IP-addresses)" echo "3.Update packages for Ubuntu-host (by custom IP-address)" echo "4.Update packages for all hosts (uses file with IP-addresses)" echo "5.View error-connection log" echo "6.Refresh" echo "7.Exit" read SELECT case $SELECT in 1) #   IP echo -n "Enter IP:" read IP #     .     nfs chown -R nfsnobody:nfsnobody $LOCAL #   if ping -c 1 -s 1 -W 1 $IP > /dev/null 2>&1; then #   IP     USERN=`cat $WORKD/ip.txt | grep "$IP" | sed 's/ .*//'` $WORKD/update $IP $USERN > /dev/null 2>&1 & spinner $! cat $LOCAL/$IP.log else #      echo "Computer is not online" echo "$DATE" >> $LOCAL/err.txt echo "$IP - not connected" >> $LOCAL/err.txt echo >> $LOCAL/err.txt fi MENU ;; 2) #     UPDATEA > /dev/null 2>&1 & spinner $! #      ,       #sleep 5s MAIN MENU ;; 3) #  IP echo "Enter IP:" read IP #     .     nfs chown -R nfsnobody:nfsnobody $LOCAL if ping -c 1 -s 1 -W 1 $IP > /dev/null 2>&1; then #   IP     USERN=`cat $WORKD/ip.txt | grep "$IP" | sed 's/ .*//'` $WORKD/package $IP $USERN > /dev/null 2>&1 & spinner $! cat $LOCAL/$IP.log else echo "Computer is not online" echo "$DATE" >> $LOCAL/err.txt echo "$IP - not connected" >> $LOCAL/err.txt echo >> $LOCAL/err.txt fi MENU ;; 4) #   PACKAGEA > /dev/null 2>&1 & spinner $! #      ,       #sleep 5s MAIN MENU ;; 5) #   cat $LOCAL/err.txt MENU ;; 6) # MAIN MENU ;; 7) exit 0 ;; *) MENU esac } #    #  ARG=$1 case $ARG in #     check) UPDATEA exit 0 ;; #   update) PACKAGEA exit 0 ;; *) MAIN MENU ;; esac 

ip.txt - database containing User - IP.
User1 - 192.168.0.1
User2 - 192.168.0.2
User3 - 192.168.0.3
User4 - 192.168.0.4


How to use:
If you used your paths, correct the following variables in uuman.sh:
 #   LOCAL="/root/uuman/log" #   WORKD="/root/uuman" 

The setup script will install the necessary packages for running the program on client stations. To use the script, in the uuman.sh file, comment out the line:
 screen -A -m -d -S "upd$i" expect $WORKD/update $IP $USERN 
And uncomment:
 #screen -A -m -d -S "upd$i" expect $WORKD/setup $IP 

Auto mode:
$WORKD/uuman.sh check - check client stations from the ip.txt file for availability of updates.
$WORKD/uuman.sh update - update client stations available from the ip.txt file.

Total:

We receive a client-server system that allows us to automatically, manually or manually receive, store and process information about the relevance of installed programs, security packages and, if necessary, update on client stations running Ubuntu Linux.

UPD:
Authorization now by ssh-key.
We generate the key
 ssh-keygen -t rsa 

Using the setup file, we place it on the client stations.

Source: https://habr.com/ru/post/160579/


All Articles