Gentoo mwlib

Gentoo Korea Wiki
둘러보기로 가기 검색하러 가기
MediaWiki에서 사용할 수 있는 Collection Extension에 대한 렌더서버 구축하기

적용범위 및 목적

이 문서는 Mediawiki에서 사용할 수 있는 Collection Extension에 대한 렌더링 서버를 Gentoo Linux 에서 구축하는것을 그 목적으로 한다.


용어정의

기준내용

시스템을 구성하기 위한 준비

일단 mwlib을 사용하기에 앞서 어느경우에 렌더서버를 구축해야하는지 생각해보도록 하자

  1. pediapress서버와 통신이 느리거나 해서 제대로 파일을 생성할 수 없는경우
  2. 내부망에 mediawiki를 설치하는경우 외부의 pediapress 서버와 연결될 수 없는경우
  3. mediawiki를 비공개로 설정하여 pediapress 서버에서 대부분의 (또는 모든) 페이지에 대한 접근이 불가능할 경우


물론 위의 3가지 경우 모두 다 Collection Extension을 사용하는것을 전제로 한다.

Collection Extension을 Mediawiki에 설치하는 방법은 여기를 참고하도록 한다.


본 문서에서는 이미 서버에 Mediawiki정도는 어느 db가 되었든 세팅하고 문제없이 사용할 수 있는 사람들을 대상으로 설명을 진행하려 한다. 당연히 Collection 은 미리 설치되어있어야하며 사용법은 숙지하고 있어야 한다.

미리 읽어두면 좋을 내용들

pip 설치

pip는 이 글 중간부터 활용하는 파이선 패키지 설치 프로그램이다. 필요하니 반드시 설치해두도록 한다. emerge -s pip 로 검색하면 pip 패키지가 두개 나온다. 이름 충돌 문제가 있으므로

# emerge dev-python/pip

mwlib의 설치

mwlib은 현재 opensource로서 이 글을 작성하는현재 0.15.3 버전이 나와있다. 물론 이것을 사용할 예정이다.


중요: emerge -s mwlib 명령으로 버전을 반드시 확인하기 바란다.



참고: tilde(~) 키워드를 사용하는 시스템(예: ~x86, ~amd64 등)에서는 나름 최신 버전을 사용할 수 있다. 하지만 포티지 트리 커미터가 제때 버전 범프를 안할 수가 있으므로 계속 진행하는 다음 설명을 따르는 것이 좋겠다


다만 gentoo에서는 gentoo만의 방법이 있는법. emerge mwlib으로 설치하면 잘 될거같지만.............. 버전이 틀리므로 안된다.

그럼 최신버전을 구해야겠지... 인터넷을 뒤져서 다음의 URL을 찾는다

http://code.google.com/p/gentoo-progress/source/detail?r=3266


아 좋다. 역시 gentoo는 다르다. 삽질거리는 참 풍부하다.. 당연히 위의 파일을 받아서 사용하는 gentoo system의 overlay에 넣는다. 하지만.. manifest가 안된다. 안되는게 정상이다.. 수정할 부분이 있기 때문이다.

# Copyright owners: Gentoo Foundation
#                   Arfrever Frehtes Taifersar Arahesis
# Distributed under the terms of the GNU General Public License v2

EAPI="4"
PYTHON_MULTIPLE_ABIS="1"
PYTHON_RESTRICTED_ABIS="2.5 3.* *-jython *-pypy-*"
SUPPORT_PYTHON_ABIS="1"
RESTRICT_PYTHON_ABIS="3.* *-pypy-* *-jython"
DISTUTILS_SRC_TEST="py.test"
PYTHON_NAMESPACES="mwlib"

inherit distutils eutils

DESCRIPTION="mediawiki parser and utility library"
HOMEPAGE="http://pediapress.com/code/ https://github.com/pediapress/mwlib https://pypi.python.org/pypi/mwlib"
SRC_URI="mirror://pypi/${PN:0:1}/${PN}/${P}.zip"

LICENSE="BSD"
SLOT="0"
KEYWORDS="*"
IUSE="doc latex"

RDEPEND="dev-lang/perl
     >=dev-python/apipkg-1.2
     dev-python/bottle
     dev-python/gevent
     dev-python/imaging
     dev-python/lxml
     =dev-python/odfpy-0.9*
     >=dev-python/py-1.4
     >=dev-python/pyPdf-1.12
     >=dev-python/pyparsing-1.4.11
     dev-python/roman
     >=dev-python/qserve-0.2.7
     dev-python/setuptools
     >=dev-python/simplejson-2.3
     dev-python/sqlite3dbm
     >=dev-python/timelib-0.2
     latex? ( virtual/latex-base )"
