about summary refs log blame commit diff stats
path: root/tools/gitolite.html
blob: 141f3231b2c321e014ee0395ee5b25ddbbcf4343 (plain) (tree)
1
2
3
4
5
6
7
8
9



                              
                               



                                            
                         
 
                                                 

                                                                            
 



                                  
                                                  
 
                                              

             
                                                                 






                                                   


                         
 


                                                   


                                                           

             








                                                                                    



















                                                                                          
                                                              

              
                                                      





                                                                                                    
                                            

              
                                           



















                                                                                                
                                           




                                                                   
                                







                                              
                                   






                                                
                                                
 
                                      




                                                             
                                  


                                         

                                                    
















                                                   


                                
 


                                                      
 

                                                           
                                                          
 

                                                          
 

                                                  

                                                          

                                                            

                                     
                                                 








                               
                                        




                                                         
                             




                                                      
                









                                   



                                        
                        



                                                                        
                                             
 





















                                                                                         


                                                                                                            

                                                                                             








                                                                  



                                               
                                                        





                                            




                                                                         


                       

                                                   

              
                                                            
 

                                                                  
 





























                                                                                
 
                 
                                                                                                                   

             
                   


                                                                              
                                                                   
         





                                                                          
 
                                                                              
 
 








                                                                       
 















                                                                                

              

                                                                                                     

             
                   
 
                   
 


                           
 


                                      
 



                                                           
 


                                                
 


                                           
 



                                                         
 



                                                                        
              

























                                                                                                  
 
          
 




                                                                 
 

                                                                             
 


                                 
 


                                                                                       
 




                                                           
 
                                                    
 






                                                                                      
 
             

                                       

              
                                     
 



                                                                                                       
 




































































































































































                                                                                    
 








                                                                           
                                                               
 


                    
 



                                              
 
                              
                                                  
                     
                                                                 
 



                                                                     
 

                     
 




















                                                                                                                   
                                      
 
             

                                                        
              
 
                                      
 
                                    
 
             
                                              
 
                                                           
                                                                             
                                                        
 

                                                                                                       

                                                
              
 
                                     
 
                                                                              
 
             

                 
              
 


                                                                           
             


                                                           

              

                                                                                
 
                    
             
                                          

              




                                          


                                                                     
             







                                                                        
 




                                  
 
                                        
 

















                                                                                
                                                       

              


                                                      



                                                         
 



                                                        

              

                                             



                                                                                            


           
<!DOCTYPE html>
<html dir="ltr" lang="en">
    <head>
        <meta charset='utf-8'>
        <title>Gitolite</title>
    </head>
    <body>

        <a href="index.html">Tools Index</a>
        <h1>Gitolite</h1>

        <h2 id="install">1. Install Gitolite</h2>

        <p>Install <a href="../ports/gitolite/">Gitolite port</a> first;</p>

        <pre>
        $ prt-get depinst gitolite
        </pre>

        <h2 id="config">2. Configure Gitolite</h2>

        <p>Create user and home directory;</p>

        <pre>
        # useradd -r -s /bin/bash -U -m -d /srv/gitolite gitolite
        # chown gitolite:gitolite /srv/gitolite
        </pre>

        <p>Password is necessary so the user is not
        locked and can login via ssh. This password
        will not be used.</p>

        <pre>
        # passwd gitolite
        </pre>

        <p>Copy public key that will be used for
        authenticating gitolite administrator, read
        <a href="openssh.html#ssh">ssh</a> how to
        create one, key don't need to have password.
        If the server is on remote a remote
        machine you can use scp to copy the public key;</p>

        <pre>
        $ scp /home/bob/.ssh/gitolite.pub admin@core.privat-network.net:/home/admin/
        bob@core.privat-network.net's password:
        gitolite.pub                              100%  390     0.4KB/s   00:00
        </pre>

        <p>Then on remote machine;</p>

        <pre>
        # cp /home/admin/gitolite.pub /srv/gitolite.pub
        </pre>

        <pre>
        # su - gitolite
        $ gitolite setup -pk gitolite.pub
        Initialized empty Git repository in /srv/gitolite/repositories/gitolite-admin.git/
        Initialized empty Git repository in /srv/gitolite/repositories/testing.git/
        WARNING: /srv/gitolite/.ssh missing; creating a new one
        (this is normal on a brand new install)
        WARNING: /srv/gitolite/.ssh/authorized_keys missing; creating a new one
        (this is normal on a brand new install)
        $
        </pre>

        <pre>
        $ rm gitolite.pub
        $ exit
        </pre>

        <pre>
        $ ssh -v -i ~/.ssh/gitolite gitolite@localhost -p 2222
        </pre>

        <h2 id="admin">3. Gitolite Administration</h2>

        <p>Read how to setup <a href="openssh.html#sshid">ssh identities</a>,
        <a href="http://gitolite.com/gitolite/gitolite.html#basic-admin">gitolite documentation</a>.
        Start by cloning gitolite-adimin;</p>

        <pre>
        $ git clone git-admin:gitolite-admin
        </pre>

        <h3>3.1. Recover Admin Account</h3>

        <p>First copy the key to remote server, in this example key is on
        same server;</p>

        <pre>
        # install -o gitolite -g gitolite /home/bob/.ssh/gitolite.pub /srv/gitolite/gitolite.pub
        </pre>

        <p>Update gitolite key with new key;</p>

        <pre>
        # su - gitolite
        $ gitolite setup -pk gitolite.pub
        </pre>

        <pre>
        $ rm gitolite.pub
        $ exit
        </pre>

        <h3 id="adminusers">3.2. Users</h3>

        <p>Gitolite helps add and remove users from authorized_keys
        by allowing add or remove keys from keydir directory in
        clone.</p>

        <h4>3.2.1. Add User</h4>

        <pre>
        $ mv bob.pub keydir/
        $ git add keydir
        $ git commit -m "Added bob public key"
        $ git push
        </pre>

        <h4>3.2.2. Remove User</h4>

        <pre>
        $ git rm keydir/bob.pub
        $ git commit -m "Removed bob public key"
        $ git push
        </pre>

        <h3 id="adminrep">3.3. Repositories</h3>

        <h4>3.3.1. Add Repository</h4>

        <p>Add repository atom and user bob to devteam group,
        edit conf/gitolite.conf;</p>

        <pre>
        @guests         =   gitweb
        @interns        =   bob alice
        @dev            =   fred mary joe
        @teamleads      =   mary
        @staff          =   @interns @dev @teamleads

        repo  @secret
            - = @guests
            option deny-rules = 1

        repo @floss
            RW+                     =   @dev @staff
            R                       =   @all

        repo @project
            RW+                     =   @teamleads
            -   master              =   @dev
            -   refs/tags/v[0-9]    =   @dev
            RW+ develop/            =   @dev
            RW+ feature/            =   @dev
            RW+ hot-fix/            =   @dev
            RW                      =   @dev
            R                       =   @interns

        repo gitolite-admin
            RW+     =   gitolite

        repo doc ports pmwiki assistant
            config gitweb.owner         =   "Team"
            config gitweb.category      =   "Projects"

        repo doc
            config gitweb.description   =   "Documentation"
            option hook.post-receive     =  deploy-web-doc

        repo ports
            config gitweb.description   =   "System Ports"

        repo pmwiki
            config gitweb.description   =   "Wiki"
            option hook.post-receive     =  deploy-web-doc

        repo assistant
            config gitweb.description   =   "Open Assistant"

        @secret    =   gitolite-admin
        @project   =   doc ports pmwiki assistant
        </pre>

        <p>Commit and push;</p>

        <pre>
        $ git add -u
        $ git push
        </pre>

        <h4>3.3.2 Rename Repository</h4>

        <p>Rename rep void to sysdoc, on remote host;</p>

        <pre>
        # cd /srv/gitolite/repositories/
        # mv void.git doc.git
        </pre>

        <p>On workstation edit conf/gitolite.conf;</p>

        <pre>
        repo doc
                RW+     =       bob
        </pre>

        <p>Commit and push;</p>

        <pre>
        $ git add -u
        $ git push
        </pre>

        <h4>3.3.3 Delete Repository</h4>

        <pre>
        # cd /srv/gitolite/repositories/
        # rm -rf doc.git
        </pre>

        <p>On workstation edit conf/gitolite.conf and remove c9-doc.</p>

        <h2 id="hooks">4. Gitolite Hooks</h2>

        <p>This document creates three scripts, one is run when gitolite receives
        push to a project with hook active, second script is run under root
        user to allow operations where gitolite user have no rights, third one
        is project specific.</p>

        <p>This example try to have a separate creation of a package and its deployment,
        in case deploy script is not on the same machine other method can be used to send
        the package.</p>

        <p>A normal package will have a files.tar with all or new files to extract,
        if necessary a deleted file with the list of files to be removed and a
        project file with data about the package like new hash commit, or witch
        script to call to deploy.</p>

        <p>Package is created under gitolite
        <a href="conf/srv/gitolite/hook.sh">/srv/gitolite/deploy/hook.sh</a>
        script and
        <a href="conf/srv/gitolite/deploy.sh">/srv/gitolite/deploy/deploy.sh</a>,
        deploy in this example is called called by cron.</p>

        <h3 id="gtl-activate">4.1. Activate Hooks</h3>

        <p>Example from
        <a href="http://gitolite.com/gitolite/cookbook.html#v3.6-variation-repo-specific-hooks">Cookbook</a>
        how to apply hooks only to certain repos. Uncomment or add
        this line on <a href="conf/srv/gitolite/.gitolite.rc">/srv/gitolite/.gitolite.rc</a>,
        within the %RC block;</p>

        <pre>
        LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local",
        </pre>

        <p>Uncomment the 'repo-specific-hooks' line in the rc file
        or add it to the ENABLE list if it doesn't exist.</p>

        <pre>
        # allow repo-specific hooks to be added
        'repo-specific-hooks',
        </pre>

        <p>Create directory on gitolite-admin clone;</p>

        <pre>
        $ cd ~/gitolite-admin
        $ mkdir -p local/hooks/repo-specific
        </pre>

        <p>Now add your hooks to that directory, but instead of using the
        git "standard" names (pre-receive, post-receive, post-update),
        you use descriptive names (e.g. "deploy", "RSS-post", etc).</p>

        <p>On remote run;</p>

        <pre>
        # su - gitolite
        $ mkdir .gitolite/local/hooks/repo-specific
        $ gitolite setup
        </pre>

        <h3 id="gtl-deploy">4.2. Deploy and Hook script</h3>

        <p>Create deploy directory on remote, /srv/gitolite/deploy
        was chosen to have less impact on the package system;</p>

        <pre>
        $ sudo -u gitolite mkdir /srv/gitolite/deploy
        </pre>

        <p>Script
        <a href="conf/srv/gitolite/hook.sh">/srv/gitolite/deploy/hook.sh</a>
        receives call create_package "project-name" "git-dir"
        "valid oldrev/invalid" "newrev" "script/to/call.sh" from gitolite hook
        and creates a package.</p>

        <pre>
        $ sudo -u gitolite cp conf/srv/gitolite/hook.sh /srv/gitolite/deploy/
        </pre>

        <p>Script
        <a href="conf/srv/gitolite/deploy.sh">/srv/gitolite/deploy/deploy.sh</a>
        loops for each package, extracts, order commit hashes to create final
        snapshot of files and call script to handle deploy.</p>

        <pre>
        $ sudo -u gitolite cp conf/srv/gitolite/deploy.sh /srv/gitolite/deploy/
        </pre>

        <h3 id="gtl-setup">4.3. Setup project hook</h3>

        <p>Project hooks create a package by calling hook.sh script and
        deploy a package being called by deploy.sh. Deploy script is a
        simple example that handle multiple web projects.</p>

        <h4>4.3.1. Hook Script</h4>

        <p>Create
        <a href="conf/srv/gitolite/deploy-web-doc">gitolite-admin/local/hooks/repo-specific/deploy-web-doc</a>;</p>

        <pre>
        #!/bin/bash
        ######################################################################
        #
        # Put this file in your gitolite-admin;
        # ~/gitolite-admin/local/hooks/repo-specific/deploy-web-doc
        #
        # set host to empty to create package for each push
        # or set remote host to create package based on last deployed push
        # host="https://doc.localhost"
        host=""
        # set name of witch branch should be deployed
        branch_to_deploy="deploy_branch"

        ######################################################################


        url="$host/.last_deploy"
        source /srv/gitolite/deploy/hook.sh
        read oldrev newrev refname
        push_branch=$(git rev-parse --symbolic --abbrev-ref $refname)

        #SCRIPT_VARS=$(set)
        #echo "project: $PROJECT"
        #echo "local dir: $PWD" &gt; /srv/gitolite/deploy/${GL_REPO}
        #echo "${SCRIPT_VARS}" &gt;&gt; /srv/gitolite/deploy/${GL_REPO}

        if [[ $push_branch = $branch_to_deploy  ]]; then

            # if host empty we make local tracking
            if [[ $host = "" ]]; then
                if [[ $(is_initial ${GL_REPO}) = "true" ]]; then
                    oldrev="initial"
                fi
            else
                if [[ ! $(valid_url $url) = "true" ]]; then
                    echo "Deploy: set $url on remote to start creating packages"
                    exit 1
                fi
                oldrev=$(get_remote_rev $url)
            fi
            create_package ${GL_REPO} ${PWD} ${oldrev} ${newrev} "deploy-web.sh"
        fi
        </pre>

        <p>Create
        <a href="conf/srv/gitolite/deploy-web.sh">/srv/gitolite/deploy/scripts/deploy-web.sh</a>;</p>

        <pre>
        #!/bin/bash

        pkg_path=$1

        www_root="/srv/www"
        www_user="nginx"
        www_group="www"

        pkg_file="${pkg_path}/project"
        pkg_rm="${pkg_path}/deleted"
        pkg_files="${pkg_path}/files"

        if [ ! -f ${pkg_file} ]; then
            echo "Deploy web: invalid pkg_file ${pkg_file}"
            exit 1
        fi

        pkg_name=$(head -1 ${pkg_file})
        pkg_new=$(head -3 ${pkg_file} | tail -1)
        pkg_new7=$(echo ${pkg_new} | cut -c1-7)

        pkg_www="${www_root}/${pkg_name}"
        pkg_back="${pkg_www}/backup_deploy"
        pkg_last="${pkg_www}/.last_deploy"

        if [ ! -d ${pkg_www} ]; then
            echo "Deploy web: invalid pkg_www ${pkg_www}"
            exit 1
        fi

        # first backup all data
        if [[ ! $(ls ${pkg_www} | grep -v "backup_deploy") = "" ]]; then
            if [ ! -d ${pkg_back} ]; then
                sudo -u ${www_user} mkdir -p ${pkg_back}
            fi
            backup_file="${pkg_back}/${pkg_name}-$(date '+%Y-%j-%H-%M-%S').tar.gz"
            echo "Deploy web: making backup ${backup_file}"
            sudo -u ${www_user} tar --exclude ${pkg_back} --xattrs -zcpf ${backup_file} ${pkg_www}
        fi

        # remove files and directories that have been deleted
        if [ -f ${pkg_rm} ]; then

            echo "Deploy web: files to delete:"
            # first we delete files
            while read deleted_file; do
                deleted_file="${pkg_www}/${deleted_file}"
                if [ -f ${deleted_file} ]; then
                    echo "file      rm ${deleted_file}"
                    rm ${deleted_file}
                fi
            done &lt;${pkg_rm}

            # delete directories
            while read deleted_file; do
                deleted_file="${pkg_www}/${deleted_file}"
                if [ -d ${deleted_file} ]; then
                    echo "file      rm ${deleted_file}"
                    rm ${deleted_file}
                fi
            done &lt;${pkg_rm}

        fi

        # copy new files to destination
        if [ -d ${pkg_files} ]; then
            echo "Deploy web: cp from ${pkg_files} to ${pkg_www}"
            sudo -u ${www_user} cp -r ${pkg_files}/* ${pkg_www}
        fi

        echo ${pkg_new} > ${pkg_last}
        echo "Deploy: scripts/deployweb.sh ${pkg_name} ${pkg_new7} deployed."

        #remove temporary package
        rm -r ${pkg_path}
        </pre>

        <p>Activate this hook, the idea is to start with this one as a template working
        and then implement the final one. Edit gitolite admin configuration file and
        activate:</p>

        <pre>
        repo doc
            config gitweb.description   =   "Documentation"
            option hook.post-receive     =  deploy-web-doc
        </pre>

        <p>Add, commit, and push the admin repo;</p>

        <pre>
        $ git add local/hooks/repo-specific/hook-deployweb
        $ git add -u && git commit -m "added deploy c9 hook"
        </pre>

        <p>Now we can test if our script is functioning by creating a branch on c9-doc
        making a random change and push;<p>

        <pre>
        $ cd c9-doc
        $ git checkout -b deploy_branch
        </pre>

        <h4>4.3.2. Deploy Script</h4>

        <p>Create <a href="conf/srv/gitolite/deploy.sh">/srv/gitolite/deploy/scripts/deploy.sh</a>;</p>

        <pre>
        #!/bin/bash

        # origin package directory
        packages_dir="/srv/gitolite/deploy/packages"
        # temporary work directory
        deploy_dir="/srv/gitolite/deploy/deploy_dir"
        # scripts to deploy packages
        deploy_scripts="/srv/gitolite/deploy/scripts"

        function get_script(){
            # receives package path return script to call
            local pkg_path=$1
            echo $(head -2 ${pkg_path}/project | tail -1)
        }

        function get_new(){
            # receives package path return commit hash (new)
            local pkg_path=$1
            echo $(head -3 ${pkg_path}/project | tail -1)
        }

        function get_dep(){
            # receives package path return previews commit hash (old)
            local pkg_path=$1

            new=$(head -3 ${pkg_path}/project | tail -1)
            old=$(head -4 ${pkg_path}/project | tail -1)

            if [[ ! ${new} = ${old} ]]; then
                echo ${old} | cut -c1-7
            fi
        }

        function project_extract(){

            # project directory containing extracted packages
            local prj_dir=$1

            # final extracted package
            local prj_pkg="${prj_dir}/package"

            # temporary vars for swapping/iterating pkg_news
            local pkg_new=""
            local pkg_old=""
            local pkg_dir=""
            local pkg_temp=""
            local pkg_next=1
            local pkg_del=""
            local x=0
            local y=0

            # array with all the news hashes
            local pkg_news=($(ls ${prj_dir}))

            # total new packages
            local total=${#pkg_news[@]}

            echo "Deploy: $(basename ${prj_dir}) extracting packages ${pkg_news[*]}"

            # find first package
            for pkg_new in ${pkg_news[@]}
            do
                # get package dependency
                pkg_dir="${prj_dir}/${pkg_new}"
                pkg_old=$(get_dep ${pkg_dir})
                if [[ ! " ${pkg_news[@]} " =~ " ${pkg_old} " ]]; then
                    # pkg_news don't contain package
                    # we found initial package
                    pkg_temp=${pkg_news[0]}
                    pkg_news[0]=${pkg_new}
                    pkg_news[${x}]=${pkg_temp}
                    break
                fi
                x=$((${x}+1))
            done

            # Order packages by dependency start with first package
            for (( y=0; y&lt;${total}; y++ ))
            do
                pkg_next=$(($y+1))
                if [[ ${pkg_next} = ${total} ]]; then
                    ## we are in the last one
                    break
                fi

                pkg_new=${pkg_news[$y]}
                for (( x=pkg_next; x&lt;${total}; x++ ))
                do
                    pkg_dir="${prj_dir}/${pkg_news[${x}]}"
                    pkg_old=$(get_dep ${pkg_dir})
                    # is dependent on current
                    if [[ ${pkg_old} = ${pkg_new} ]]; then
                        pkg_temp=${pkg_news[${pkg_next}]}
                        pkg_news[${pkg_next}]=${pkg_news[${x}]}
                        pkg_news[${x}]=${pkg_temp}
                        # we can break and pass next one
                        break
                    fi
                done
            done

            # create project final package directory
            mkdir -p ${prj_pkg}/files

            # copy project information of last commit
            cp ${prj_dir}/${pkg_news[$((${total}-1))]}/project ${prj_pkg}

            # now that packages are ordered we can start creating files
            for pkg_new in ${pkg_news[@]}
            do
                pkg_dir=${prj_dir}/${pkg_new}
                tar xf ${pkg_dir}/files.tar.xz \
                    --directory ${prj_pkg}/files

                # if deleted files exists
                if [ -f "${pkg_dir}/deleted" ]; then
                    # first collect all files/directories don't exist
                    while read pkg_del; do
                        # if file don't exist add entry to project deleted file
                        pkg_temp="${prj_pkg}/files/${pkg_del}"
                        if [ ! -f ${pkg_temp} ]; then
                            if [ ! -d ${pkg_temp} ]; then
                                # is not a file or directory from previous packages
                                echo ${pkg_del} &gt;&gt; ${prj_pkg}/deleted
                            fi
                        fi
                    done &lt;${prj_dir}/${pkg_new}/deleted

                    # delete directories and files
                    while read pkg_del; do
                        pkg_temp="${prj_pkg}/files/${pkg_del}"
                        if [ -d ${pkg_temp} ]; then
                            rm -r ${pkg_temp}
                        elif [ -f ${pkg_temp} ]; then
                            rm ${pkg_temp}
                        fi
                    done &lt;${prj_dir}/${pkg_new}/deleted
                fi

                #remove temporary directory
                rm -r ${prj_dir}/${pkg_new}
            done

            # call project deploy script
            call_script=${deploy_scripts}/$(get_script $prj_pkg)
            echo "Deploy: calling deploy script: ${call_script}"
            /bin/bash ${call_script} ${prj_pkg}

        }

        if [[ ! $(ls ${deploy_dir}) = "" ]]; then
            rm -r ${deploy_dir}/*
        fi

        # first extract all packages from origin directory
        for pkg_path in `find ${packages_dir} -type f -name "*.tar.gz"`
        do
            if [ -f ${pkg_path} ]; then
                pkg_name=$(basename ${pkg_path})
                pkg_proj=$(echo ${pkg_name} | cut -d "_" -f 1)
                pkg_new7=$(echo ${pkg_name} | tail -c -15 | cut -c -7)
                pkg_temp=${deploy_dir}/${pkg_proj}/${pkg_new7}
                mkdir -p ${pkg_temp}
                tar xf ${pkg_path} --directory ${pkg_temp}
                rm ${pkg_path}
            fi
        done

        # loop for all projects and deploy them
        for prj_dir in `find ${deploy_dir} -maxdepth 1 -mindepth 1 -type d`
        do
            # order index of hashes based on old commit
            echo "prj_dir $prj_dir"
            project_extract ${prj_dir}
        done
        </pre>
        
        <p>Add cron job to call deploy script every minute;</p>

        <pre>
        # crontab -e
        </pre>

        <pre>
        #
        # /etc/crontab: crond(8) configuration
        #

        # this way it will log
        # * * * * * /srv/gitolite/deploy/deploy.sh
        # without log
        * * * * * /srv/gitolite/deploy/deploy.sh > /dev/null 2>&1

        @hourly   ID=sys.hourly   /usr/sbin/runjobs /etc/cron/hourly
        @daily    ID=sys.daily    /usr/sbin/runjobs /etc/cron/daily
        @weekly   ID=sys.weekly   /usr/sbin/runjobs /etc/cron/weekly
        @monthly  ID=sys.monthly  /usr/sbin/runjobs /etc/cron/monthly

        # End of file
        </pre>

        <h4>4.3.3. Debuging hooks</h4>

        <p>Comment gitolite admin repo script "if" and uncomment debug sections, this allow to
        source the file with environment of hook.</p>

        <p>Later you can delete this branch locally and remote and start fresh. To test
        if hook is called each time you push run;</p>


        <pre>
        $ echo $(( ( RANDOM % 10 ) +1 )) >> index.html && git add -u && git commit -m "test deploy" && git push git
        </pre>

        <p>See if a file was created in /srv/gitolite/deploy with name of project and
        with environmental variables of gitolite script.</p>

        <p>From now on you can test changes directly on
        /srv/gitolite/.gitolite/local/hooks/repo-specific/hook-deployweb
        and repeat above command to see the results or create a separate script with
        all variables generated by above script set so you don't have to push at all.</p>

        <h2 id="gitweb">5. Gitweb</h2>

        <pre>
        $ prt-get depinst p5-cgi p5-cgi-session libcgi \
                        fcgiwrap spawn-fcgi highlight
        </pre>

        <h3>5.1. Configure gitweb</h3>

        <p>Edit /etc/gitweb.conf</p>

        <pre>
        our $git_temp = "/srv/www/gitweb_tmp";

        our $projects_list = "/srv/gitolite/projects.list";
        # The directories where your projects are. Must not end with a slash.
        our $projectroot = "/srv/gitolite/repositories";

        # Base URLs for links displayed in the web interface.
        our @git_base_url_list = qw(git://core.privat-network.com http://git@core.private-network.com);

        our $projects_list_group_categories = 1;
        </pre>

        <h3>5.2. Configure nginx</h3>

        <p>Edit /etc/rc.d/fcgiwrap to run as www user member of www group;</p>

        <pre>
        USER=www
        GROUP=www
        </pre>

        <p>Permissions for /srv/gitolite/repositories directories should be
        0750/drwxr-x---.</p>

        <pre>
        $ chown gitolite:www /srv/gitolite
        $ chown -R gitolite:www /srv/gitolite/projects.list
        $ chown -R gitolite:www /srv/gitolite/repositories
        </pre>

        <p>A link from gitweb don't work under grsecurity since user www can't
        follow simlink to root. Make a copy, later deploy via gitolite hook.</p>

        <p>Link;</p>
        <pre>
        # ln -s /usr/share/gitweb /srv/www
        </pre>

        <p>Copy;</p>
        <pre>
        # cp -r /usr/share/gitweb /srv/www
        </pre>

        <p>Add this to default or main
	<a href="nginx.html#virtual-host">nginx virtual host</a>;</p>

        <pre>
	location /gitweb/gitweb.cgi {
            alias /srv/www/gitweb;
	    include fastcgi_params;
	    gzip off;
	    fastcgi_param   SCRIPT_FILENAME  /srv/www/gitweb/gitweb.cgi;
	    fastcgi_param   GITWEB_CONFIG    /etc/gitweb.conf;
	    fastcgi_pass    unix:/var/run/fcgiwrap.sock;
	}

	location /gitweb {
	    alias /srv/www/gitweb;
	    index gitweb.cgi;
	}
	</pre>

        <h3>5.3. Configure gitolite</h3>

        <p>Edit
        <a href="conf/srv/gitolite/.gitolite.rc">/srv/gitolite/.gitolite.rc</a>,
        change UMASK and GIT_CONFIG_KEYS to;</p>

        <pre>
        # default umask gives you perms of '0700'; see the rc file docs for
        # how/why you might change this
        UMASK                           =>  027,

        # look for "git-config" in the documentation
        GIT_CONFIG_KEYS                 =>  '.*',
        </pre>

        <p>Fix permissions;</p>

        <pre>
        $ sudo chown -R gitolite:gitolite /srv/gitolite
        $ sudo chmod g+rx /srv/gitolite/projects.list
        $ sudo chmod -R 755 /srv/gitolite/repositories/
        </pre>

        <p>Edit gitolite-admin/conf/gitolite.conf;</p>

        <pre>
        repo doc
            config gitweb.owner         =   team
            config gitweb.description   =   Documentation
            config gitweb.category      =   Projects

        repo ports
            config gitweb.owner         =   team
            config gitweb.description   =   System ports
            config gitweb.category      =   Projects
        </pre>

        <a href="index.html">Tools Index</a>
        <p>This is part of the c9-doc Manual.
        Copyright (C) 2016
        c9 team.
        See the file <a href="../fdl-1.3-standalone.html">Gnu Free Documentation License</a>
        for copying conditions.</p>

    </body>
</html>