A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

Jump to

Quick reference

Showing posts with label config. Show all posts
Showing posts with label config. Show all posts

Specify git config temporarily for one command

Use -c after the git call, before any other options:

e.g. to override your core.pager="less -r" setting:

    git -c 'core.pager=cat' log -n 3 --abbrev-commit

(source)

Jenkins admin notes

Some things to help on your Continuous Integration journey with Jenkins:

  • Use  docker pull jenkins  for a quick start
  • Security can be a bit fiddly to set up. Try these easy settings:
    • Jenkins’ own user database
    • Allow users to sign up
    • Logged-in users can do anything
  • There is a Role-Based Strategy plugin for more advanced use
  • If you accidentally lock yourself out, edit  $JENKINS_HOME/config.xml  to say false and restart Jenkins
  • To see a list of failing tests, configure a Post-build action for  "Publish JUnit test result report"

-- Jenkins ver. 1.642.2

Can't push to github




The problem:

Git asks you for your password, when it should just accept your SSH key.

$ git push origin master
Password for 'https://github@github.com': 


The solution:

1) First, read the github documentation to ensure your SSH keys are set up correctly

2) Then add this to your ~/.ssh/config:

Host github github.com
Hostname github.com
User git
IdentityFile ~/.ssh/github/id_rsa


3) Finally, clone using ssh instead of https:

git clone https://github.com/username/project-name.git # wrong

git clone git@github.com:username/project-name.git # right

4) Push should now work as expected


Make apt-get and aptitude work through a proxy

1) sudo vi /etc/apt/apt.conf.d/70debconf
2) It should already have: DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt || true";};
3) Add this after what's there (no blank lines):
Acquire {
        http {
                Proxy "http://user:pass@host:port";
                No-Cache "false";
                Max-Age "86400";
                No-Store "false";
        };
};
Thanks

Git basics

Have git remember merge conflict resolutions so you never have to do them more than once:
git config --global rerere.enabled 1

Prevent "git push" with no parameters from pushing anything other than your current branch:
git config --global push.default current

Show a graphical summary of the merge tree (looks a bit like gitk).
This gives the answer to "Have I pushed or not"? :
git log --decorate --color --graph  --oneline


Find the point at which you forked (branched):
git merge-base [branch] [trunk or previous branch]


Show all changes made in this branch (if you branched from master):
git log --oneline --name-only --reverse master..HEAD


Ensure only one commit per file; pipe the above through:
| grep -v '^....... ' |sort |uniq -c |sort -nr 
 
Edit all commit messages since a particular commit:
git rebase -i $(git merge-base [branch or HEAD] [trunk or previous branch])


Undo the last commit made locally (e.g. in order to re-do it differently, perhaps in the middle of a rebase): 
git reset HEAD^


To reverse a pushed commit two commits back,
first reverse the second most recent commit, and then commit it back:
git revert -n HEAD~1
git push origin branch
(Do not try to rebase what has been pushed, it will not work. Rebase only changes your local repo)

To revert a merge commit:
git revert SHA -m 1
(Where SHA is the commit ID)

Reset a branch to be same as the repo:
git reset --hard origin/branch_name

Delete a branch:

git branch -D branch_name # delete it locally
git push origin :branch_name # delete it on remote


Use a branch in a different repo for the same project:
git remote add repo_shortname user@server:/repo_name
Use different branch names in each repo.
Push to your repo_shortname instead of origin.

Create a new, tracked branch:
Tracked means that 'git status' will show you how many commits behind the parent branch you are, and if the parent branch has diverged (which means you might want to rebase onto it)
git checkout master # or wherever you want to branch from 
git checkout -t -b my_new_branch

Easily make an alteration to a previous commit:
git commit -m'fixup! same title as another commit' filename
git rebase -i --autosquash [commit id]

(the commit will be put in the correct place and marked as 'fixup' automatically)

A git workflow:
(dca-73 is the name of a branch)
git fetch
git checkout dca-73
git pull origin dca-73
# run tests
# make changes
# run tests
git fetch
git push origin dca-73
git checkout master
git pull origin master
git merge --no-ff dca-73

# run tests

# check it looks right
git log --decorate --graph --oneline

git push origin master




How to merge conflicts without editing the file:

git checkout --ours path/to/filename
git checkout --theirs path/to/filename


Automatically run checks on your code before committing with git hooks:
e.g. Just edit the file .git/hooks/pre-commit in your working directory, and make it executable.
It will not be committed along with your code because it's in the special .git directory.

CPAN config

o conf prerequisites_policy 'follow'
o conf make_install_make_command 'sudo make'
o conf build_requires_install_policy yes
o conf commit

My .bashrc config

# general:
export PATH="~/scripts:$PATH"

alias ls="ls -F --color"
alias grep="grep --color=auto"

# git aliases
function gitdiff() {    git diff --no-ext-diff -w "$@" | vim -R -
}

