10
25
2017

Planex 2.1.0 在 Fedora 26 上的安装

Planex 是维护本地 yum 源批量重构的工具,可用于维护第三方源或定制发行版。在某个基础包发生变化时,会按需自动重构所有依赖这个基础包的其它包。

  • 预先已经准备好 mock 的环境和用户(下面设为 cheese)

一、安装 planex

二、从头创建 planex 项目环境(构建两个 rpm)

  • 初始化目录结构
    • mkdir buildenv
    • cd buildenv
    • planex-init
      • 运行之后会创建一个 Makefile 文件
    • mkdir SPECS
    • ln -s _build/RPMS .
  • 根据当前默认 mock root 修改 Makefile
    • ls -l /etc/mock/default.cfg
lrwxrwxrwx. 1 root root 20 Oct 25 17:23 /etc/mock/default.cfg -> fedora-26-x86_64.cfg
  • 因此要修改 Makefile 变成 DIST?=.fc26
  • 将下面两个文件分别保存成对应的 spec 文件,放置于 SPECS 目录
Name:           perl-Furl
Version:        3.03
Release:        1%{?dist}
Summary:        Lightning-fast URL fetcher
License:        GPL+ or Artistic
Group:          Development/Libraries
URL:            http://search.cpan.org/dist/Furl/
Source0:        http://www.cpan.org/authors/id/T/TO/TOKUHIROM/Furl-%{version}.tar.gz
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildArch:      noarch
BuildRequires:  perl-generators
BuildRequires:  perl(Class::Accessor::Lite)
BuildRequires:  perl(Compress::Raw::Zlib)
BuildRequires:  perl(Encode)
BuildRequires:  perl(File::Temp)
BuildRequires:  perl(HTTP::CookieJar)
BuildRequires:  perl(HTTP::Parser::XS) >= 0.11
BuildRequires:  perl(IO::Socket::SSL)
BuildRequires:  perl(Module::Build)
BuildRequires:  perl(Mozilla::CA)
BuildRequires:  perl(Net::IDN::Encode)
BuildRequires:  perl(Scalar::Util)
BuildRequires:  perl(Socket)
BuildRequires:  perl(Test::More) >= 0.96
BuildRequires:  perl(Test::Requires)
BuildRequires:  perl(Test::TCP) >= 1.06
BuildRequires:  perl(Time::HiRes)
# Required for extra tests
BuildRequires:  perl(HTTP::Proxy)
BuildRequires:  perl(IO::Callback)
BuildRequires:  perl(Starlet)
BuildRequires:  perl(HTTP::Proxy::HeaderFilter::simple)
BuildRequires:  perl(Test::Fake::HTTPD)
Requires:       perl(Class::Accessor::Lite)
Requires:       perl(Compress::Raw::Zlib)
Requires:       perl(Encode)
Requires:       perl(HTTP::CookieJar)
Requires:       perl(HTTP::Parser::XS) >= 0.11
Requires:       perl(IO::Socket::SSL)
Requires:       perl(Mozilla::CA)
Requires:       perl(Net::IDN::Encode)
Requires:       perl(Scalar::Util)
Requires:       perl(Socket)
Requires:       perl(Time::HiRes)
Requires:       perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))

%description
Furl is yet another HTTP client library. LWP is the de facto standard HTTP
client for Perl 5, but it is too slow for some critical jobs, and too
complex for weekend hacking. Furl resolves these issues. Enjoy it!

%prep
%setup -q -n Furl-%{version}

%build
%{__perl} Build.PL installdirs=vendor
./Build

%install
rm -rf $RPM_BUILD_ROOT

./Build install destdir=$RPM_BUILD_ROOT create_packlist=0
find $RPM_BUILD_ROOT -depth -type d -exec rmdir {} 2>/dev/null \;

