2017년 6월 23일 금요일

이미 설치된 Miniconda의 설치 directory 바꾸기

System admin이 Miniconda를 설치했는데, 별 생각없이 설치하여 root user의 home directory에 설치하는 바람에 /root/miniconda3에 설치된 경우 어떻게 해야 할까요 ?

결론부터 말씀드리면, 원하는 directory로 copy한 뒤 ownership을 바꿔주고, 그리고나서 약 100여개의 file들 속의 기존 directory 이름을 바꿔주면 됩니다.

원래의 정답은 아래의 Continuum 홈페이지에 나왔습니다.

https://docs.continuum.io/anaconda/user-guide/tasks/move-directory

클릭하기 귀찮으신 분을 위해 아래에 copy & paste 해드리면 다음과 같습니다.

To move Anaconda from one directory to another:

1. Delete it from the old directory.
2. Go to the new directory and install it there following the Anaconda installation instructions.

즉, 지우고 새로 설치하라는 것입니다.   Anaconda 또는 Miniconda를 한번 설치하고 나면, 그 directory만 새로 옮기는 것은 허용되지 않는다고 합니다.

그러나 Continuum의 그런 정책에 대해서는 많은 불만들이 있을 수 있습니다.  많은 기업들이 보안 등의 문제로 서버를 internet access를 허용하지 않습니다.  따라서 서버를 도입할 때, 먼저 회사 외부의 internet이 자유롭게 access되는 곳에서 OS와 Miniconda를 설치한 뒤,  mecab-python3처럼 Miniconda에는 포함되어 있지 않아 internet에서 download 받아야 하는 python package 등을 다 설치한 뒤 회사에 반입하는 경우가 꽤 많습니다.   그런데 그 설치 directory를 /root/miniconda3에 해버리면 다른 일반 유저들이 conda 명령들을 수행할 때 아래와 같은 error가 나버립니다.

u0017496@sys-87926:~$ /root/miniconda3/bin/conda list
-bash: /root/miniconda3/bin/conda: Permission denied

그래서 /root와 같은 민감한 directory를 피해서, /opt 혹은 /usr/local과 같은 곳으로 이 directory를 copy한 뒤 ownership만 변경해주면 좋겠습니다만, 아래와 같이 그것도 안 됩니다.

먼저 /root/miniconda3를 /usr/local/miniconda3로 copy 하고...

root@sys-87926:~# pwd
/root

root@sys-87926:~# cp -r miniconda3 /usr/local/

ownership을 변경해준 뒤

root@sys-87926:~# chown -R u0017496:u0017496 /usr/local/miniconda3

이제 u0017496 사용자로 login해서 환경 변수를 맞춰주고

u0017496@sys-87926:~$ vi ./.bashrc
...
export PATH=/usr/local/miniconda3/bin:$PATH
export PYTHONPATH=/usr/local/miniconda3/lib/python3.6/site-packages
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-ppc64el

u0017496@sys-87926:~$ . ./.bashrc

u0017496@sys-87926:~$ which conda
/usr/local/miniconda3/bin/conda

간단한 conda 명령을 날려보면 다음과 같이 error가 납니다.

u0017496@sys-87926:~$ conda list
-bash: /usr/local/miniconda3/bin/conda: /root/miniconda3/bin/python: bad interpreter: Permission denied

이는 보시다시피 상당히 많은 file들에 원래의 directory name, 즉 /root/miniconda3이 박혀 있기 때문입니다.  가령 conda라는 명령 자체도 아래와 같이 python script이며, 그 속에 원래 설치 directory의 이름이 박혀 있습니다.

u0017496@sys-87926:~$ vi /usr/local/miniconda3/bin/conda
#!/root/miniconda3/bin/python
if __name__ == '__main__':
    import sys
    import conda.cli

    sys.exit(conda.cli.main())