DEPEND="${RDEPEND}
    doc? ( dev-python/sphinx )"

S="${WORKDIR}/${P}"


다운받은 ebuild파일의 상단부를 위와같이 싹 바꿔준다. 실제로 바꿀내용이 많은것은 아니니 뭐뭐를 바꿔야 하는지 궁굼한 사람들은 본인이 직접 비교해가면서 바꿔보도록 한다.


이후 해당되는 ebuild의 emerge를 진행하도록 한다. 본인이 이때 사용한 USE flag는 대략 다음과 같다.

USE="-X -ipv6 -gtk -alsa -esd -svg raw openexr lcms fftw fpx hdri jbig lqr q8 i18n dbus udev hal unicode cjk bash-completion cscope ruby vim-pager vim-syntax mmx sse sse2 nptl nptlonly ctype ftp fastcgi spl xml soap cli jpeg jpeg2k python tiff gif png truetype corefonts xetex"


물론 본인의 경우니 적절히 가려가며 쓰도록 한다. 다만.... 그림파일 관련된 부분은 모조리 들어가주는것이 좋다.

또한! python의 버전은 eselect python set 을 통해서 미리 맞춰놓도록 한다.

주의사항::가능하면 dev-python/imagingdev-python/pygments 정도를 미리 설치하는것이 좋다. 이후 좀 덜 귀찮아진다.
주의사항::귀찮다고 ACCEPT_KEYWORDS 따위를 쓸생각은 하지말자. 사용하는 패키지중에 perl이 걸리면서 perl이 불안정버전으로 올라가는 경우가 생긴다. 이렇게되면 vi도 안뜨는 경우가 발생할 수 있기때문에 심히 곤란한 상황이 벌어진다. accept keyword가 필요한 패키지의 경우 gentoo만의 방법으로 하나하나 따로 설치해주길 바란다.
참고사항::왜인지 이유는 모르겠으나 texlive 2011버전이 r6는 gcc 4.5.3에서 설치가 잘 되지 않는다. texlive-core 2011 r6 이 잘 설치되지 않는 경우에는 r7을 설치하도록 한다.


이렇게 설치가 완료되면 이제 재대로 동작하는지 확인을 해봐야 한다.


mwlib의 동작확인

간단하다. 별 이상 없으면 다음과같은 명령어를 진행해보자.

# mw-render --list-write
odf	OpenDocument Text


윗줄은 명령어와 옵션이고 아랫줄은 출력결과물이다. 이야.. 일단 동작은 하게된거같다.

위에서 odf가 나왔다는건 Mediawiki의 Collection extension을 이용해 pdf포맷으로 내용을 내보내기 할 수 있다는 의미가 된다.

mwlib.rl의 설치

mwlib.rl은 mwlib에서 pdf로 내보내기를 가능하게 해주는 모듈이다.

이 페이지 를 참고해서 mwlib.rl 을 설치하도록 한다.

물론 pip를 사용해서 설치해줘야하며.. 이 문서를 제대로 읽고 왔다면 다른 추가패키지 설치없이 mwlib.rl 까지 설치가 진행된다.


참고: pyfribidi 패키지는 옵션으로 설치해도 되는 것처럼 설명하지만, 반드시 설치해야 한다



mwlib.rl의 설치확인

다음과같은 명령어와 결과를 확인할 수 있으면 된다.

$ mw-render --list-write
odf	OpenDocument Text
rl	PDF documents (using ReportLab)


어.. 뭔가 늘었다. 맨 아랫줄을 확인하면 rl PDF documents (using ReportLab) 이라는 부분이 있다. mwlib.rl 이 제대로 설치되었다. 그부분만 정상적으로 떠있으면 일단 제대로 작동된다고 생각하면 된다.

mwlib.epub의 설치

mwlib.epub은 mwlib에서 epub으로 내보내기를 가능하게 해주는 모듈이다. 렌더서버가 동작중이라면 렌더서버를 완전히 내리고 (/etc/init.d/blabla stop) 설정하는 것을 추천한다.

다음 명령으로 mwlib.epub를 설치한다. (다행스럽게도 해당 서버에 mwlib.epub 모듈이 있다.)

# pip install -i http://pypi.pediapress.com/simple/ mwlib.epub

설치 과정중에 오류 메시지 같은 내용이 뜨는데, 이미 의존성을 만족한다는 이야기니 안심해도 좋다. 설치가 끝났다면 다음과 같은 결과가 나오는지 확인해본다.