%{_fixperms} $RPM_BUILD_ROOT/*

%check

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root,-)
%doc Changes cpanfile LICENSE META.json README.md TODO
%{perl_vendorlib}/*
%{_mandir}/man3/*

%changelog
* Sat Sep 13 2014 Robin Lee <cheeselee@fedoraproject.org> 3.03-1
- Specfile autogenerated by cpanspec 1.78.
Name:           perl-IO-Callback
Version:        1.12
Release:        1%{?dist}
Summary:        IO::Callback Perl module
License:        GPL+ or Artistic
Group:          Development/Libraries
URL:            http://search.cpan.org/dist/IO-Callback/
Source0:        http://www.cpan.org/authors/id/T/TO/TOBYINK/IO-Callback-%{version}.tar.gz
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildArch:      noarch
BuildRequires:  perl-interpreter >= 0:5.006
BuildRequires:  perl-generators
BuildRequires:  perl(Carp)
BuildRequires:  perl(Fatal)
BuildRequires:  perl(File::Slurp)
BuildRequires:  perl(File::Temp)
BuildRequires:  perl(IO::String)
BuildRequires:  perl(Module::Build)
BuildRequires:  perl(Test::Exception)
BuildRequires:  perl(Test::More)
BuildRequires:  perl(Test::NoWarnings)
# required for extra tests
#BuildRequires:  perl(Pod::Snippets)
Requires:       perl(Carp)
Requires:       perl(IO::String)
Requires:       perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))

%description
"IO::Callback" provides an easy way to produce a phoney read-only
filehandle that calls back to your own code when it needs data to satisfy a
read. This is useful if you want to use a library module that expects to
read data from a filehandle, but you want the data to come from some other
source and you don't want to read it all into memory and use IO::String.

%prep
%setup -q -n IO-Callback-%{version}

%build
%{__perl} Build.PL installdirs=vendor
./Build

%install
rm -rf $RPM_BUILD_ROOT

./Build install destdir=$RPM_BUILD_ROOT create_packlist=0
find $RPM_BUILD_ROOT -depth -type d -exec rmdir {} 2>/dev/null \;

%{_fixperms} $RPM_BUILD_ROOT/*

%check

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root,-)
%doc Changes META.json README
%{perl_vendorlib}/*
%{_mandir}/man3/*

%changelog
* Sat Sep 13 2014 Robin Lee <cheeselee@fedoraproject.org> 1.12-1
- Specfile autogenerated by cpanspec 1.78.

 

  • 运行 make,最终 RPMS 目录就是一个 yum 源

三、其它现成 planex 项目环境(都在 XenServer 项目下)
https://github.com/xenserver/xen-api-libs-specs
https://github.com/xenserver/xen-api-base-specs
https://github.com/xenserver/unified-specs
https://github.com/xenserver/buildroot

Category: Fedora | Tags:
4
18
2011

Perl 与 Python 3 线程机制实测比较

      计算机世界没有免费的午餐。特别地,CPU时间与内存消耗通常存在此消彼长的关系。实现某个功能,某算法可能使用更多CPU时间但占用更少内存,而另一算法可能使用更少CPU时间而占用更多内存。

      而另一种状况是,对于某种功能,某种实现占用更少内存但无法充分利用CPU时间,而另一种实现会消耗更多的内存但能更充分地利用CPU。在线程机制上,Python就属于前者,而Perl属于后者。下面通过几个简单的例子来体验一下这种差别。

      CPython 的线程机制使用了 Global Interpreter Lock 来实现,粗略的理解就是由一个解释器程序轮流来执行各个线程。

      Perl 的线程机制称为 ithread,粗略理解就是每个线程都有一个独立的解释器,也即是Perl进程的内存空间可能有多个解释器副本。

 

测试环境

CPU: AMD Phenom(tm) II X6 1055T Processor  (六核 2.8GHz)

         (也即是每个核心占总CPU时间约 17%)

RAM: 8G

OS: Fedora 15 beta (Linux 2.6.38.2-9.fc15.x86_64)

Python 3.2

Perl 5.12.3


Python 代码:

#! /usr/bin/env python3
import sys
import time
import threading

def main():
    if len(sys.argv) == 1:
        print("%s [-r] num"%sys.argv[0])
        exit(1);
    elif len(sys.argv) == 2:
        is_sleep = False
        thr_count = int(sys.argv[1])
    else:
        is_sleep = True
        thr_count = int(sys.argv[2])
    if thr_count < 1:
        thr_count = 1
    if is_sleep:
        func = dead_loop_with_sleep
    else:
        func = dead_loop
    if thr_count > 1:
        for i in range(thr_count-1):
            t = threading.Thread(target=func)
            t.start()
    func()

def dead_loop():
    while True:
        pass

def dead_loop_with_sleep():
    while True:
        time.sleep(1);

if __name__ == "__main__":
    main()

Perl 代码:

#!/usr/bin/env perl
use strict;
use warnings;
use threads;

my $is_sleep;
my $thr_count;

if (!@ARGV){
    print("$0 [-r] num\n");
    exit(1);
}
elsif (@ARGV == 1){
    $thr_count = int($ARGV[0]);
}
else {
    $is_sleep = 1;
    $thr_count = int($ARGV[1]);
}
$thr_count = 1 if $thr_count < 1;

my $func_ref = $is_sleep ? \&dead_loop_with_sleep : \&dead_loop;

if ($thr_count > 1){
    for (1..($thr_count - 1)){
        threads->create($func_ref);
    }
}

&$func_ref();

sub dead_loop{
    while(1){}
}

sub dead_loop_with_sleep{
    while(1){
        sleep(1);
    }
}

 

测试结果(内存按Pss计算):

测试形态 命令行 1 core (pl) 1 core (py) all (pl) all (py) Mem (pl) Mem (py)
单线程死循环 dead_loop 1 100% 100% 17% 17% 0.7M 8.0M
6线程死循环 dead_loop 6 近100% 不可测 近100% 17% 3.7M 10.2M
500线程带睡眠死循环 dead_loop -r 500 0% 0% 0% 0% 234.1M 29.8M

 

 

 

 

 


 

总结

      6线程死循环测试表明:Python在切换线程过程中有机会让操作系统将其安排到另一核心上运行,这样各核心的占用率大致平均。也即是,Python解释器在任何时候都只占用一个核心,因此Python占用的总CPU时间比总是 17%。Perl进程则占用了所有CPU核心的几乎所有时间,充分利用了CPU的多核心,但内存占用也几乎与线程数成正比。

 

      当500线程并行时,Python的内存占用增长率显然比线程数增加率要低得多,而Perl的内存占用依然几乎与线程数成正比。

Category: 未分类 | Tags:
2
24
2011

用 Shipwright 构建 Dancer 环境

Shipwright 为在虚拟主机上构建 Perl 应用带来了福音。

Shipwright 是一个软件构建和捆绑环境,用于创建自含的(self-contained)的软件环境。CPAN为我们带来了大量便利高效的模块,但也因此 CPAN 模块通常都有一些依赖关系,更不要说像 Catalyst 那样的庞然大物。Shipwright就是让我们将自己想要的模块以及它的所有依赖包捆绑到一个独立的环境,并且可以方便升级已有的环境或继续添加新包。当然,Shipwright 可以构建多样的软件环境,并不局限于Perl/CPAN。

下面以构建 Dancer 环境作为 Shipwright 的一个最简使用例子。我的系统环境是 Fedora 14。

cpan Shipwright
shipwright create -r fs:/tmp/daner-shipyard
shipwright import -r fs:/tmp/daner-shipyard/ cpan:Dancer
cd /tmp/daner-shipyard/
./bin/shipwright-builder --install-base /tmp/dancer-vessel --skip-test
cd /tmp/dancer-vessel

第1行:安装 Shipwright (希望近期能将 Shipwright 推到 Fedora 主库)

第2行:构建一个 shipyard (造船厂)目录,用于存在源码

第3行:载入 Dancer 源码,自动拉取完整依赖(不包含你正在使用的 Perl 的标准包)

第4行:进入 shipyard 目录

第5行:构建 Dancer 及其完整依赖,安装到 vessel (大船)目录

第6行:进入 vessel 目录,这个目录也就存放着完整的 Dancer 环境

下面来测试一下 Dancer。

如果是用 rpm/deb 的发行版,要先确定是否安装了 CGI 模块,在 Fedora 中可以这样安装:

su -c "yum install 'perl(CGI)'"

然后在当前目录 /tmp/dancer-vessel 创建一个测试小脚本 mydaner.pl:

#!/usr/bin/perl
use lib 'lib/perl5';
use Dancer;

get '/' => sub {
    return 'Hello World!';
};

start;

关键是第2行,将 vessel 的目录加入到 @INC 中。

运行脚本:

perl mydancer.pl

点击: http://0.0.0.0:3000/

Hello World!

 

Category: 未分类 | Tags:
4
9
2010

用C编写Python扩展的简单例子

此例子其实也就是官方的教程中的例子,详见 http://docs.python.org/extending/extending.html

但官方例子中把一段代码拆成若干个段落来解释,我自己看的时候都有点迷惑。在这里我把完整的代码贴出,并加上最简单的步骤。

 

第一步:新建一个文件夹,在里面建一个文件 spammodule.c :

 

#include <Python.h>

static PyObject *
spam_system(PyObject *self, PyObject *args)
{
    const char *command;
    int sts;

    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = system(command);
    return Py_BuildValue("i", sts);
}

static PyObject *SpamError;

static PyMethodDef SpamMethods[] = {
    {"system",  spam_system, METH_VARARGS,
     "Execute a shell command."},
    {NULL, NULL, 0, NULL}        /* Sentinel */
};

