Posts tagged as sysadm
Working with git
a lot I decided I needed some git
status
in my prompt.
I searched the web and some solutions where almost what I wanted
and this one by Sebastian Celis
came very close.
But it didn't work with my version of zsh
, because that didn't seem
to understand the =~
operator.
I also think Sebastian makes things over complicated and so I changed
some things aroud.
This is what I came up with:
First make sure this code is included in your ~/.zshenv
file
prompt_git_info()
{
unset __GIT_BRANCH
unset __GIT_BRANCH_STATUS
unset __GIT_BRANCH_DIRTY
local st="$(git status 2>/dev/null)"
if [[ -n "$st" ]]; then
local -a arr
arr=(${(f)st})
if [[ $arr[1] = *Not\ currently\ on\ any\ branch.* ]]
then
__GIT_BRANCH='no-branch'
else
__GIT_BRANCH="${arr[1][(w)4]}"
fi
if [[ $arr[2] = *Your\ branch\ is* ]]
then
if [[ $arr[2] = *ahead* ]]
then
__GIT_BRANCH_STATUS='ahead'
elif [[ $arr[2] = *diverged* ]]
then
__GIT_BRANCH_STATUS='diverged'
else
__GIT_BRANCH_STATUS='behind'
fi
fi
if [[ $st = *nothing\ to\ commit* ]]
then
__GIT_BRANCH_DIRTY='0'
else
__GIT_BRANCH_DIRTY='1'
fi
fi
if [[ -n "$__GIT_BRANCH" ]]
then
local s="("
s+="$__GIT_BRANCH"
case "$__GIT_BRANCH_STATUS"
in
ahead) s+="↑" ;;
diverged) s+="↕" ;;
behind) s+="↓" ;;
esac
if [[ "$__GIT_BRANCH_DIRTY" = "1" ]]
then
s+="⚡"
fi
s+=")"
printf " %s%s" "%{${fg[yellow]}%}" $s
fi
}
and set your prompt to something like this
PS1=$'$C_CYAN%n@%m$(prompt_git_info) $C_WHITE%2~$ $C_OFF'
When I now switch to a directory that is under control of git
I get gt status
messages in my prompt, like
tonk@mach (master⚡) ~/dir$ git commit -a
[master fca5ac3] Nice, new stuff.
6 files changed, 88 insertions(+), 12 deletions(-)
tonk@mach (master↑) ~/.dir$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
tonk@mach (master↑) ~/.dir$
When installing a minimal CentOS 6 system, minimal really, really means
minimal. After a reboot the network interfaces do not start, so network
connectivity is non existing.
Looking into that I noticed that the file
/etc/sysconfig/network-scripts/ifcfg-eth0
contained
DEVICE=eth0
HWADDR=11:22:33:44:55:66
NM_CONTROLLED=yes
ONBOOT=no
BOOTPROTO=dhcp
TYPE=Ethernet
USERCTL=no
PEERDNS=yes
IPV6INIT=no
The lines that mess things up are NM_CONTROLLED=yes
meaning the interfaces
are managed with NetworkManager, which isn’t actually installed as part of a
minimal install. You want a minimal install, you get a minimal install. And
ONBOOT=no
, meaning "do not start the interface on boot". How stupid is
that!
The trick is to run something like system-config-network-tui
to set the IP
addresses manually, but as you might imagine, that's not installed either.
So you best edit /etc/sysconfig/network-scripts/ifcfg-eth0
by hand and set it
to:
DEVICE=eth0
HWADDR=11:22:33:44:55:66
NM_CONTROLLED=no
ONBOOT=yes
BOOTPROTO=none
TYPE=Ethernet
USERCTL=no
PEERDNS=yes
IPV6INIT=no
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
DNS1=192.168.0.254
The USERCTL=...
line is optional: If set to yes
it lets non-root users
control the interface.
After setting this a service network restart
will do the trick.
It often happens that I get into a situation
where I need to know key codes of pressed
keys. On my Mac that's simple. Just use the
Key Codes
by Many Tricks.
But on Linux I constantly was trying to find
out which key produced what.
So I ended up writing a program for that. I started
of in the shell, but that ended up being rather
tricky and unnecessary complicated. So I redid the
whole thing in C.
This is the result
/*
* Program : code.c
* Author : Ton Kersten
*/
#include <stdio.h>
#include <curses.h>
#define DONE 'q'
#define ESC 0x1b
#define SPC 0x20
char ch;
main()
{
printf("Press '%c' to quit!\n\n", DONE);
/*
* Put the terminal in raw mode, with no echo
*/
system("stty raw -echo");
/*
* Print the header
*/
printf("%4s\t%4s\t%4s\t%4s\r\n", "Char", " Hex", " Oct", " Dec");
printf("%4s\t%4s\t%4s\t%4s\r\n", "----", "----", "----", "----");
/*
* Set the initial loop value to something odd
*/
ch = DONE-1;
while ( ch != DONE )
{ ch = getchar();
/*
* Character read. Display it. Look out for < 0x20
*/
if ( ch < SPC )
{ if ( ch == ESC )
{ /*
* Esc. Just say 'Esc'
*/
printf("%-4s\t0x%02x\t%04o\t%04d\r\n",
"Esc", ch, ch, ch);
}
else
{ /*
* < ' '. Print Control character
*/
printf("^%-c\t0x%02x\t%04o\t%04d\r\n",
ch-1+'A', ch, ch, ch);
}
}
else
{ /*
* Normal character. Display it normally
*/
printf("%-4c\t0x%02x\t%04o\t%04d\r\n",
ch, ch, ch, ch);
}
}
/*
* Put the terminal back to something usefull
*/
system("stty sane echo");
}
And this is an example of the output
Press 'q' to quit!
Char Hex Oct Dec
---- ---- ---- ----
Esc 0x1b 0033 0027
O 0x4f 0117 0079
P 0x50 0120 0080
Esc 0x1b 0033 0027
[ 0x5b 0133 0091
2 0x32 0062 0050
4 0x34 0064 0052
~ 0x7e 0176 0126
q 0x71 0161 0113
During one of my teaching sessions a student
asked me if it was possible to find the number
of spaces in a variable.
As with all questions in Linux and UNIX the answer is
a simple
Of course that's possible. In UNIX and Linux everything
is possible.
With some sed
or awk
this can be done within
seconds. But I wanted it done completely within
the shell, in this case bash
.
This is what I came up with
P="John and Paul and Ringo and George where the Beatles"
R=${P//[! ]/} # Remove everything that is NOT a space
echo ${#R} # Show the number of characters (spaces) that are left
And this also works in the Korn shell (ksh
) and the Z-shell (zsh
).
I'm creating a Puppet Starter Kit with some standard manifests included and a
complete set of documentation. All documentation should be written in
Markdown and will be served
by Markdoc. But I want to generate all Markdown files
from the Puppet manifests, so I only need to document the manifest file.
Generating the Markdown is not that difficult, except that I kept ending up
with empty lines at the top of the manifest code and I wanted to get rid of
those. Of course this should be done with sed
, because the whole generation
process is written in bash
. When playing around with sed
I found
which, I think, is genius in it's simplicity. After you find something, do not
remove. Life in UNIX and Linux is nice!
Read more »
When working with Puppet and a VCS (like git
and SVN
)
it's nice to have a simple way of updating the Puppet tree.
My tree is always in /etc/puppet
and owned by user and group
puppet
. User puppet
is allowed to checkout the complete
tree from git
or subversion
.
I have created two one-liners to update the complete tree and make sure
all rights are still correct.
update_svn
#!/bin/bash
# update_svn
su - puppet -c 'cd /etc/puppet; svn up; cd doc; ../bin/gendoc'
update_git
#!/bin/bash
# update_git
su - puppet -c 'cd /etc/puppet; git pull; cd doc; ../bin/gendoc'
But, of course, it's not handy to type update_git
today and update_svn
tomorrow. And I also don't want a path to /etc/puppet/bin
.
The solution is a very simple one, as always:
cd /usr/local/bin
ln -s /etc/puppet/bin/update_git pupdate
and now I only have to type pupdate
and things work out.
A customer called and wanted help with an error they made.
The error was simple, they typed:
and now things broke. Of course things broke. If they would not brake that
would be very weird.
Luckily they had a second server and a simple one-liner stole all the rights
from this second server and and we could put these on the broken one.
The oneliner
find / -depth -printf 'chmod %m\t\t-- "%p"\nchown %u:%g\t-- "%p"\n' > rights.sh
produces output like this
chmod 644 -- "/etc/sysconfig/kdump"
chown root:root -- "/etc/sysconfig/kdump"
chmod 644 -- "/etc/sysconfig/rhn/sources"
chown root:root -- "/etc/sysconfig/rhn/sources"
chmod 644 -- "/etc/sysconfig/rhn/sources.rpmforge.txt"
chown root:root -- "/etc/sysconfig/rhn/sources.rpmforge.txt"
Running this script on the broken server left us with something
that was working.
Running
on all cached packages in /var/cache
and after that a
Solved the rest.
Pheeeuuwww, we were lucky 
I'm using Pygments for quite some time now and I just noticed there was a new
version available (1.5). I installed that and I was wondering if there would be
a lexer included for Puppet. Well, it wasn't, but a short Google action
directed me to the Pygments lexer for the Puppet
DSL.
Of course my old CentOS 5 system with Python 2.6 doesn't want to install this,
so I hacked the Puppet lexer into Pygments.
Here's an example of the result:
class generic::ssh {
$ssh_service = hiera("ssh_service")
$ssh_packages = hiera("ssh_packages")
$ssh_debug = hiera("ssh_debug", "undef")
$permit_root_login = hiera("permit_root_login", "no")
$ssh_users = hiera_array("ssh_users", "undef")
$ssh_groups = hiera_array("ssh_groups", "undef")
package { $ssh_packages:
ensure => present,
before => File["/etc/ssh/sshd_config"],
}
file { "/etc/ssh/sshd_config":
ensure => present,
content => template("generic/sshd_config.erb"),
notify => Service["${ssh_service}"],
}
service { $ssh_service:
ensure => running,
enable => true,
hasrestart => true,
hasstatus => true,
}
}
and an example of the Hiera Yaml
file:
---
# SSH Settings
permit_root_login : 'no'
ssh_service :
- 'sshd'
ssh_users :
- 'root'
- 'tonk'
ssh_groups :
- 'wheel'
ssh_packages :
- 'openssh'
- 'openssh-clients'
- 'openssh-server'
Nice 
Some time ago I was fighting my .screenrc
again. I wanted to change
the status line, but it was hardly possible to read and understand
what I typed hardly half a year ago. The screen
config file is not
exactly poetry.
While searching the web to find how to change the status line I ran
into tmux
and I thought: "Let's give it
a try". And after the very simple compile I started configuring it.
What a surprise I was in for. This config file could be read, understood and
changed. Man, this is good.
One of the first things I changed was the default Prefix key Ctrl-B
. I changed
it to Alt-A
, so I can still use all the control keys with Vim and in the
terminal.
Read more »
Some posts ago I wrote that I was busy to find out how a FreeBSD machine can be
PXE-ed from a Linux server. Well, I found that some time ago, but I didn't have
the time to type it here, yet. Well, as always, once you know how it's
done, it's quite simple. But because a lot of the FreeBSD documentation is very
old (talking about FreeBSD 4, 5 and 6) it takes some time to find it all.
Read more »