取势 明道 优术

作者为 扶 凯 发表

自从  Perl 界出来 PSGI 的协议,大量的基于这种协议的应用都出来了,无论是性能,还是功能,还是开发速度.都有了极为大的提升.象前几天,我做了一个基于 IP 的视频文件的 GSLB. 用来做基于用户 IP 的视频访问调度的系统.原来是使用 Nginx 加 Lua 开发,性能是不错,但周期非常有点小长.后来重新使用这种 Plack 的一个高性能的后端 feersum. 花了一天时间就重新开发了一个,目前可以每秒处理 10k 的调度请求的应用.所以基于 Plack 来实现各种接口和应用相当的容易和高效.

这次要推荐的是一个简单的 Git 的 HTTP 服务器.这样不用做 key ,不用搞得很麻烦。我们知道,平时最常使用的是 github .但 github 私有项目是必须收费的,所以并不合适公司使用.因为收费和服务器在国外.所以这时我们常常需要自建 Git 的服务器.这时必须推荐一的一个 Perl 的模块是 Plack-App-GitSmartHttp. 安装和配置都超级容易.还非常容易扩展.这个小日本也在 Fukuoka Perl Workshop 上推荐过这个模块.讲实话,这个模块去年刚出第一版时我就知道,一直想分享和推荐给大家来着.


默认 Git 只支持 git:// 和 ssh://.只有在 git 1.6.6 后才支持使用 http 协议.

安装

安装这个非常容易,还是使用伟大的 cpanm 来安装.一条命令搞定安装.比安装 apache 什么的都方便.

cpanm Plack::App::GitSmartHttp


建立空的索引库

记得先要使用 git 的命令建个空的 repos.

$cd /data/git
$ mkdir  newrepos.git
$ cd newrepos.git
$ git init --bare

简单配置

其实就是一个 Perl 程序,这个可以让大家体会到强大的 Perl 模块.

#!/usr/bin/perl
use strict;
use Plack::App::GitSmartHttp;

Plack::App::GitSmartHttp->new(
    root            => '/data/git',
    upload_pack     => 1, # clone
    received_pack   => 1, # push
)->to_app;


测试clone功能:

$ git clone http://www.servername.com/newproject.git

高级应用
我们还可以使用 Plack::Middleware::Auth 系列的模块来做增强的各种认证和控制.写个小例子给大家参照一下.

#!/usr/bin/perl
use strict;
use Plack::Builder;
use Plack::App::GitSmartHttp;

my $git = Plack::App::GitSmartHttp->new(
    root            => '/data/git',
    upload_pack     => 1, # clone
    received_pack   => 1, # push
);
my %user = (
    'fukai'    => 'test', 
    'test1'   => 'test', 
);

builder {
    enable "Auth::Basic", authenticator => sub {
        my($username, $password) = @_;
        return 1 if exists $user{$username} and $user{$username} eq "$password";
    };
    $git;
};

这时需要修改一下你的 push 的 url 支持用户名.象我的项目的话,我进入项目的目录.

/usr/libexec/git-core/git-config remote.upload.url http://fukai@git.servername.com/newproject.git

这样以后,每次提交都会提示你输入密码.
在写一个配合可以根据每个用户设置权限的小例子

#!/usr/bin/perl
use strict;
use Plack::Builder;
use Plack::App::URLMap;
use Plack::App::GitSmartHttp;
use Plack::Middleware::Auth::Basic;

my %user_list = (
    user1  => 'pass',
    user2  => 'pass',
);

my $app = Plack::App::URLMap->new;

# 单独的用户认证和访问地址 
for my $user (keys %user_list) {  
    my $user_path = "$user.git";
    my $git_app = Plack::App::GitSmartHttp->new(
        root            => "/data/git/$user_path",
        upload_pack     => 1, # clone
        received_pack   => 1, # push
    );
    $git_app = Plack::Middleware::Auth::Basic->wrap(
                    $git_app, authenticator => sub {
                        my($username, $password) = @_;
                        return 1 if $username eq $user and $user_list{$user} eq $password;
                    } 
                );
    $app->mount("/$user_path" => $git_app ); 
}

$app;

如果想git 多用户分组管理同一个项目,也是非常容易的。

my $authority_list = {
    'squid.git' => {
        'user1' => {
            pass  => 'user2pass',
        },
    },
    'nginx.git' => {
        'user2'   => {
            pass => 'user2pass',
        },
    },
};
my $app = Plack::App::URLMap->new;
# 用户认证和访问地址 
foreach my $git_path (keys %$authority_list) {   
    my $git_app = Plack::App::GitSmartHttp->new(
        root            => "/data/git/" . $git_path,
        upload_pack     => 1, # clone
        received_pack   => 1, # push
    );  
    $git_app = Plack::Middleware::Auth::Basic->wrap(
        $git_app, authenticator => sub {
            my($username, $password) = @_; 
            my $git_user = $authority_list->{$git_path}{$username} || ''; 
            return 1 if $git_user and $git_user->{pass} eq $password;
        }   
    );  
    $app->mount("/$git_path" => $git_app );  
}

$app;

 

来了就留个评论吧! 2个评论



    Blackrose 2013年01月17日 的 11:26

    你好,我运行那个配置perl程序后,出现http://0:80,请问ip地址在哪里设置?谢谢

      扶 凯 2013年01月19日 的 07:21

      plackup -s Starman -p 500 git.psgi -D

      其中 p 就是端口,建议使用 Starman 来做 Web 服务器就好了