PyMODINIT_FUNC
initspam(void)
{
    PyObject *m;

    m = Py_InitModule("spam", SpamMethods);
    if (m == NULL)
        return;

    SpamError = PyErr_NewException("spam.error", NULL, NULL);
    Py_INCREF(SpamError);
    PyModule_AddObject(m, "error", SpamError);
}

第二步:建立 setup.py

 

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from distutils.core import setup, Extension

module1 = Extension('spam',
                    sources = ['spammodule.c'])

setup (name = 'spam',
       version = '1.0',
       description = 'This is a demo package',
       ext_modules = [module1])

第三步:运行命令

 

python setup.py build

运行后的文件夹结构如下:

.
├── build
│   ├── lib.linux-i686-2.6
│   │   └── spam.so
│   └── temp.linux-i686-2.6
│       └── spammodule.o
├── setup.py
└── spammodule.c

测试步:

 

cd build/lib.linux-i686-2.6/
python -c "import spam;spam.system('ls -l')"
ls -l

后面两行命令应该显示相同的结果。

 

 

 

 

 

 

 

 

Category: 未分类 | Tags: python c
3
28
2010

给Thunderbird添加托盘图标

有若干个扩展声称能实现这一功能,包括FireTray, MinimizeToTray Plus, xultray for gecko 1.9.x。

