Thursday 29 August 2013

Gitosis setup

official link: https://github.com/res0nat0r/gitosis

usually "git" user is created with following command before this installation. but you can use any other name for the user. e.g. "git2".
sudo adduser \
   --system \
   --shell /bin/bash \
   --gecos ‘User for managing of git version control’ \
   --group \
   --disabled-password \
   --home /home/git \ 
   git
You can change the home directory.

1. gitosis requires python tools, so need install it first
$ apt-get install python-setuptools

2. then clone the gitosis repo
$ git clone https://github.com/res0nat0r/gitosis.git gitosis

3. install gitosis (installs a couple of executables that Gitosis will use.)
$ cd gitosis
$ sudo python setup.py install

4.Gitosis wants to put its repositories under /home/git, which is fine. But if you have already set
up your repositories in /opt/git, so instead of reconfiguring everything, you can create a symlink:
$ ln -s /opt/git /home/git/repositories

5.remove the current authorized_keys, re-add the keys later, and let Gitosis control the authorized_keys
file automatically.
$ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak

6. Next you need to turn your shell back on for the 'git' user, if you changed it to the git-shell command. People still won't be able to log in, but Gitosis will control that for you. So, let's change this line in your /etc/passwd file
git:x:1000:1000::/home/git:/bin/bash

7.initialize gitosis: (if you want to use anoterh user id instead of git, you need change -u param). You do this by running the gitosis-init command with your personal public key. If your public key isn’t on the server,you’ll have to copy it there(/tmp/id_rsa.pub). This lets the user with that key modify the main Git repository that controls the Gitosis setup.
$ sudo -H -u git gitosis-init < /tmp/id_dsa.pub
Initialized empty Git repository in /opt/git/gitosis-admin.git/

Reinitialized existing Git repository in /opt/git/gitosis-admin.git/

8.verifying the ssh connection to the server with the user git(via your pub key).
$ ssh git@gitserver
ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.

Connection to <server> closed.
this means Gitosis recognized you but shut you out because you’re not trying to do any Git commands.

9. from now on, you can manage users/repos by editing gitosis.conf and public key files in keydir folder.
- add user key files to keydir;
- update gitosis.conf to add team and team members and also permissions.
[group myteam]
members = uname1 uname2 
writable = myproject