$ mw-render --list-write
odf	OpenDocument Text
rl	PDF documents (using ReportLab)
epub	epub Files

마지막 줄의 epub가 나와야 한다. 안나오면 도루묵이다.

{mediawiki-root}/extensions/Collection/Collection.php 를 열어 다음과 같이 epub 관련 줄을 추가한다.

/** List of available download formats,
        as mapping of mwlib writer to format name */
$wgCollectionFormats = array(
    'rl' => 'PDF',
    'odf' => 'ODT',
    'epub' => 'EPUB'
);

이제 렌더 서버를 재시작해보자. 그래도 안되면 위키 하단의 문제 해결에 클레임을 넣어주기 바란다.

mwlib을 서버로 띄우기

mwlib에서 핵심적인 4개 파일은 다음과같다.

nserve.py
mw-qserve
nslave.py
postman


참고: 설치 방법에 따라서 ,py 확장자가 안 붙어 있을 수도 있다.


위의 4개파일이 순서대로 뜨면 일단 daemon은 제대로 구동이 되는거라고 보면 된다. 문제는.....


gentoo에서 emerge로 설치했을때 문제가되는 2개의 파일

gentoo에서 mwlib을 서버로 띄우는데 2개정도의 문제가 되는 파일이 있다.

nserve.py, nslave.py 이 두개 파일이 그것이다. 이 파일들은 대단히 엽기적인 동작을 보여주는데..

(물론 nserve.py는 nserve-2.7 파일의 wrapper, nslave.py는 nslave-2.7의 wrapper되시겠다)


아래와 같이 실행하면 미묘한 결과가 나오면서 실행이 되지 않는다...

# /usr/bin/nserve-2.7 
This Python implementation (python2.7) is not supported by the script.


...................응? 이게 뭔소리지?

이유는 잘 모르겠지만 /usr/bin 디렉토리에 있으면 실행이 안된다.

그래서 본인은 따로 디렉토리를 만든후 그 안에 파일을 복사하고 실행한다.. 잘된다...-.-;

대략 다음의 파일들을 복사하면 된다.

/usr/bin/nslave.py
/usr/bin/nslave-2.7
/usr/bin/nserve.py
/usr/bin/nserve.2.7

이렇게 파일을 복사햐면 서버를 띄울 최소한의 준비가 된다.


mwlib 서버를 띄우는 방법

  1. 먼저 위의 파일이 복사된 디렉토리로 이동한다. 그리고 다음과 같은 내용으로 shell script를 하나 만든다.
#!/bin/bash
./nserve.py &
mw-qserve &
./nslave.py --cachedir /var/log/cache/mediawiki/ &
postman
  1. 이후 screen 을 이용해서 별도의 session을 연다.
  2. 해당되는 shell script를 실행한다.
  3. 에러같지 않으며 idle 어쩌고..하는 메세지가 뜨면 daemon 기동 성공

물론 screen 의 사용법은 이 문서에서 다루지 않겠다.

mwlib서버를 죽이는 방법

  1. 이전의 구동용 shell script를 만들 디렉토리로 이동해서 다음과같은 내용으로 shell script를 하나 더 만든다.
    #!/bin/bash
    killall nserve.py
    killall mw-qserve
    killall nslave.py
    
  1. 서버 daemon을 종료하려는경우 사용하면 된다.

mwlib 서버 daemon의 테스트

telnet을 이용해서 아래와같은 방법으로 테스트를 진행하면 된다.

# telnet localhost 8899
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

물론 telnet이 깔려있어야 테스트가 가능하다. telnet이 깔려있는 다른 windows머신에서 테스트를 해보는 방법도 있겠다.

Mediawiki의 설정변경

Mediawiki의 Collection Extension 은 기본적으로 아무것도 설정하지 않은경우 pediabook 의 서버로 연결되게 된다. 이걸 바꿔야 직접 띄운 render서버로 연결이 되어 사용할 수 있게된다.


Mediawiki의 LocalSettings.php 파일에 다음 부분을 추가한다.

$wgCollectionMWServeURL="http://렌더링서버IP:8899";


이후 Collection Extension 기능을 사용해서 pdf 또는 odf 파일을 생성해보면 된다.

파일이 제대로 생성되면 성공!

rc-script 만들기

머신을 시작하면서 렌더링 서버를 자동으로 돌아가게 하려면 다음 스크립트를 /etc/init.d/ 에 알아서 추가하도록 한다. 예를 들어 설명해보도록 하겠다

만약 다음 명령을 실행하면

root ~ # cd /etc/init.d
root init.d # vi mwlib