function gitlog() {
    git log --name-only "$@"
}

function gitcommit() {
    git --no-pager diff --no-ext-diff
    echo
    read -p "Are you sure you want to commit these changes? " yn
    case $yn in
        [Yy]* ) git commit "$@"; break;;
    esac
}

# git prompt
host_colour="01;34"
export PS1="\[\033[${host_colour}m\]\h\[\033[00m\]/\u \t \w \$ "

function __git_commits_behind {
    if [ -d .git ]
    then
        git st | perl -ne'm{Your branch is behind.+by (\d+) commit} && print "behind $1< "'
    fi
}

function __git_commits_ahead {
    if [ -d .git ]
    then
        git st | perl -ne'm{Your branch is ahead of.+ by (\d+) commit} && print "ahead $1> "'
    fi
}

function update_prompt {
    local branch=$(git branch --no-color 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /')
    export PS1="\[\033[${host_colour}m\]\h\[\033[00m\]/\u \[\033[${branch_colour}m\]${branch}$(__git_commits_behind)$(__git_commits_ahead)\[\033[00m\]\t \w \$ "
}
export PROMPT_COMMAND=update_prompt

Git setup

git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com

git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto

git config --global core.editor vim

Example ssh config

Host [alias]
    HostName [remote hostname]
    User [remote username]
    IdentityFile [file]

[alias] is what you type to select the connection, e.g. ssh [alias]
[file] is your DSA or RSA private key file

Set an option in vim

:set cmdheight=3
or
:set ch=3

My vim config

Superceded by https://github.com/willsheppard/dotfiles/blob/master/.vimrc

in ~/.vimrc:

" TABS
" make tabs 4 characters wide
:set tabstop=4
" make > and < keys shift by 4 characters
:set shiftwidth=4
" turn tabs into 4 spaces
:set expandtab

" automatically tab to the right place, after pressing enter                     
:set autoindent

" COLOURS
" less bright colours
:set background=light 
" set colour of comments
:highlight Comment ctermfg=Green

" syncronise syntax highlighting properly
:syntax on
autocmd BufEnter * :syntax sync fromstart 
" highlight terms for which you've searched
:set hlsearch


" SCRIPTS
" allow Shift-K to look up stuff
":set keywordprg=/path/to/a/script




" PLUGINS
" For Taglist: http://vim-taglist.sourceforge.net/
" Show name of current subroutine

map q :TlistShowTag<Enter>
" Show list of all subroutines

nnoremap <silent> <tab> :TlistToggle<Enter>




" Enable code folding for perl subroutines
:let perl_fold=1
" don't fold the whole package up, just subroutines (type zazO with cursor on the package name to unfold everything)
":set foldlevelstart=1
" don't fold anything (type za while in a subroutine to fold it up)
:set foldlevelstart=99




" EXAMPLE of mapping a keypress to a sequence of other keypresses
" map CTRL-E to end-of-line (while in insert mode)
imap <C-e> <esc>$i<right>


" Also set .vim/ftplugin/perl.vim to display the current Perl subroutine name in the status line



" save local marks a-z for up to 100 files ('100), save global marks A-Z upon exit (f1)
set viminfo='100,f1


" don't clear the screen upon exiting vim
set t_ti= t_te=

" load custom filetypes
:filetype on
au BufNewFile,BufRead *.tt set filetype=html

Make vi recognise different filetypes

In ~/.vimrc:

" load custom filetypes
:filetype on
au BufNewFile,BufRead *.tt set filetype=html

Easily import properties file in JUnit

Pass this parameter to the jvm:
-DPropertyManager.file=/path/to/props.properties

Then in the program:
import junitx.util.PropertyManager; // from http://sourceforge.net/projects/junit-addons/ ?
PropertyManager.getProperty("my.key");

Start Apache with a custom configuration

/path/to/main/httpd -f /path/to/your/custom/httpd.conf -k start

Using a custom Apache config

apachectl -f ~/httpd/conf/httpd.conf -k graceful

tail -f ~/httpd/logs/error_log

Using an XML configuration file for Log::Log4perl

XML configuration file:

<!--
* General configuration for log4perl
* LOGFILE.filename may be set by the application
* All logging goes to STDOUT (CONSOLE)
-->
<log4perl>
<log4perl.rootlogger>WARN, CONSOLE, LOGFILE</log4perl.rootLogger>

<log4perl.appender.console>Log::Log4perl::Appender::Screen</log4perl.appender.CONSOLE>
<log4perl.appender.console.layout>PatternLayout</log4perl.appender.CONSOLE.layout>
<log4perl.appender.console.layout.conversionpattern>[%d] [%p %c] - %m%n</log4perl.appender.CONSOLE.layout.ConversionPattern>

<log4perl.appender.logfile>Log::Log4perl::Appender::File</log4perl.appender.LOGFILE>
<!-- Let logging come to STDERR on the console, and *pipe* into a log so that unexpected errors are caught
<log4perl.appender.logfile.filename>/optional/absolute/path/to/logfile.log</log4perl.appender.LOGFILE.filename>
-->
<log4perl.appender.logfile.mode>append</log4perl.appender.LOGFILE.mode>
<log4perl.appender.logfile.layout>PatternLayout</log4perl.appender.LOGFILE.layout>
<log4perl.appender.logfile.layout.conversionpattern>[%d] [%p %c] - %m%n</log4perl.appender.LOGFILE.layout.ConversionPattern>

<!-- Add different log levels for specified modules
<log4perl.logger.clickthrough.transform>INFO</log4perl.logger.ClickThrough.Transform>
-->
</log4perl>


How to read the configuration:

my $log4perl = XML::Simple->new(ForceArray=>0, KeyAttr=>[])->XMLin( $log4perl_config_filename );
my $logname = $0;
$logname =~ s/\.pl$/.log/;
$log4perl->{'log4perl.appender.LOGFILE.filename'} = $logname;
Log::Log4perl::init($log4perl);
my $logger = Log::Log4perl->get_logger(__PACKAGE__);

Apache::Registry / Perl config files

  • Apache::Reload causes more problems than it fixes
  • Apache::StatINC only works on the @INC path which is set by Apache before scripts are run
  • Apache::Registry - just don't bother
  • Don't use Apache's PerlFreshRestart On, it will break things
  • If parsing Perl syntax config files from Apache, remember it takes a few seconds for Perl to 'let go' after making changes.

Unix timezone settings

Time zone stuff in UNIX isn't difficult in concept but it can be tricky to work out how a box is configured.

The current timezone is set by the /etc/localtime file, which is either a symlink, or a hard link, or a copy of a file in /usr/share/zoneinfo. If the file's timestamp is a long time ago it's a fair bet it's been configured this way for a while.

The files in /usr/share/zoneinfo contain the definitions of a time zone -- its offset from UTC and any daylight savings in use. The problem is working out which file is in use. It could be a symlink:

[root@server ~]# ls -l /etc/localtime
lrwxrwxrwx 1 root root 27 Jun 26 2008 /etc/localtime -> /usr/share/zoneinfo/Etc/GMT

Given the timestamp on the symlink to the GMT zone file is June last year I'd say it's likely that it's been configured this way (ie, GMT) for a long time.

Other boxes don't have symlinked timezone files:

[root@server ~]# ls -l /etc/localtime
-rw-r--r-- 1 root root 118 Mar 4 2008 /etc/localtime

They might have a hard link (which is like having a file known by another name -- same contents, more than one name) to a zoneinfo file. You can try to work this out using find:

[root@server ~]# ls -l /etc/localtime
-rw-r--r-- 11 root root 118 Apr 13 2009 /etc/localtime

[root@server ~]# find /usr/share/zoneinfo -samefile /etc/localtime
/usr/share/zoneinfo/GMT0
/usr/share/zoneinfo/Greenwich
/usr/share/zoneinfo/GMT
/usr/share/zoneinfo/Etc/GMT0
/usr/share/zoneinfo/Etc/Greenwich
/usr/share/zoneinfo/Etc/GMT
/usr/share/zoneinfo/Etc/GMT-0
/usr/share/zoneinfo/Etc/GMT+0
/usr/share/zoneinfo/GMT-0
/usr/share/zoneinfo/GMT+0

You can see here that /etc/localtime and all the GMT zone files are hard links to the same file contents -- ie, the file contents that set the time to GMT, showing this box is in GMT.

If /etc/localtime isn't a symlink or a hard link it must be a straight copy of a zone file (or it's totally broken). You can work this out by MD5 summing /etc/localtime's contents against all the possible time zone files it could be. Get the MD5 sum (like an abbreviation of the contents) of /etc/localtime:

[root@server ~]# md5sum /etc/localtime
fcccbcf95c718cf2fdee557763e460be /etc/localtime

Then find other files with the same contents:

[root@server ~]# find /usr/share/zoneinfo/ -type f -exec md5sum {} \; | grep fcccbcf95c718cf2fdee557763e460be
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT-0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT-0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT-0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT-0

So it looks like this server's /etc/localtime has the same contents as all the GMT files. This box is in GMT.

Apache: make file download instead of appear in browser

(Untested)

## FORCE FILE TO DOWNLOAD INSTEAD OF APPEAR IN BROWSER ###
-> http://www.htaccesselite.com/addtype-addhandler-action-vf6.html
AddType application/octet-stream .mov .mp3 .zip

Where you might find Apache files

  • /usr/sbin/apachectl
  • /usr/sbin/httpd
  • /etc/httpd/conf/httpd.conf
  • /var/log/httpd/error_log
  • /etc/httpd/
  • /etc/httpd/modules/