---output of python setup.py install---
running install
Checking .pth file support in /usr/local/lib/python2.7/dist-packages/
/usr/bin/python -E -c pass
TEST PASSED: /usr/local/lib/python2.7/dist-packages/ appears to support .pth files
running bdist_egg
running egg_info
creating gitosis.egg-info
writing requirements to gitosis.egg-info/requires.txt
writing gitosis.egg-info/PKG-INFO
writing top-level names to gitosis.egg-info/top_level.txt
writing dependency_links to gitosis.egg-info/dependency_links.txt
writing entry points to gitosis.egg-info/entry_points.txt
writing manifest file 'gitosis.egg-info/SOURCES.txt'
reading manifest file 'gitosis.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'gitosis.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/gitosis
copying gitosis/init.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/access.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/serve.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/util.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/gitweb.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/mirror.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/__init__.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/app.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/run_hook.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/ssh.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/gitdaemon.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/snagit.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/repository.py -> build/lib.linux-x86_64-2.7/gitosis
copying gitosis/group.py -> build/lib.linux-x86_64-2.7/gitosis
creating build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/test_mirror.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/test_run_hook.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/test_group.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/util.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/test_ssh.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/test_repository.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/__init__.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/test_init.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/test_serve.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/test_gitdaemon.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/test_access.py -> build/lib.linux-x86_64-2.7/gitosis/test
copying gitosis/test/test_gitweb.py -> build/lib.linux-x86_64-2.7/gitosis/test
creating build/lib.linux-x86_64-2.7/gitosis/templates
copying gitosis/templates/__init__.py -> build/lib.linux-x86_64-2.7/gitosis/templates
creating build/lib.linux-x86_64-2.7/gitosis/templates/admin
creating build/lib.linux-x86_64-2.7/gitosis/templates/admin/hooks
copying gitosis/templates/admin/hooks/post-update -> build/lib.linux-x86_64-2.7/gitosis/templates/admin/hooks
creating build/lib.linux-x86_64-2.7/gitosis/templates/default
creating build/lib.linux-x86_64-2.7/gitosis/templates/default/hooks
copying gitosis/templates/default/hooks/post-receive -> build/lib.linux-x86_64-2.7/gitosis/templates/default/hooks
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
creating build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/init.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/access.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/serve.py -> build/bdist.linux-x86_64/egg/gitosis
creating build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/test_mirror.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/test_run_hook.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/test_group.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/util.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/test_ssh.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/test_repository.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/__init__.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/test_init.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/test_serve.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/test_gitdaemon.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/test_access.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/test/test_gitweb.py -> build/bdist.linux-x86_64/egg/gitosis/test
copying build/lib.linux-x86_64-2.7/gitosis/util.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/gitweb.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/mirror.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/__init__.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/app.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/run_hook.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/ssh.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/gitdaemon.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/snagit.py -> build/bdist.linux-x86_64/egg/gitosis
creating build/bdist.linux-x86_64/egg/gitosis/templates
creating build/bdist.linux-x86_64/egg/gitosis/templates/admin
creating build/bdist.linux-x86_64/egg/gitosis/templates/admin/hooks
copying build/lib.linux-x86_64-2.7/gitosis/templates/admin/hooks/post-update -> build/bdist.linux-x86_64/egg/gitosis/templates/admin/hooks
copying build/lib.linux-x86_64-2.7/gitosis/templates/__init__.py -> build/bdist.linux-x86_64/egg/gitosis/templates
creating build/bdist.linux-x86_64/egg/gitosis/templates/default
creating build/bdist.linux-x86_64/egg/gitosis/templates/default/hooks
copying build/lib.linux-x86_64-2.7/gitosis/templates/default/hooks/post-receive -> build/bdist.linux-x86_64/egg/gitosis/templates/default/hooks
copying build/lib.linux-x86_64-2.7/gitosis/repository.py -> build/bdist.linux-x86_64/egg/gitosis
copying build/lib.linux-x86_64-2.7/gitosis/group.py -> build/bdist.linux-x86_64/egg/gitosis
byte-compiling build/bdist.linux-x86_64/egg/gitosis/init.py to init.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/access.py to access.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/serve.py to serve.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/test_mirror.py to test_mirror.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/test_run_hook.py to test_run_hook.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/test_group.py to test_group.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/util.py to util.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/test_ssh.py to test_ssh.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/test_repository.py to test_repository.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/__init__.py to __init__.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/test_init.py to test_init.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/test_serve.py to test_serve.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/test_gitdaemon.py to test_gitdaemon.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/test_access.py to test_access.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/test/test_gitweb.py to test_gitweb.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/util.py to util.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/gitweb.py to gitweb.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/mirror.py to mirror.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/__init__.py to __init__.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/app.py to app.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/run_hook.py to run_hook.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/ssh.py to ssh.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/gitdaemon.py to gitdaemon.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/snagit.py to snagit.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/templates/__init__.py to __init__.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/repository.py to repository.pyc
byte-compiling build/bdist.linux-x86_64/egg/gitosis/group.py to group.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying gitosis.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying gitosis.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying gitosis.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying gitosis.egg-info/entry_points.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying gitosis.egg-info/not-zip-safe -> build/bdist.linux-x86_64/egg/EGG-INFO
copying gitosis.egg-info/requires.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying gitosis.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
creating dist
creating 'dist/gitosis-0.2-py2.7.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing gitosis-0.2-py2.7.egg
creating /usr/local/lib/python2.7/dist-packages/gitosis-0.2-py2.7.egg
Extracting gitosis-0.2-py2.7.egg to /usr/local/lib/python2.7/dist-packages
Adding gitosis 0.2 to easy-install.pth file
Installing gitosis-init script to /usr/local/bin
Installing gitosis-run-hook script to /usr/local/bin
Installing gitosis-serve script to /usr/local/bin