대강 다음과 비슷한 템플릿이 뜬다.

#!/sbin/runscript
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $

depend() {

}

start() {

}

stop() {

}

이 템플릿을 다음과 비슷하게 채워준다. 처음 네 줄을 제외한 나머지 주석은 넣지 않아도 된다. 내용 참고는 상단에서 했다.

#!/sbin/runscript
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $

USERID="user" # 스크립트를 실행할 UserID. 본인의 경우에는 root로 했다.
HOMEDIR="/home/user/mwlib-script" # 스크립트가 들어있는 폴더(or 디렉터리)

depend() {
    need net # 네트워크를 시작하지 않으면 무용지물.
}

start() {
    ebegin "Starting mwlib document rendering server"
    /usr/bin/screen -dmS mwlib-screen su ${USERID} -c "${HOMEDIR}/mwlib-server.sh" 
    eend $? 
}

stop() {
    ebegin "Stopping mwlib document rendering server"
    local pid=`ps aux | grep mwlib-screen | grep SCREEN | awk -F ' ' '{print $2}'`
    killall postman
    killall nslave
    killall mw-qserve
    killall nserve
   
    /bin/kill -9 $pid
    sleep 1 # 이 줄을 안 넣으면 fail이 난다. 원인은 모름 -_-

    eend $? 
}

일단 저장하고 나와서 이번에는 rc-script로 돌릴 스크립트를 만들어보자. 위에 적어두었던 스크립트에서 실행 권한 부여 부분이 바뀐다.

#!/bin/bash
su - root -c '/usr/local/bin/nserve'&
su - root -c '/usr/bin/mw-qserve'&
su - root -c '/usr/local/bin/nslave --cachedir /var/log/cache/mediawiki/'&
su - root -c 'postman'

루트 권한으로 실행하도록 명령하는 것은 사실 아주 위험한 명령이긴 하지만 이렇게 하지 않으면 퍼미션 문제가 발생한다. root대신 apache를 넣으면 (apache를 넣어야 하는게 정상이지만) 가끔 not available 오류가 뜬다. 이 스크립트를 어딘가 잘 만들어서 rc-script에 지정한 디렉터리로 잘 복사해둔다. 물론 실행 퍼미션도 잊지 말고 부여하도록.

그리고 마지막으로 넣으면 좋은 명령 한 줄.

root init.d # rc-update add mwlib default

스크립트 이름을 rend-server 이런식으로 했다면 mwlib가 아니라 rend-server로 적어줘야 한다.

일단 시작해보고

root init.d # ./mwlib start

동작중인지 확인해본다

root init.d # screen -ls

제대로 나온다면 아마 다음 처럼 나올 것이다.

There are screens on:
	30672.mwlib-screen	(Detached)
 1 Sockets in /root/.screen.

그리고 실제로 스크립트로 실행한 네가지 명령이 동작중인지 확인해봐야 한다

root init.d # ps aux | grep nserve;ps aux | grep nslave;ps aux | grep mw-qserve;ps aux | grep postman

참고사항

  1. 페이지수가 너무 많으면 pdf 파일의 경우생성을 제대로 못한다. 아마도 페이지에 들어있는 이미지의 개수와 상관이 있는듯. 이런경우에는 페이지수를 적게해서 pdf를 여러개 생성해야 한다
    # 아마도 epub을 쓰려면...... python관련 library도 좀 올려야하는데.. ebuild가 없어서 근성부족으로 포기 (내용 추가로 삭제)
    # pyfribidi는.. 설치하다가 ctrl+c를 눌러서 중지했더니... 설치가 똑바로 안되고있다... 역시 근성부족으로 포기 아마도 망 문제인듯 하다
  2. iptables를 설치했을 경우 포트가 막혀있을 경우가 있다. 그럴 경우 다음과 같이 명령을 실행한다
# iptables -A INPUT --protocol tcp --dport 8899 -j ACCEPT
# iptables -A INPUT --protocol tcp --dport 14311 -j ACCEPT
# iptables -L // tcp/8899 포트와 tcp/14311 포트가 제대로 추가 되었는지 확인
# /etc/init.d/iptables restart

문제 해결

  • 아래같은 이상한 오류 메시지가 뜨면서 1.00%에서 그냥 멈춰요 ㅠㅠ