이에 대해서 아래 URL에 몇몇 user들이 토론을 벌인 바 있습니다.  실은 저 위의 Continuum 홈페이지에 '지우고 새로 설치하라'라고 하는 문서도 아래 github 토론에서 이야기가 나왔다가  Continuum 소속의 개발자가 사람들에게 공표하는 의미로 만든 것입니다.

https://github.com/ContinuumIO/anaconda-issues/issues/270

하지만 꼭 불가능한 것은 아닙니다.  위 github 토론에서도 (결론을 내지는 않았지만) '그냥 그 수많은 file들의 directory name들을 다 바꿔버리면 될 거다'라는 해결책을 제시한 개발자도 있었습니다.

제가 해보니 총 113개의 file만 고치면 되고, 실제로 sed 명령으로 고치면 꽤 쉽게 고칠 수 있으며, 결과적으로 잘 됩니다.

위에서처럼 cp와 chown을 해주고 환경변수 PATH 및 PYTHONPATH도 다 맞춰준 상태에서, 다음과 같이 예전 directory 이름, 즉 /root/miniconda3를 포함하는 text file들을 찾아 list를 만듭니다.  아래에서 find의 -type f는 (directory는 빼고) 파일만 찾으라는 것이고, grep의 -Iq (대문자 아이와 소문자 큐입니다)는 text file이 아닌 것은 즉각 무시하라는 뜻입니다.

u0017496@sys-87926:~$ for i in `find /usr/local/miniconda3 -type f -exec grep -Iq . {} \; -print`
> do
> grep "root\/miniconda3" $i
> if [[ $? -eq 0 ]]
> then
> echo $i >> matchlist.txt
> fi
> done

이 matchlist라는 새로 생성된 파일 속에는 아래처럼 /root/minconda3라는 string을 포함한 text file들의 목록이 들어 있습니다.

u0017496@sys-87926:~$ tail matchlist.txt
/usr/local/miniconda3/bin/idle3.6
/usr/local/miniconda3/bin/route53
/usr/local/miniconda3/bin/python3.6m-config
/usr/local/miniconda3/bin/cq
/usr/local/miniconda3/bin/conda
/usr/local/miniconda3/bin/instance_events
/usr/local/miniconda3/bin/freetype-config
/usr/local/miniconda3/bin/conda-env
/usr/local/miniconda3/bin/launch_instance
/usr/local/miniconda3/include/openssl/opensslconf.h

이제 이 파일들의 *.org(원본 보관용)과 *.new(임시작업용)을 복사해두고

u0017496@sys-87926:~$ for i in `cat matchlist.txt`
> do
> cp $i ${i}.org
> cp $i ${i}.new
> done

아래와 같이 sed 명령으로 "root/miniconda3"를 "usr/local/miniconda3"로 교체하여 임시작업용 *.new에 넣습니다.  그러고 난 뒤 원본을 이 *.new로 바꿔줍니다.

u0017496@sys-87926:~$ for i in `cat matchlist.txt`
> do
> sed 's/root\/miniconda3/usr\/local\/miniconda3/g' $i > ${i}.new
> cp ${i}.new $i
> done

임시작업용 파일들인 *.new는 나중에 삭제하셔도 됩니다.

보시면 아래와 같이 /root/miniconda가 /usr/local/miniconda3로 바뀐 것을 보실 수 있습니다.

u0017496@sys-87926:~$ grep usr\/local /usr/local/miniconda3/bin/pyvenv-3.6
#!/usr/local/miniconda3/bin/python

이제 conda 명령이 제대로 수행되는지 테스트 해보겠습니다.  보시다시피 잘 됩니다.

u0017496@sys-87926:~$ which conda
/usr/local/miniconda3/bin/conda

