Fedora 혹은 Redhat Linux 상에서 CVS 를 pserver 방식으로 구축하기를 정리한다.
참조 :
-
OpenSeed Wiki CVSWithLinux -
java.net과 이클립스를 이용한 오픈 소스 자바 어플리케이션 개발CVS가 뭐지 :
KLDP의 CVS 문서들 이 중에서도 먼저
CVS 를 읽어본다.
* ChangeLog
- 2006/07/14 Solaris에서 inetd를 이용할 경우 상황 추가
1. 패키지 설치
$ yum install cvs
2. 기타
xinetd 와 Perl도 설치되어 있어야 한다.
3. CVS 사용자의 생성
# useradd cvs
# su - cvs
$ mkdir CVS저장소이름
"CVS
저장소이름"에 새로운 디렉토리를 생성하고 앞으로 프로젝트의 저장소로 사용할 디렉토리 이름을 지정한다. 사실 그냥
/home/cvs 를 사용해도 상관없지만, 여러가지 프로젝트를 할 경우에 서로 다른 저장소를 사용하고 싶다면 디렉토리를 구분하는
것이 좋다.
4. /etc/services 설정
cvspserver 2401/tcp # CVS client/server operations
cvspserver 2401/udp # CVS client/server operations
/etc/services 파일에 위 내용을 추가한다.
5. /etc/xinetd.d/cvspserver 파일 생성
# default : on
# description : The cvsserver serves CVS Password Server sessions; it uses
# unencrypted username/password pairs for authentication.
service cvspserver
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = cvs
server = /usr/bin/cvs
server_args = -f --allow-root=/home/cvs/newproject pserver
log_on_failure += USERID
}
CVS를 xinetd 의 서비스로 등록한다. "server_args" 부분에서 "-f"와 "pserver" 사이에
--allow-root=저장소경로를 추가함으로써 여러개의 CVS 저장소를 지정할 수 있게 된다. user = cvs 는 cvs 계정을 이용해서 cvs 서버를 사용하겠다는 의미일꺼다... 아마도..
# service xinetd restart
xinetd 를 재시작한다.
5-1. inetd 이용하기
Solaris의 inetd를 이용해서 CVS서버를 운영할 필요가 있을 경우에, 다른 사항은 모두 같고, xinetd 대신 inetd를 사용하며, /etc/inetd.conf 파일에 다음을 추가한다.
cvspserver stream tcp nowait cvs /usr/local/bin/cvs -f --allow-root=/home/cvs/newproject pserver
그리고 inetd 재시작한다.
# ps -ef | grep inetd
# kill -HUP inetd의PID
6. 저장소 공간 생성
# su - cvs
$ cvs -d /home/cvs/newproject init
프로젝트 저장소 공간을 초기화 한다. 이제부터 여기다가 소스 파일을 올려놓겠소! 하는 것이다.
7. 계정 발급하기
CVS 사용자를 등록해줘야 한다. CVS사용자와 실제 리눅스 운영 시스템 사용자는 분리되어 관리되는데, 그럼에도,
CVS 사용자의 사용자명이 리눅스 시스템의 사용자로 존재해야만 한다. 그러니 먼저 사용자 계정을 만들때 useradd 사용자명 명령으로 리눅스 사용자를 추가한 뒤에 아래 작업을 한다.pserver 방식에서 사용하는 CVS 사용자와 실제 Linux상의 사용자는 아무 관련이 없다.
- /usr/local/bin/cryptpasswd 파일
#!/usr/bin/env perl
srand(time());
$randletter = "(int (rand (26)) + (int(rand(1) + .5)% 2?65:97))";
$salt = sprintf("%c%c",eval$randletter,eval$randletter);
$plaintext =shift;
$crypttext = crypt ($plaintext,$salt);
print "${crypttext}
";
CVS에 사용자를 등록하고 그 사용자의 CVS접속 비밀번호를 설정할 때 사용하는 펄 스크립트이다. 만들어서 /usr/local/bin/cryptpasswd 로 저장하고
chmod a+x /usr/local/bin/cryptpasswd로 실행할 수 있게 한다.
이제 리눅스의 사용자 계정과 별도로 CVS 사용자를 각 저장소 별로 등록할 필요가 있다.
저장소경로/CVSROOT/passwd파일에 등록한다. 처음 프로젝트를 생성하면 존재하지 않기 때문에 생성해야 한다.
"kwon37xi"라는 사용자를 추가해보자.
# useradd kwon37xi
# su - cvs
$ cryptpasswd 1111
HJ8V/1Wrr5HpQ
-- 위 결과는 CVS 저장소 접근용 비밀번호를 생성한 것이다. 비밀번호가 1111일 때에 대한 예이다.
$ vi /home/cvs/newproject/CVSROOT/passwd
kwon37xi:HJ8V/1Wrr5HpQ:cvs
위와 같이 passwd 파일을 만들어주면 사용자가 등록된 것이다. 마지막에 :cvs 는 항상 이렇게 쓴다. cvs 계정을 이용해서 저장소에 접근하라는 의미로 알고 있다.
이제는
Eclipse나
Tortoise CVS등을 이용해서 kwon37xi 사용자가 비밀번호 1111로 /home/cvs/newproject CVS 저장소를 사용할 수 있게 되었다.
8. 방화벽 설정하기
사실 pserver 방식은 보안에 취약한 것으로 알려져있다. 데이터 송수신시에 전혀 암호화를 안한다.
아무튼 그래도 보호를 해줘야 하니까 회사 내의 특정 아이피들만 접속할 수 있게 설정한다.
/etc/hosts.allow파일을 없으면 만들어서 다음을 추가한다.
cvs: 접속허용IP 192.168.1.* LOCAL
cvs: 뒤에 접속을 허용할 IP 목록을 공백으로 구분하여 적는다. LOCAL은 리눅스 서버 자체를 의미하고 ALL의 경우에는 아무나 허용한다. 그런뒤에 다시
service xinetd restart를 실행하여 xinetd에 방화벽(?)을 적용한다.
//
//
// 저장소 및 디렉토리 생성 및 초기화
// 다운로드 : http://www.cvshome.org/
//
//
///////////////////////////////////////////////////////////////////////////
mkdir /home/cvs
cvs =d /home/cvs init
adduser cvs
chown root.cvs /home/cvs -R
chmod 770 /home/cvs -R
// 유저 패스워드 설정
htpasswd -nb [ID] [PASS]
// cvs server start
/etc/xinetd.d/cvspserver
/////////////////////////////////////////////////////////////////////////////
//
//
// cvs서버를 실행 시키기 위해서 아래 파일을 생성
//
//
/////////////////////////////////////////////////////////////////////////////
// 파일명
/etc/xinetd.d/cvspserver
// 내용
service cvspserver
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = cvs
server = /usr/bin/cvs
server_args = --allow-root=/home/cvs pserver
}
// 파일 생성후 진행 작업
service xinetd restart
netstat -an grep 2401
////////////////////////////////////////////////////////////////////////
//
//
// cvs 로그인 하기
//
//
////////////////////////////////////////////////////////////////////////
cvs -d:pserver:kurome@localhost:2401/home/cvs login
:[접속방법]:[cvs사용자ID]@[주소:포트/경로]
맨날 하기 귀찮아서리 다른 방법이 존재하는데
~/.bash_profile
에다가 아래 내용을 추가한다.
export CVSROOT=:pserver:kurome@localhost:/home/cvs
추가한뒤
source ~/.bash_profile
을 명령한다.
여기서 pserver 대신 ext를 사용하게 되면 시스템 계정을 이용한 rsh 나 ssh로 접속 하는 것을 의미한다.
////////////////////////////////////////////////////////////////////////
//
//
// cvs 파일 등록하기
//
//
////////////////////////////////////////////////////////////////////////
cvs import -m "diary project start " diary project start
////////////////////////////////////////////////////////////////////////
//
//
// cvs 프로젝트 파일 받아 오기
//
//
////////////////////////////////////////////////////////////////////////
cvs checkout diary
나
cvs co diary
////////////////////////////////////////////////////////////////////////
//
//
// cvs 수정한 내용을 저장소 디렉토리에 반영
//
//
////////////////////////////////////////////////////////////////////////
cvs commit -m "main.c file comment append" main.c
////////////////////////////////////////////////////////////////////////
//
//
// cvs 수정한 파일이 많은데 일일히 수정하기 곤란할 때 이용
//
//
////////////////////////////////////////////////////////////////////////
cvs ci
////////////////////////////////////////////////////////////////////////
//
//
// cvs 현재 작업 디렉토리에 최신 소스 반영하기
//
//
////////////////////////////////////////////////////////////////////////
cvs update
나
cvs up
////////////////////////////////////////////////////////////////////////
//
//
// cvs 파일과 디렉토리 추가 및 삭제
//
//
////////////////////////////////////////////////////////////////////////
cvs add newfile.c // 파일 추가
////////////////////////////////////////////////////////////////////////
//
//
// cvs 디렉토리 트리를 추가하는 스크립트 파일
//
//
////////////////////////////////////////////////////////////////////////
#!/usr/bin/python
# vi: set ts=4 sts=4 sts=4 sw=4 : #
import os
import sys
import getopt
import glob
def read_dir(args, dirname, filenames) :
if not dirname.endswith("CVS") :
if dirname.endswith("/") :
dirname = dirname[ 0:dirname.rindex("/")]
os.system("cvs add " + dirname)
for f in filenames :
if os.path.isfile(dirname + "/" + f) :
os.system("cvs add " + dirname + "/" + f)
################ main start ###############
if len(sys.argv) > 1:
options, args = getopt.getopt(sys.argv[1:], "t:")
for op, var in options:
if op == "-t" :
os.path.walk(var, read_dir, [] )
os.system("cvs ci -m \"append directories\"")
위 스크립트를 cvsadd.py 로 작성하고 chmod 755 /usr/local/cvsadd.py 명령으로 실행 권한
을 준다. 그리고 newdir 디렉토리의 상위 디렉토리에서 아래와 같이 명령을 내리면 newdir 디렉
토리 이하 모든 파일과 디렉토리가 CVS 서버에 추가된다.
cvsadd.py -t newdir
////////////////////////////////////////////////////////////////////////
//
//
// cvs 디렉토리의 삭제
//
//
////////////////////////////////////////////////////////////////////////
rm -rf newfile.c
cvs remove newfile.c
cvs ci -m "newfile.c 파일 제거"
////////////////////////////////////////////////////////////////////////
//
//
// cvs 현재 버전 확인
//
//
////////////////////////////////////////////////////////////////////////
cvs status newfile.c
////////////////////////////////////////////////////////////////////////
//
//
// cvs 이전 버전으로 복귀
//
//
////////////////////////////////////////////////////////////////////////
cvs up -r 1.5 -p newfile.c > newfile.c
이건 일시적은 복귀이고 완전히 복귀 하기 위해서는
cvs add newfile.c 명령을 사용하여 파일을 추가 해야 한다.
cvs up -j 1.6 -j 1.5 newfile.c
기타 > 이미지와 같은 바이너리 파일의 경우는 -kb 옵션을 주어 바이너리
파일 이라는 것을 알려야 한다.
cvs add -kb image.jpg
기타 > 간혹 롤백(Rollback)을 하고 롤백한 파일을 수정한 후 commit을 할때
sticky tag `1.2`와 같은 메시지가 출력 되면서 commit 이 되지 않는 경우가 발
생할 경우가 있는데 이는 파일에 sticky tag가 있어서 그렇다. sticky tag는 이
전 버전으로 되돌린다거나 할 때 자동으로 들어가게 되는데 sticky tag가 들어
가는 이유는 main.c파일을 1.2로 바꾸고 commit이 가능하다면 현재 저장소
디렉토리에 있는 main.c 파일은 훨씬 이전 버전인 1.2 버전으로 바뀌기 때문
이다.
이런 일을 미연에 방지하고자 CVS는 cvs up -r 1.2 main.c 명령으로 main.c
파일을 1.2 버전으로 되돌릴 때 항상 스티키 태그를 집어 넣는다. 스티키 존재
유무는 cvs status [파일명]으로 확인 가능하다.
cvs up -A main.c
////////////////////////////////////////////////////////////////////////
//
//
// cvs 파일 로그 및 특정 부분을 수정한 사람 확인
//
//
////////////////////////////////////////////////////////////////////////
cvs log [파일명]
을 이용하면 버전별로 수정한 사람이 나타나게 되고
cvs annotate [filename] or cvs ann [filename]
을 이용 소스 라인 별로 수정한 사람이 나타나게 된다.
////////////////////////////////////////////////////////////////////////
//
//
// cvs 파일 버전대별 차이점 확인
//
//
////////////////////////////////////////////////////////////////////////
cvs diff -r 1.5 -r 1.6 main.c
1.5버전에서 main.c 파일과 1.6 버전의 main.c 파일에서 달라진 부분이 있
는지 출력한다.
////////////////////////////////////////////////////////////////////////
//
//
// cvs 현재 작업 디렉토리에 있는 main.c 와 저장소 디렉토리 내용 비교
//
//
////////////////////////////////////////////////////////////////////////
cvs diff -r HEAD main.c
////////////////////////////////////////////////////////////////////////
//
//
// cvs 소스에 TAG걸기
//
//
////////////////////////////////////////////////////////////////////////
소스 편집 상태를 저장 하기 위해서 특정 시점에 TAG을 걸 수 가 있다.
cvs tag TAG_1
이런식으로 현재 상태를 태깅 해놓으면 추후 TAG_1 의 상태로 돌아
갈수 가 있다.
cvs up -r TAG_!
이렇게 태그를 거는건 버그 수정 하거나 소스를 많이 수정해야 할 경우 유용
하다.
///////////////////////////////////////////////////////////////////////
cvs command
///////////////////////////////////////////////////////////////////////
login : cvs server login
logout : cvspass file에서 저장소 제거
import : 프로젝트 파일 등록
checkout(co, get) : 프로젝트 파일 가져오기
commit(ci) : project file 수정후 cvs 서버에 반영
update(up) : cvs server의 최신 버전을 작업 디렉토리에 반영
add(new) : 파일 또는 디렉토리 추가
remove(rm, delete) : 파일 삭제
diff : 파일 버전에 따른 차이점 비교
log : 파일 로그 보기
annotate(ann) : 행별 정보 출력(날짜 작성자 등)
status : 파일 상태 보기
history : 각종 히스토리 보기
tag : 프로젝트 파일들 태깅
rtag : 저장소 디렉토리에 태깅
release : 모듈 release
/////////////////////////////////////////////////////////////////////////
참조 사이트
http://wiki.kldp.org/wiki.php/DocbookSgml/CVS_Tutorial-KLDP
http://jakarta-k.sourceforge.net/guide/HOWTO_Sourceforge_CVS.html#%C1%D8%BA%F1%B9%B0
다운로드 사이트
http://www.cvshome.org/