RuntimeError: RuntimeError: command failed with returncode 256: ['mw-zip', '-o', '/var/log/cache/mediawiki/0a/0ad39576d7b62f5e/collection.zip', '-m', '/var/log/cache/mediawiki/0a/0ad39576d7b62f5e/metabook.json', '--status', 'qserve://localhost:14311/0ad39576d7b62f5e:makezip', '--template-blacklist', 'MediaWiki:PDF Template Blacklist', '--template-exclusion-category', u'\uc778\uc1c4\uc2dc \uc81c\uc678\ud560 \ubb38\uc11c', '--print-template-prefix', u'\uc778\uc1c4', '--print-template-pattern', u'$1/\uc778\uc1c4'] Last Output: 2013-03-23T22:53:08 mwlib.options.warn >> Both --print-template-pattern and --print-template-prefix (deprecated) specified. Using --print-template-pattern only. 1% creating nuwiki in u'/var/log/cache/mediawiki/0a/0ad39576d7b62f5e/tmp3RkWo0/nuwiki' removing tmpdir u'/var/log/cache/mediawiki/0a/0ad39576d7b62f5e/tmp3RkWo0' memory used: res=18.7 virt=249.1 1% error Traceback (most recent call last): File "/usr/bin/mw-zip-2.7", line 9, in <module> load_entry_point('mwlib==0.15.3', 'console_scripts', 'mw-zip')() File "/usr/lib64/python2.7/site-packages/mwlib/apps/buildzip.py", line 155, in main make_zip(output, options, env.metabook, podclient=podclient, status=status) File "/usr/lib64/python2.7/site-packages/mwlib/apps/buildzip.py", line 50, in make_zip make_nuwiki(fsdir, metabook=metabook, options=options, podclient=podclient, status=status) File "/usr/lib64/python2.7/site-packages/mwlib/apps/make_nuwiki.py", line 152, in make_nuwiki assert x.wikiident in id2wiki, "no wikiconf for %r (%s)" % (x.wikiident, x) AssertionError: no wikiconf for None (<article {'_env': <mwlib.wiki.Environment object at 0xaf1690>, 'title': u'Idea:myIdea', 'url': u'http://hostname/index.php/Idea:myIdea', 'timestamp': u'1363919027', 'currentVersion': 1, 'content_type': u'text/x-wiki', 'revision': u'43', 'type': 'article', 'latest': u'43'}>) in function system, file /usr/lib64/python2.7/site-packages/mwlib/nslave.py, line 64 in function qaddw, file /usr/lib64/python2.7/site-packages/qs/slave.py, line 66

먼저 LocalSettings.php를 열어 다음을 확인해본다

$wgScriptPath = ""

여기서 $wgScriptPath = ""가 아니라 마지막에 슬래시(/)가 빠진 자신의 위키 서버 주소가 들어가야 한다. 가령 예를 들면 다음과 같다.

$wgScriptPath = "http://webhost/wiki"

그 다음 다음 변수 존재 유무를 확인하고 없으면 추가한다.

$wgEnableAPI = "true"

다음 두 줄의 존재 유무를 다시 한번 확인한다.

$wgGroupPermissions['user']['collectionsaveascommunitypage'] = true;
$wgGroupPermissions['user']['collectionsaveasuserpage'] = true;

비공개 위키를 사용하는 경우, 자신의 계정으로 접속하게 하도록 한다. extensions/Collection/Collection.php를 열어 다음 변수의 내용을 null에서 다른 문자열 값으로 바꿔준다.

$wgCollectionMWServeCredentials = "user:passwd";


  • Permission denied가 뜨네요. 왜죠?
error finish: 801a5c314495021a:makezip: "OSError: [Errno 13] Permission denied: '/var/log/cache/mediawiki/80/801a5c314495021a' in function doit, file /usr/lib64/python2.7/site-packages/mwlib/nslave.py, line 144" Traceback (most recent call last): File "/usr/lib64/python2.7/site-packages/qs/slave.py", line 150, in handle_one_job result = workhandler(qs).dispatch(job) File "/usr/lib64/python2.7/site-packages/qs/slave.py", line 50, in dispatch return m(**tmp) File "/usr/lib64/python2.7/site-packages/mwlib/nslave.py", line 161, in rpc_makezip return doit(**params) File "/usr/lib64/python2.7/site-packages/mwlib/nslave.py", line 144, in doit os.mkdir(dir) OSError: [Errno 13] Permission denied: '/var/log/cache/mediawiki/80/801a5c314495021a' error: OSError: [Errno 13] Permission denied: '/var/log/cache/mediawiki/80/801a5c314495021a' in function doit, file /usr/lib64/python2.7/site-packages/mwlib/nslave.py, line 144

실행 권한을 apache 또는 root로 주고 스크립트를 실행하면 문제가 해결된다.

참고문서