其中xultray for gecko 1.9.x实现的功能最符合习惯,在此推荐一下。

Category: 未分类 | Tags:
1
30
2010

Fedora下配置lighttpd+Django

这个blog的处女贴

1. 已有环境:

  • Fedora 12
  • Django project已配置好,位于 /var/www/django/mysite

2. 安装相关软件包:

sudo yum install python-flup lighttpd lighttpd-fastcgi 

3. 修改 /etc/lighttpd/lighttpd.conf 。中间省略了一大段,这只是最简单的配置

# lighttpd configuration file
#
# use it as a base for lighttpd 1.0.0 and above
#
# $Id: lighttpd.conf,v 1.7 2004/11/03 22:26:05 weigon Exp $

############ Options you really have to take care of ####################

## modules to load
# at least mod_access and mod_accesslog should be loaded
# all other module should only be loaded if really neccesary
# - saves some time
# - saves memory
## 去掉一些module的注释
server.modules              = (
                               "mod_rewrite",
                               "mod_redirect",
                               "mod_alias",
                                "mod_access",
#                               "mod_trigger_b4_dl",
#                               "mod_auth",
#                               "mod_status",
#                               "mod_setenv",
                               "mod_fastcgi",
#                               "mod_proxy",
#                               "mod_simple_vhost",
#                               "mod_evhost",
#                               "mod_userdir",
#                               "mod_cgi",
#                               "mod_compress",
#                               "mod_ssi",
#                               "mod_usertrack",
#                               "mod_expire",
#                               "mod_secdownload",
#                               "mod_rrdtool",
                                "mod_accesslog" )

## 省略了很多…………
## ………………………………

## include configuration snippets, usually provided by packages
include_shell "find /etc/lighttpd/conf.d -maxdepth 1 -name '*.conf' -exec cat {} \;"

## 加入以下内容
fastcgi.server = (
    "/mysite.fcgi" => (
        "main" => (
            # Use host / port instead of socket for TCP fastcgi
            #"host" => "127.0.0.1",
            #"port" => 8000,
            "socket" => "/tmp/mysite.sock",
            "check-local" => "disable",
        )
    ),
)

url.rewrite-once = (
    "^(/.*)$" => "/mysite.fcgi$1",
)

4. 创建快速运行脚本 /var/www/django/mysite/runfastcgi ,(其实放在哪里没所谓,)并添加执行权限

#!/bin/bash

# Replace these three settings.
PROJDIR="/var/www/django/mysite"
PIDFILE="$PROJDIR/django.pid"
SOCKET="/tmp/mysite.sock"

cd $PROJDIR
if [ -f $PIDFILE ]; then
kill `cat -- $PIDFILE`
rm -f -- $PIDFILE
fi

exec /usr/bin/env - \
PYTHONPATH="../python:.." \
./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE umask=000

5. 运行 lighttpd

sudo service lighttpd start

6. 访问 http://localhost/ ,大功告成

 

 

 参考: http://oteam.cn/2007/8/17/setting-lighttpd-django-on-ubuntu-server/

Category: Fedora | Tags: lighttpd fastcgi django

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com