System Administration & Network Administration
linux networking centos bash scripting
Updated Fri, 20 May 2022 11:22:43 GMT

CentOS 7: Getting interface IP numbers


I am trying to autopopulate the /etc/issue in a CentOS 7 image (this will be a template, and it needs to be easy to identify the resultant VMs at a glance).

I have the following in my /sbin/ifup-local:

#!/bin/bash
cd /etc ;
unlink ./issue ;
sleep 1 ;
issue_original="$(cat ./issue-original)" ;
show_ip="$(ip addr show |awk '$1=="inet" && $2 !~ /^127/ {print "\t"$2}')" ;
co -l ./issue ;
echo -e "${issue_original}\n\n\tCurrent IP Numbers:\n\t===================\n${show_ip}\n" >./issue ;
ci -m -u ./issue ;

The /etc/issue-original looks like:

Logging into:
        Node: \\n
        Running: \\S

When I run the script by hand (sudo /sbin/ifup-local ; cat /etc/issue), it populates the /etc/issue correctly. When this is run automatically (such as when it is a result of sudo service network restart ; cat /etc/issue), the file-template and static text are there, but the IP numbers are empty (not even empty lines).

Am I misunderstanding the order of execution (is ifup-local executed before the IP numbers are assigned)? It looks like this is at the very end of the /etc/sysconfig/network-scripts/ifup-post, so I would assume it is after DHCP client has set the interfaces.

Is there a delay between when the interface IP numbers are set and when the "ip" command knows about them? The "sleep" statement is in there because I thought it might be the case.

Any pointers in the right direction are greatly appreciated.

Happy Sunday!

==========================

Edit:

Here is what I saw in /etc/issue after restarting the network service.

[david@localhost ~]$ sudo service network restart
Restarting network (via systemctl):                        [  OK  ]
[david@localhost ~]$ cat /etc/issue
Logging into:
        Node: \n
        Running: \S
        Current IP Numbers:
        ===================
[david@localhost ~]$

Additionally, I have instrumented the script with copious debugging messages, to find where things are and are not working. Here is what was logged on the last run (I truncated the log before the run, to remove extraneous information).

[david@localhost conf.d]$ clear
[david@localhost conf.d]$ >/tmp/ifup-local.log
[david@localhost conf.d]$ tail -f /tmp/ifup-local.log
--------------------------------------------------
2014-10-01 18:50:0808   DEBUG:  PATH: /usr/sbin/:/usr/bin/:/sbin:/usr/sbin:/bin:/usr/bin
2014-10-01 18:50:0808   DEBUG:  PWD: /etc
2014-10-01 18:50:0808   DEBUG:  issue file exists
2014-10-01 18:50:0808   DEBUG:  Removing old issue file
2014-10-01 18:50:0808   DEBUG:  issue_original:
 Logging into: Node: \n Running: \S
2014-10-01 18:50:0808   DEBUG:  about to check the IP numbers
2014-10-01 18:50:0808   DEBUG:  0
2014-10-01 18:50:0909   DEBUG:  show_ip:
2014-10-01 18:50:0909   DEBUG:  checking out issue file to lock it
2014-10-01 18:50:0909   DEBUG:  new_issue:
 Logging into: Node: \n Running: \S
        Current IP Numbers:
        ===================
2014-10-01 18:50:0909   DEBUG:  issue file exists
2014-10-01 18:50:0909   DEBUG:  checked back in issue file
--------------------------------------------------
2014-10-01 18:50:0909   DEBUG:  PATH: /usr/sbin/:/usr/bin/:/sbin:/usr/sbin:/bin:/usr/bin
2014-10-01 18:50:0909   DEBUG:  PWD: /etc
2014-10-01 18:50:0909   DEBUG:  issue file exists
2014-10-01 18:50:0909   DEBUG:  Removing old issue file
2014-10-01 18:50:0909   DEBUG:  issue_original:
 Logging into: Node: \n Running: \S
2014-10-01 18:50:0909   DEBUG:  about to check the IP numbers
2014-10-01 18:50:0909   DEBUG:  0
2014-10-01 18:50:0909   DEBUG:  show_ip:
2014-10-01 18:50:0909   DEBUG:  checking out issue file to lock it
2014-10-01 18:50:0909   DEBUG:  new_issue:
 Logging into: Node: \n Running: \S
        Current IP Numbers:
        ===================
2014-10-01 18:50:0909   DEBUG:  issue file exists
2014-10-01 18:50:0909   DEBUG:  checked back in issue file

Here is the revised script, with all of the debugging messages:

#!/bin/bash
function write-debug() {
        msg="$(date +'%Y-%m-%d %H:%M:%S%S')\tDEBUG:\t$1\n" ;
        echo -e ${msg}  >>${LOGFILE} ;
}
################################################
################################################
set -x ;
export LOGFILE='/tmp/ifup-local.log' ;
export PATH="/usr/sbin/:/usr/bin/:${PATH}" ;
echo -e "\n--------------------------------------------------\n" >>${LOGFILE} ;
write-debug "PATH: ${PATH}" ;
cd /etc ;
write-debug "PWD: $(pwd)" ;
[[ -a ./issue ]] && write-debug "issue file exists" || write-debug "no existing issue file" ;
write-debug "Removing old issue file" ;
[[ -a ./issue ]] && unlink ./issue || write-debug "no issue file to remove" ;
issue_original="$(cat ./issue-original)" ;
write-debug "issue_original:\n${issue_original}" ;
write-debug "about to check the IP numbers" ;
show_ip="$(ip addr show |awk '$1=="inet" && $2 !~ /^127/ {print "\t"$2}')" ;
#show_ip="$(ip addr show |fgrep 'inet ')" ;
write-debug $? ;
write-debug "show_ip:\n ${show_ip}" ;
write-debug "checking out issue file to lock it" ;
[[ -a ./issue ]] && write-debug "issue file exists" || "no existing issue file" ;
co -l ./issue ;
export new_issue="${issue_original}\n\n\tCurrent IP Numbers:\n\t===================\n${show_ip}\n" ;
write-debug "new_issue:\n${new_issue}" ;
echo -e "${new_issue}" >./issue ;
[[ -a ./issue ]] && write-debug "issue file exists" || "no existing issue file" ;
ci -m -u ./issue ;
write-debug "checked back in issue file" ;



Solution

I found the answer: the information is not available to the "ip" command until the network change (from the "sudo service network restart" or the reboot) is complete. Because the network change causes "/etc/sysconfig/network-scripts/ifup-post" to run before it is finished, which in-turn calls out to "/sbin/ifup-local" to run before it is finished, "ip" called within "/sbin/ifup-local" called automatically can never have that information. To solve this, I renamed the script from "/sbin/ifup-local" to "/sbin/update-issue", and created a new "/sbin/ifup-local" that calls "/sbin/update-issue" asynchronously. Now it works.

=====

"/sbin/ifup-local":

#!/bin/sh
nohup (sleep 1 ; /sbin/update-issue) &

=====

"/sbin/update-issue":

#!/bin/bash
function write-debug() {
        msg="$(date +'%Y-%m-%d %H:%M:%S%S')\tDEBUG:\t$1\n" ;
        echo -e ${msg}  >>${LOGFILE} ;
}
################################################
################################################
set -x ;
export LOGFILE='/tmp/ifup-local.log' ;
export PATH="/usr/sbin/:/usr/bin/:${PATH}" ;
echo -e "\n--------------------------------------------------\n" >>${LOGFILE} ;
write-debug "PATH: ${PATH}" ;
cd /etc ;
write-debug "PWD: $(pwd)" ;
[[ -a ./issue ]] && write-debug "issue file exists" || write-debug "no existing issue file" ;
write-debug "Removing old issue file" ;
[[ -a ./issue ]] && unlink ./issue || write-debug "no issue file to remove" ;
issue_original="$(cat ./issue-original)" ;
write-debug "issue_original:\n${issue_original}" ;
write-debug "about to check the IP numbers" ;
show_ip="$(ip addr show |awk '$1=="inet" && $2 !~ /^127/ {print "\t"$2}')" ;
#show_ip="$(ip addr show |fgrep 'inet ')" ;
write-debug $? ;
write-debug "show_ip:\n ${show_ip}" ;
write-debug "checking out issue file to lock it" ;
[[ -a ./issue ]] && write-debug "issue file exists" || "no existing issue file" ;
co -l ./issue ;
export new_issue="${issue_original}\n\n\tCurrent IP Numbers:\n\t===================\n${show_ip}\n" ;
write-debug "new_issue:\n${new_issue}" ;
echo -e "${new_issue}" >./issue ;
[[ -a ./issue ]] && write-debug "issue file exists" || "no existing issue file" ;
ci -m -u ./issue ;
write-debug "checked back in issue file" ;




Comments (4)

  • +0 – Damn. So with this hop from CentOS 6.x to 7, getting the IP shown in issue is a much more complex setup. Why oh why... Thanks for this extremely perfect answer though. Saved me a few hours right here. I would like to buy you a beer. — Feb 22, 2015 at 14:51  
  • +0 – Can I ask why you use [[ -a? — Feb 22, 2015 at 14:55  
  • +0 – @StevenLu the [[ -a ./issue ]] checks that the file exists. It was done as a simple assertion test when I was tooling with this, so I knew I was in expected state when I took certain actions. — Feb 22, 2015 at 17:02  
  • +0 – Ok, i was just seeing if you had a reason to use it over -e. Also none of this code shows what issue-original actually is (but it's pretty obvious) — Feb 23, 2015 at 06:43