u0017496@sys-87926:~$ conda list
# packages in environment at /usr/local/miniconda3:
#
asn1crypto                0.22.0                   py36_0
bazel                     0.4.5                         0
boto                      2.47.0                    <pip>
bz2file                   0.98                      <pip>
cffi                      1.10.0                   py36_0
conda                     4.3.18                   py36_0
conda-env                 2.6.0                         0
cryptography              1.8.1                    py36_0
cudatoolkit               8.0                           0
cudnn                     6.0.21                        0
cycler                    0.10.0                   py36_0
freetype                  2.5.5                         2
gensim                    2.0.0                     <pip>
idna                      2.5                      py36_0
Keras                     2.0.4                     <pip>
konlpy                    0.4.4                     <pip>
libffi                    3.2.1                         1
libpng                    1.6.27                        0
libprotobuf               3.2.0                         0
matplotlib                2.0.2               np112py36_0
numpy                     1.13.0                    <pip>
numpy                     1.12.1                   py36_0
openblas                  0.2.19                        0
openssl                   1.0.2k                        2
packaging                 16.8                     py36_0
pip                       9.0.1                    py36_1
protobuf                  3.2.0                    py36_0
pyasn1                    0.2.3                    py36_0
pycosat                   0.6.2                    py36_0
pycparser                 2.17                     py36_0
pyopenssl                 17.0.0                   py36_0
pyparsing                 2.1.4                    py36_0
python                    3.6.1                         2
python-dateutil           2.6.0                    py36_0
pytz                      2017.2                   py36_0
PyYAML                    3.12                      <pip>
requests                  2.14.2                   py36_0
ruamel_yaml               0.11.14                  py36_1
scikit-learn              0.18.1              np112py36_1
scipy                     0.19.0                    <pip>
scipy                     0.19.0              np112py36_0
setuptools                27.2.0                   py36_0
six                       1.10.0                   py36_0
smart-open                1.5.3                     <pip>
sqlite                    3.13.0                        0
tensorflow                1.1.0               np112py36_0
tensorflow-gpu            1.1.0               np112py36_0
Theano                    0.9.0                     <pip>
werkzeug                  0.12.2                   py36_0
wheel                     0.29.0                   py36_0
xz                        5.2.2                         1
yaml                      0.1.6                         0
zlib                      1.2.8                         3


새로 package를 install하는 것도 잘 됩니다.

u0017496@sys-87926:~$ conda install flask
Fetching package metadata .........
Solving package specifications: .

Package plan for installation in environment /usr/local/miniconda3:

The following NEW packages will be INSTALLED:

    click:        6.7-py36_0
    flask:        0.12.2-py36_0
    itsdangerous: 0.24-py36_0
    jinja2:       2.9.6-py36_0
    markupsafe:   0.23-py36_2

Proceed ([y]/n)? y

click-6.7-py36 100% |######################################| Time: 0:00:00   7.96 MB/s
itsdangerous-0 100% |######################################| Time: 0:00:00  13.50 MB/s
markupsafe-0.2 100% |######################################| Time: 0:00:00  19.45 MB/s
jinja2-2.9.6-p 100% |######################################| Time: 0:00:00   8.85 MB/s
flask-0.12.2-p 100% |######################################| Time: 0:00:00   8.55 MB/s


뿐만 아니라, 새로 인터넷에서 download 받아 설치하는 것도 잘 됩니다.  (물론 이건 인터넷이 access되는 환경에서만 가능한 테스트입니다.)

u0017496@sys-87926:~$ pip install Jpype1
Collecting Jpype1
  Downloading JPype1-0.6.2.tar.gz (147kB)
    100% |████████████████████████████████| 153kB 2.8MB/s
Building wheels for collected packages: Jpype1
  Running setup.py bdist_wheel for Jpype1 ... done
  Stored in directory: /home/u0017496/.cache/pip/wheels/8e/f3/e6/a1250b8e8d2bd105f4dd21b1dc801dbcf5d815592443bfe741
Successfully built Jpype1
Installing collected packages: Jpype1
Successfully installed Jpype1-0.6.2


KoNLPy를 python에서 import 해보면 잘 되는 것을 보실 수 있습니다.   (이걸 테스트하시려면 위와 같이 Jpype1가 설치되어 있어야 합니다.)