Installed /usr/local/lib/python2.7/dist-packages/gitosis-0.2-py2.7.egg
Processing dependencies for gitosis==0.2
Searching for distribute==0.6.28dev-r0
Best match: distribute 0.6.28dev-r0
Adding distribute 0.6.28dev-r0 to easy-install.pth file
Installing easy_install script to /usr/local/bin
Installing easy_install-2.7 script to /usr/local/bin

Using /usr/lib/python2.7/dist-packages
Finished processing dependencies for gitosis==0.2
-----

Tuesday 27 August 2013

gitlab - access denied issue (not able to push after installation)

[gitlab]
installation guide:
https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md


- if you have the following issue with gitlab, that means your gitlab-shell not configured correctly

$ ssh git@server
Welcome to GitLab, Anonymous!
Connection to server closed.
$ git push -u origin master
Access denied.
fatal: Could not read from remote repository.
then you need update /home/git/gitlab-shell/config.yml
change default one("http://localhost/") to "http://<server>/"
refer to following info/explanation as well:
https://github.com/gitlabhq/gitlabhq/issues/3384#issuecomment-15457287
---- excerpted from above page ----
When invoking the internal api likehttp://server/api/v3/internal/allowed?key_id=2&action=git-upload-pack&ref=_any&project=user/projectfrom other machines, the nginx config will give gitlab as default web so it works.
However when actually doing clone, push and pull. The internal api is invoked by gitlab-shell on the same machine of the gitlab server. Now since the gitlab config for nginx /etc/nginx/sites-enabled/gitlab is set as:
server {
  listen YOUR_SERVER_IP:80 default_server;         # e.g., listen 192.168.1.1:80;
  server_name YOUR_SERVER_FQDN;     # e.g., server_name source.example.com;
  root /home/git/gitlab/public;
user git on the server invoked gitlab-shell to access web api at YOUR_SERVER_FQDN, but now the server IP to user git is 127.0.0.1. So gitlab is not valid website now. But the default nginx site listens to any IP at port 80 so the
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body bgcolor="white" text="black">
<center><h1>Welcome to nginx!</h1></center>
</body>
</html>
is given out. Because it is the index page of default nginx site.
Solution is to set the gitlab nginx config file /etc/nginx/sites-enabled/gitlab as:
server {
  listen *:80 default_server;         # e.g., listen 192.168.1.1:80;
  server_name YOUR_SERVER_FQDN;     # e.g., server_name source.example.com;
  root /home/git/gitlab/public;
Hope this solves problems.
If don't use FQDN only use IP, then the mentioned problem would not appear.
---------

- couple of config files to look at:
/home/git/gitlab/config/gitlab.yml
/home/git/gitlab-shell/config.yml
/etc/nginx/sites-enabled/gitlab

- restart service
sudo service gitlab stop/restart
sudo service nginx stop/restart
sudo /etc/init.d/gitlab restart

- turn on DEBUG log for gitlab-shell if still have trouble.
check /home/git/gitlab-shell/gitlab-shell.log

- if you meet following error:
fatal:bad default revision "HEAD"

most likely your repo has some issue, check ./git/refs, something must be missed there. and also use git branch --list --list -a to see whether correct branches listed.(should be no)  

you can re-clone the project, redo checkout, and then overwrite the original ".git" with the new one.

- check status:
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
/home/git/gitlab-shell/bin/check

- make sure the version of gitlab-shell is correct(with above check). and also hooks path is correct in /home/git/gitlab/config/gitlab.yml. 

  gitlab_shell:
    # REPOS_PATH MUST NOT BE A SYMLINK!!!
    repos_path: /home/git/repositories/

    hooks_path: /home/git/gitlab-shell/hooks/



Wednesday 21 August 2013

Version control - Git

[Setup git in Windows]

1, download client (GUI client and binary realese) from official website: http://git-scm.com/;
  for windows, it's msysgit.
  You can also download it from official site for msysgit: http://msysgit.github.io/ (moved from google to github), detail downloads : https://code.google.com/p/msysgit/downloads/list?q=full+installer+official+git

2, install it.(remember to choose second option for PATH env in order to use context sensitive menu.

3, config the user info and client look and feel.
$git config --global user.name "xxx"
$git config --global user.email "yy@zz.com"
$git config --global color.ui true

4, create local directory and clone the project
assume your local dir is C:\dev\proj
$cd /c/dev/proj
$git clone user@host : project URL

5, now you can add/update/delete source code; or add/udpate/delete branch;

Git Basics:
+ distributed VCS; 
+ everything is local including commit; you can work offline with no network connection;
+ push and pull(fetch & merge) for sync among different hosts. whenever you have network connection;
+ snapshots vs deltas
+ three states:
   + working directory(work tree); modified
   + stage area(index); staged
   + git directory(repo); committed
Committed means that the data is safely stored in your local database. 
Modified means that you have changed the file but have not committed it to your database yet. Staged means that you have marked a modified file in its current version to go into your next commit snapshot.

The Git directory is where Git stores the metadata and object database for your project. This is the most important part of Git, and it is what is copied when you clone a repository from another computer.
The working directory is a single checkout of one version of the project. These files are pulled out of the compressed database in the Git directory and placed on disk for you to use or modify.
The staging area is a simple file, generally contained in your Git directory, that stores information about what will go into your next commit. It’s sometimes referred to as the index, but it’s becoming standard to refer to it as the staging area.

+ configuration has three levels:
/etc/gitconfig file: Contains values for every user on the system and all their repositories. If you pass the option--system to git config, it reads and writes from this file specifically.
~/.gitconfig file: Specific to your user. You can make Git read and write to this file specifically by passing the --global option.
config file in the git directory (that is, .git/config) of whatever repository you’re currently using: Specific to that single repository. Each level overrides values in the previous level, so values in .git/config trump those in /etc/gitconfig.

+ configure
1, user identity
$ git config --global user.name "XXX"

$ git config --global user.email "YY@ZZ.com"
2, editor
$ git config --global core.editor emacs
3, diff tool
$ git config --global merge.tool vimdiff
4, show configurations
git config --list

+ remote & local
   + git remote; or git remote -v to show where you clone is from.

[Conventions]
+ use bare repo if you want to set up a git server (conceptually there is no central server, through this we just want to keep one host as a primary host);
- server repo is bare mode; no working directory. you can't use it directly for dev;
- master branch is used only for formal release; don't checkout master branch for coding;
- dev branch is a collaborative branch;

[Tips]
- you can create new branch in server side(with bare repo), but you can not check it out as there is no working tree/directory there;

- when you do a fetch that brings down new remote branches, you don’t automatically have local, editable copies of them. In other words, you don’t have a new local serverbranch — you only have an origin/serverbranch pointer that you can’t modify.
To merge this work into your current working branch, you can run git merge origin/serverbranch. If you want your own serverbranch branch that you can work
on, you can base it off your remote branch: "git checkout -b serverbranch origin/serverbranch" (looks like, use "git checkout origin/serverbranch" also works, it will automatically created a local branch with same name)

- "git checkout <branch>" : If <branch> is not found but there does exist a tracking branch in exactly one remote (call it <remote>) with a matching name, treat as equivalent to "git checkout -b <branch> --track <remote>/<branch>"

"git checkout fix" is identical as "git checkout --track origin/fix", and identical as "git checkout -b fix origin/fix"; if there is no local branch with same name already. it will automatically create the new local branch.


- to push a local branch to server, you can use "git push origin localbranch" this can push the localbranch to server. another form is "git push origin localbranch:localbranch" with same name, or with a new branch name on server side "git push origin localbranch:newnamebranch"

- push a local branch to origin/server, it will not take the remote branch(you just pushed) as the upstream of the local branch automatically. use "git branch --verbose --verbose -a" to show upstream relationship.


- use "git fetch -p"(prune) if there is some remote branch already removed/deleted, but you can not get it removed in your local host through fetch.
- to remove a remote branch, use "git push origin :featA" = "git push [alias] [null]:[branch name]".  try to remember this as "git push [remotename] [localbranch]:[remotebranch]" syntax.

- use "git reset HEAD <file>" to unstage a file
- use "git checkout -- <file>..." to discard changes in working directory
- to merge from remote branch or other local branch, you need make sure there is no modified file in working tree.
- "git reset --hard <commit>/HEAD", will reset the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded.
- "git reset --soft <commit>/HEAD", Does not touch the index file nor the working tree at all (but only resets the head to <commit>, just like all modes do). This leaves all your changed files "Changes to be committed", as git status would put it.

- "git reset HEAD <file>" default is mixed mode, it will reset the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action.





- after fix the conflicts via editor, you need run "git add" to mark it as resolved (staging the file mark it as resolved in Git) so that git knows the conflict is resolved. if you use mergetool, after you exit the tool git will ask you if the merge is successful, if yes, it will stage the file and mark it as resolved.
- for newly added file, you can not use "git commit -am 'blabla' ", you need first add it then commit;

- rebase is a little bit confusing in git. but it's useful to make history linear; when you rebase from another branch, git will find the common commit between two branches and reapply every commit you have that is not in the other branch. Each time when git reapply a commit, you may need to resolve the conflict, for any conflict resolved, you need use "git add" to tell git the conflict is resolved. and then "git rebase --continue"

- set "HOME" env in windows(HOME=c:\users\uid\) to let msysgit to store the .gticonfig and other config files under this folder; if you set the HOME env as C:\, then the ".gitconfig" will be stored in "C:\users\<uid>\AppData\Local\VirtualStore" this is because git is not permitted to store files at C:\, so it use the virtualStore.
- right click the shortcut of gitbash/gitgui to set the dir to start with ("start in" box);

- two ways to create a bare repo:
A: create a repo from existing project, and then clone a bare repo;
B: git init --bare directly with a empty bare repo, and then clone it from another host and push contents;






[git server setup]
1, suppose you have a local repository setup with "git init" under dir "/opt/projects/my_project". there will be a ".git" dir under /opt/projects/my_project". go to that directory and execute the following command": git clone --bare <repo> <dir>
$ cd /opt/projects
$ mkdir my_project
$ add some source dir/files
$ git init    #this will create a repo for my_project (a ".git" created under /opt/projects/my_project dir)
$ cd /opt/projects
$ git clone --bare my_project my_project.git
Initialized empty Git repository in /opt/projects/my_project.git/
after this, there will be a bare repo in /opt/projects/my_project.git
This is roughly equivalent to something like
$ cp -Rf my_project/.git my_project.git

2, putting the bare repo  on a server
scp: secure file transfer over network; -r means recursively; git.exmple.com is the server to put; /opt/git is the dir to put;
$ scp -r my_project.git user@git.example.com:/opt/git

3, at this point, anyone else can clone the repo via:(need input password of user named "user" )
$ git clone user@git.example.com:/opt/git/my_project.git

4, for every developer that need to access the server(via ssh), you need 
either create a user id in the server for each of them;
or create a single ‘git’ user on the machine, ask every user who is to have write access to send you an SSH public key, and add that key to the ~/.ssh/authorized_keys file of your new ‘git’ user. At that point, everyone will be able to access that machine via the ‘git’ user. This doesn’t
affect the commit data in any way — the SSH user you connect as doesn’t affect the commits you’ve recorded.

5, gen SSH pub key and send to git server
$ ssh-keygen  (run under ".ssh" dir under home dir C:\users\<uid>\.ssh)
leave passphrase as empty to avoid inputing password every time you interact with git server;
$ scp id-rsa.pub user@server:/path

6, add every developer's public key to the authorized_keyfile for git user. (under /home/git/.ssh)
$ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys

[tips part 2]
- if you use gitbash(wiondows host) to clone a github repo, and get the following error:
$ git clone https://github.com/msysgit/msysgit.git syslab
Cloning into 'syslab'...
fatal: unable to access 'https://github.com/msysgit/msysgit.git/': Failed connect to github.com:443; No error
this means you need config a proxy for it. 
you can use 
$git config --global http.proxy <proxy server>:<port>
BTW, if you use 
$sudo -u git -H clone https://github.com/msysgit/msysgit.git syslab
then you need first switch to user git to config the http proxy(via git config --global http.proxy)

Monday 12 August 2013

Virtualization - Hypervisor

Wiki: http://en.wikipedia.org/wiki/Hypervisor

Hypervisor = Virtual machine monitor
is a piece of computer software, firmware or hardware that creates and runs virtual machines.
A computer on which a hypervisor is running one or more virtual machines is defined as a host machine. Each virtual machine is called a guest machine. The hypervisor presents the guest operating systems with a virtual operating platform and manages the execution of the guest operating systems. Multiple instances of a variety of operating systems may share the virtualized hardware resources.

Two types:
  • Type 1 (or nativebare metal) hypervisors run directly on the host's hardware to control the hardware and to manage guest operating systems. A guest operating-system thus runs on another level above the hypervisor.
This model represents the classic implementation of virtual-machine architectures; IBM developed the original hypervisors as bare-metal tools in the 1960s: the test tool, SIMMON, and CP/CMS. CP/CMS was the ancestor of IBM's z/VM. Modern equivalents include Oracle VM Server for SPARCOracle VM Server for x86, the Citrix XenServer and VMware ESX/ESXi.
  • Type 2 (or hosted) hypervisors run within a conventional operating-system environment. With the hypervisor layer as a distinct second software level, guest operating-systems run at the third level above the hardware. VMware Workstation and VirtualBox exemplify Type 2 hypervisors.
Hyperviseur.png
The classification of specific hypervisor implementations as Type 1 or Type 2 is not always clear cut. For example:
  • Kernel-based Virtual Machine (KVM) is implemented as a kernel module for Linux 2.6.20 which, when loaded, allows the Linux kernel to operate as a bare-metal (i.e., Type 1) hypervisor.[2] However, as Linux is an operating system in its own right, one can argue that KVM is a Type 2 hypervisor.[3]
  • Microsoft Hyper-V (released in June 2008)[4] has also been misidentified as a Type 2 hypervisor.[5] Both the free stand-alone version and the version that is part of the commercial Windows Server 2008 product use a virtualized Windows Server 2008 parent partition to manage the Type 1 Hyper-V hypervisor. In both cases the Hyper-V hypervisor loads prior to the management operating-system, and any virtual environments created run directly on the hypervisor, not via the management operating-system.
Attempts have been made to introduce the term Type 0 (Zero) Hypervisor to differentiate specific hypervisor implementations.[6][7] However, no consensus as to the validity of this term has been reached.[8]
-----
Several factors led to a resurgence around 2005 in the use of virtualization technology among Unix and Linux server vendors:[10]
  • Expanding hardware capabilities, allowing each single machine to do more simultaneous work
  • Efforts to control costs and to simplify management through consolidation of servers
  • The need to control large multiprocessor and cluster installations, for example in server farms and render farms
  • The improved security, reliability, and device independence possible from hypervisor architectures
  • The ability to run complex, OS-dependent applications in different hardware or OS environments

Friday 9 August 2013

virtulization - Libvirt/KVM/Qemu

1, Libvirt: http://libvirt.org/
Anatomy of the libvirt virtualization library (From IBM, 2010)

Libvirt provides a hypervisor-agnostic API to securely manage guest operating systems running on a host. Libvirt isn't a tool per se but an API to build tools to manage guest operating systems. Libvirt itself is built on the idea of abstraction. It provides a common API for common functionality that the supported hypervisors implement. Libvirt was originally designed as a management API for Xen, but it has since been extended to support a number of hypervisors.


developed by Redhat.


Comparison and use model of libvirt

The two fundamental differences are that libvirt calls the physical host a node, and the guest operating system is called a domain. Note here that libvirt (and its application) runs in the domain of the host Linux operating system (domain 0).
-----------------------------

Control of remote hypervisors with libvirtd


Control of remote hypervisors with libvirtd
-----------------------------

Driver-based architecture of libvirt

To support extensibility over a wide variety of hypervisors, libvirt implements a driver-based architecture, which allows a common API to service a large number of underlying hypervisors in a common fashion. 

Hypervisors that libvirt supports
HypervisorDescription
XenHypervisor for IA-32, IA-64, and PowerPC 970 architectures
QEMUPlatform emulator for various architectures
Kernel-based Virtual Machine (KVM)Linux platform emulator
Linux Containers (LXC)Linux (lightweight) containers for operating system virtualization
OpenVZOperating system-level virtualization based on the Linux kernel
VirtualBoxHypervisor for x86 virtualization
User Mode LinuxLinux platform emulator for various architectures
TestTest driver for a fake hypervisor
StorageStorage pool drivers (local disk, network disk, iSCSI volume)

libvirt introduction(chinese): http://smilejay.com/2013/03/libvirt-introduction/



Term & Goals from official website:

Terminology and goals

To avoid ambiguity about the terms used, here are the definitions for some of the specific concepts used in libvirt documentation:
  • node is a single physical machine
  • an hypervisor is a layer of software allowing to virtualize a node in a set of virtual machines with possibly different configurations than the node itself
  • domain is an instance of an operating system (or subsystem in the case of container virtualization) running on a virtualized machine provided by the hypervisor
Hypervisor and domains running on a node
Now we can define the goal of libvirt: to provide a common and stable layer sufficient to securely manage domains on a node, possibly remote.
As a result, libvirt should provide all APIs needed to do the management, such as: provision, create, modify, monitor, control, migrate and stop the domains - within the limits of the support of the hypervisor for those operations. Not all hypervisors provide the same operations; but if an operation is useful for domain management of even one specific hypervisor it is worth providing in libvirt. Multiple nodes may be accessed with libvirt simultaneously, but the APIs are limited to single node operations. Node resource operations which are needed for the management and provisioning of domains are also in the scope of the libvirt API, such as interface setup, firewall rules, storage management and general provisioning APIs. Libvirt will also provide the state monitoring APIs needed to implement management policies, obviously checking domain state but also exposing local node resource consumption.
This implies the following sub-goals:
  • All API can be carried remotely though secure APIs
  • While most API will be generic in term of hypervisor or Host OS, some API may be targeted to a single virtualization environment as long as the semantic for the operations from a domain management perspective is clear
  • the API should allow to do efficiently and cleanly all the operations needed to manage domains on a node, including resource provisioning and setup
  • the API will not try to provide high level virtualization policies or multi-nodes management features like load balancing, but the API should be sufficient so they can be implemented on top of libvirt
  • stability of the API is a big concern, libvirt should isolate applications from the frequent changes expected at the lower level of the virtualization framework
  • the node being managed may be on a different physical machine than the management program using libvirt, to this effect libvirt supports remote access, but should only do so by using secure protocols.
  • libvirt will provide APIs to enumerate, monitor and use the resources available on the managed node, including CPUs, memory, storage, networking, and NUMA partitions.
So libvirt is intended to be a building block for higher level management tools and for applications focusing on virtualization of a single node (the only exception being domain migration between node capabilities which involves more than one node).
2, relationship between QEMU & KVM (chinese)

http://blog.chinaunix.net/uid-23769728-id-3256677.html


QEMU is an independent virtualization tool/env, it can work without KVM. but if we have KVM and hardware(CPU) support (e.g. Intel VT), QEMU can use KVM to improve the performance in CPU virtualization.


KVM has two kernel modules: kvm.ko & kvm_intel.ko(kvm_amd.ko), these modules are used to provide CPU virtualization. for others, like IO virtuzalition, KVM based on QEMU's solution, all in all, it's qemu-kvm. KVM has dependency on QEMU.