1

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" ;

5
  • Part of why this is important is it will eventually also be extended to register resultant VMs into a small LDAP directory, for discovery by monitoring and loadbalancing, etc.
    – DTK
    Sep 28, 2014 at 15:53
  • You can simplify that a bit, or at least make it easier to understand, with something like ip addr show up scope global to 0.0.0.0/0 | grep -w inet | awk '{ print $2 }' Sep 28, 2014 at 16:04
  • I'm not sure if that's easier, but I hadn't thought about scope (the "ip" command is significantly more powerful than the old "ifconfig", "route" and related commands).
    – DTK
    Sep 28, 2014 at 16:15
  • As an update, heavily instrumenting this script with debug messages, it looks like when the script runs, the IP command does not yet have access to this information. Not sure if I would benefit from forking-off a separate script that has a delay.
    – DTK
    Sep 29, 2014 at 8:22
  • Can you show us the output of sudo service network restart ; cat /etc/issue? Also, I believe the -m requires a message argument in the ci command, so that will probably fail. Sep 29, 2014 at 14:54

3 Answers 3

1

If you want to show the IP address in the /etc/issue, then you may be able to use \4 in the issue file. From man agetty, under ISSUE ESCAPES:

4 or 4{interface}

Insert the IPv4 address of the specified network interface (for example: \4{eth0}). If the interface argument is not specified, then select the first fully configured (UP, non-LOCALBACK, RUNNING) >interface. If not any configured interface is found, fall back to the IP address of the machine's hostname.

6 or 6{interface}

The same as \4 but for IPv6.

This is agetty from util-linux 2.28.2 from ubuntu.

0

I think that problem is in path. ip command is in /sbin directory.

Usually - this directory isn't in path except root user, so - using it in scripts may cause problems.

Try use /sbin/ip instead of ip command.

1
  • 'which ip' shows is is in "/usr/sbin/ip". I added 'export PATH="/usr/sbin/:/usr/bin/:${PATH}" ;', to no avail. The ip command is being called, but it is only seeing the loopback interface for IPv4.
    – DTK
    Oct 1, 2014 at 23:44
0

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" ;

4
  • 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.
    – Steven Lu
    Feb 22, 2015 at 14:51
  • Can I ask why you use [[ -a?
    – Steven Lu
    Feb 22, 2015 at 14:55
  • @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.
    – DTK
    Feb 22, 2015 at 17:02
  • 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)
    – Steven Lu
    Feb 23, 2015 at 6:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.