u0017496@sys-87926:~$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-ppc64el

u0017496@sys-87926:~$ python
Python 3.6.1 |Continuum Analytics, Inc.| (default, May 11 2017, 15:31:35)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from konlpy.tag import *
>>> Kkma()
<konlpy.tag._kkma.Kkma object at 0x3fff97589b38>
>>>

이제 다른 user를 만들어서 이 /usr/local/miniconda를 쓸 수 있는지 보겠습니다.

root@sys-87926:/home/u0017496# adduser newuser

새로 만들어진 newuser로 login 한 뒤, PATH를 맞춰줍니다.

newuser@sys-87926:~$ vi .bashrc
export PATH=/usr/local/miniconda3/bin:$PATH
export PYTHONPATH=/usr/local/miniconda3/lib/python3.6/site-packages
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-ppc64el

newuser@sys-87926:~$ . ./.bashrc

보시다시피 다 잘 됩니다.

newuser@sys-87926:~$ conda list
# packages in environment at /usr/local/miniconda3:
#
asn1crypto                0.22.0                   py36_0
bazel                     0.4.5                         0
boto                      2.47.0                    <pip>
bz2file                   0.98                      <pip>
...
yaml                      0.1.6                         0
zlib                      1.2.8                         3


newuser@sys-87926:~$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-ppc64el
newuser@sys-87926:~$ python
Python 3.6.1 |Continuum Analytics, Inc.| (default, May 11 2017, 15:31:35)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from konlpy.tag import *
>>> Kkma()
<konlpy.tag._kkma.Kkma object at 0x3fffa4e49780>
>>>

/usr/local/miniconda3의 permission이 아래처럼 755로 되어 있으므로, 아래처럼 newuser라는 새로운 사용자는 conda uninstall이나 install 같은 것은 할 수 없습니다.  만약 다른 사용자들도 자유롭게 install/uninstall을 하기를 원하신다면 그에 맞춰 permission을 조정해주셔야 합니다.  그러나 되도록 그러지 않는 편이 낫겠지요.

u0017496@sys-87926:~$ ls -la /usr/local/miniconda3
total 76
drwxr-xr-x  11 u0017496 u0017496  4096 Jun 23 02:55 .
drwxr-xr-x  13 root     root      4096 Jun 22 22:35 ..
drwxr-xr-x   2 u0017496 u0017496  4096 Jun 23 02:20 bin
drwxr-xr-x   2 u0017496 u0017496 12288 Jun 23 02:55 conda-meta
drwxr-xr-x   3 u0017496 u0017496  4096 Jun 23 02:21 envs
drwxr-xr-x   3 u0017496 u0017496  4096 Jun 22 22:43 etc
drwxr-xr-x   8 u0017496 u0017496  4096 Jun 22 22:40 include
drwxr-xr-x   6 u0017496 u0017496  4096 Jun 23 02:12 lib
-rw-r--r--   1 u0017496 u0017496  3699 Jun 22 22:35 LICENSE.txt
drwxr-xr-x 238 u0017496 u0017496 24576 Jun 23 02:23 pkgs
drwxr-xr-x   4 u0017496 u0017496  4096 Jun 22 22:43 share
drwxr-xr-x   3 u0017496 u0017496  4096 Jun 22 22:43 ssl


newuser@sys-87926:~$ conda uninstall matplotlib

CondaIOError: Missing write permissions in: /usr/local/miniconda3
#
# You don't appear to have the necessary permissions to remove packages
# into the install area '/usr/local/miniconda3'.
# However you can clone this environment into your home directory and
# then make changes to it.
# This may be done using the command:
#
# $ conda create -n my_root --clone="/usr/local/miniconda3"


** 이 작업 및 test 결과는 아래의 Continuum github에도 comment로 올렸습니다.

https://github.com/ContinuumIO/anaconda-issues/issues/270

댓글 없음:

댓글 쓰기