MacOS에서 sudo 커맨드를 실행하면 다음과 같은 에러가 발생했다.


$ sudo -s

sudo: /etc/sudoers is owned by uid 502, should be 0

sudo: no valid sudoers sources found, quitting

sudo: unable to initialize policy plugin



$ su - root

Password:

su: Sorry




root 계정을 활성화하고 패스워드를 변경한다.


https://support.apple.com/ko-kr/HT204012





$ su - root


$ chown 0 /etc/sudoers




$ sudo

usage: sudo -h | -K | -k | -V

usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]

usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]

usage: sudo [-AbEHknPS] [-C num] [-g group] [-h host] [-p prompt] [-u user] [VAR=value] [-i|-s]

            [<command>]

usage: sudo -e [-AknS] [-C num] [-g group] [-h host] [-p prompt] [-u user] file ...





잘 동작한다. 




Posted by 김용환 '김용환'



파이썬의 선(zen of python)를 보려면 파이썬 인터프리터에서 this를 임포트하면 된다. 이스터 에그(Easter Egg)..




>>> import this

The Zen of Python, by Tim Peters


Beautiful is better than ugly.

Explicit is better than implicit.

Simple is better than complex.

Complex is better than complicated.

Flat is better than nested.

Sparse is better than dense.

Readability counts.

Special cases aren't special enough to break the rules.

Although practicality beats purity.

Errors should never pass silently.

Unless explicitly silenced.

In the face of ambiguity, refuse the temptation to guess.

There should be one-- and preferably only one --obvious way to do it.

Although that way may not be obvious at first unless you're Dutch.

Now is better than never.

Although never is often better than *right* now.

If the implementation is hard to explain, it's a bad idea.

If the implementation is easy to explain, it may be a good idea.

Namespaces are one honking great idea -- let's do more of those!




그동안의 경험을 기반으로 의역했다.



파이썬의 선, 팀 피터


아름다운 코드는 지저분한 코드보다 낫다.


명확한 코드는 암시적인 코드보다 낫다.


단순한 코드가 복잡한 코드보다 낫다.


복잡한 코드가 난해한 코드보다 낫다.


단조로운 코드가 복잡한 코드보다 낫다.


읽기 쉬운 코드는 읽기 어려운 코드보다 낫다.


가독성은 중요하다.


규칙을 깰 정도로 특별한 경우란 없다.


하지만 실용성은 이상을 능가한다.


에러를 결코 조용히 넘어가지 않도록 한다.


명시적으로 조용히 넘어가라고 하더라도 조용히 넘어가지 않는다.


모호한 코드를 대면할 때마다 추측하고 싶은 유혹을 거절하라.


문제를 해결할 단 하나의 명확하고 바람직한 방법이 있을 것이다. 


하지만 처음에 코딩을 할 때는 잘 모를 수 있기에 코드의 동작 방법을 정확히 알지 못 할 수 있다.


아무 것도 안하는 것보다 지금 하는 게 낫다.


하지만 아무 것도 하지 않는 것이 지금 *당장* 하는 것보다 나을 수도 있다.


설명하기 어려운 구현이라면 좋은 아이디어는 아니다.


쉽게 설명할 수 있는 구현이라면 좋은 아이디어일 것이다.


네임스페이스는 매우 훌륭한 아이디어이다. 많이 사용하자




'python' 카테고리의 다른 글

파이썬의 선(Zen of Python)  (0) 2018.09.23
[python] pickle 예시  (0) 2018.09.12
[python] urlsplit 예제  (0) 2018.09.12
파이썬 모듈 프로그래밍 예시 - __init__.py  (0) 2018.09.07
[python] whois 모듈  (0) 2018.09.03
[python] OptionParser 활용하는 사례  (0) 2018.07.04
Posted by 김용환 '김용환'



docker를 실행하면 대부분 기본 시간이 GMT+0이다.


따라서 시스템 환경에 맞출려면 다음과 같은 옵션을 주어 multiple docker volume을 맞추는 것이 좋다.


  -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime

Posted by 김용환 '김용환'





jenkins를 docker로 말아 올릴 때(jenkins Dockerfile 사용) 치명적인 이슈는 모든 environment variable을 사용할 수 없을 수 있다. 


동작할 것이라 생각한 두개의 변수는 비어 있었다.

BUILD_URL

JENKINS_URL_VALUE




Manager Jenkins->Configure System ( $jenkin-url:8080/configure) 에 접속해서 

Global properties의 Envrioment variables를 임의로 추가했더니..



BUILD_URL, JENKINS_URL_VALUE를 jenkins에서 읽어온다. 



Posted by 김용환 '김용환'


ubuntu 장비에서 진행했고,


master만 jenkins-docker를 사용하고, slave는 간단하게 기존처럼 실행(java 설치, 디폴트 디렉토리는 /var/lib/jenkins)가 되도록 했다.


jenkins master 장비에 docker를 실행할 때 최신 docker 18.06.ce 버전을 사용했고,


2.141 버전을 사용했다.


jenkins dockerfile은 https://github.com/jenkinsci/docker/blob/master/Dockerfile 에 있고,





< 주의 사항>


1. 백업은 필수 


docker가 죽어도 파일 시스템은 살아야 하니, 호스트 장비에 파일 시스템을 두었다. credentials이나 ssh, slave 설정, 추가 플러그인은 호스트 장비에 두어야 마음이 편할 것이다. (하지만 항상 백업하는 것이 중요하다. 자칫 잘못하면 도커 볼륨에 연결된 파일들이 모두 초기화될 수 있다) 


docker rm container_id 커맨드가 대표적이다.



2. jenkins-docker의 내부 홈 디렉토리는 /var/jenkins_home 이다.



3. docker volume 설정을 잘 적용한다.

ssh 설정, jenkins 홈 디렉토리를 docker외부에서 접근할 수 있도록 한다.


 -v  /home/www/.ssh/:/var/jenkins_home/.ssh




예를 들어 여러 개의 docker volumne을 설정하고 싶을 수 있다. 

ssh 설정은 docker host의 ssh 설정을 사용하고, docker의 timezone을 docker host의 timzezone 설정을 사용하도록 하고 jenkins 홈 디렉토리를 docker host의 디렉토리를 가르키게 하려면 다음을 실행한다.


sudo docker run --name google-jenkins-master -d  -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime -v /var/lib/jenkins:/var/jenkins_home -v  /home/www/.ssh/:/var/jenkins_home/.ssh -p 8080:8080 hub/google-jenkins-docker






4. 기본 계정은 Dockerfile에서 정의한다.

dockerfile 생성할 때 ADMIN_USERNAME, ADMIN_PASSWORD가 기본 패스워드이다. 


ENV JAVA_OPTS="-Djenkins.install.runSetupWizard=false" \

    ADMIN_USERNAME="google" \

    ADMIN_PASSWORD="google" \

...




5. 참고할 만한 dockerfile 설정은 다음과 같다. 



ENV JENKINS_FOLDER /usr/share/jenkins

USER ROOT


COPY plugins.txt "${JENKINS_FOLDER}/ref/plugins.txt"

COPY setupSecurity.groovy "${JENKINS_FOLDER}/ref/init.groovy.d/setupSecurity.groovy"

COPY setupProxy.groovy "${JENKINS_FOLDER}/ref/init.groovy.d/setupProxy.groovy"

COPY executors.groovy "${JENKINS_FOLDER}/ref/init.groovy.d/executors.groovy"

RUN /usr/local/bin/install-plugins.sh < "${JENKINS_FOLDER}/ref/plugins.txt"



6. 플러그인 추려내기

아래를 참조해서 잘 알아낸다. 실제 알고 있던 플러그인 이름이 plugins.txt 파일의 이름과 정확히 매칭되지 않으니.. 좀 시도해야 봐야 감이 잡힌다.

https://github.com/fabric8io/jenkins-docker/blob/master/plugins.txt



7.시작할 때 다음 url을 참고한다. 


https://github.com/jenkinsci/docker/blob/master/README.md

Posted by 김용환 '김용환'

docker inspect 커맨드

docker 2018.09.14 19:14



docker run을 실행한 후,  어떤 매개 변수를 썼는지 기억이 안날 때라든가,

현재 docker가 어떻게 실행되고 있는지 보려면 docker inspect 커맨드를 사용하면 된다.


여러 docker volume을 지원하는지도 알 수 있다..



$ sudo docker inspect google-jenkins



$ sudo docker inspect --format "{{ json .Mounts }}" google-jenkins



[{"Type":"volume","Name":"feda69298044ad46ab3444bd40ab81089e84cd5646259fa948b3325b8dfcd35f","Source":"/var/lib/docker/volumes/feda69298044ad46ab3444bd40ab81089e84cd5646259fa948b3325b8dfcd35f/_data","Destination":"/var/jenkins_home","Driver":"local","Mode":"","RW":true,"Propagation":""},{"Type":"volume","Name":"jenkins_home","Source":"/var/lib/docker/volumes/jenkins_home/_data","Destination":"/var/lib/jenkins","Driver":"local","Mode":"z","RW":true,"Propagation":""},{"Type":"bind","Source":"/root/.ssh","Destination":"/root/.ssh","Mode":"","RW":true,"Propagation":"rprivate"}]



https://docs.docker.com/engine/reference/commandline/inspect/#get-an-instances-image-name

Posted by 김용환 '김용환'


docker 실행 후, docker 프로세스의 memory 증가로 oom이 발생되고 os에서 docker 프로세스를 죽일 수 있다.


기본 docker 메모리는 unlimited이다.




$ cat /sys/fs/cgroup/memory/system.slice/docker.service/memory.stat 

cache 878325760

rss 58626048

rss_huge 0

mapped_file 20238336

dirty 0

writeback 0

swap 0

pgpgin 758173

pgpgout 529425

pgfault 431213

pgmajfault 1

inactive_anon 12288

active_anon 58683392

inactive_file 587464704

active_file 290791424

unevictable 0

hierarchical_memory_limit 9223372036854771712

hierarchical_memsw_limit 9223372036854771712

total_cache 878325760

total_rss 58626048

total_rss_huge 0

total_mapped_file 20238336

total_dirty 0

total_writeback 0

total_swap 0

total_pgpgin 758173

total_pgpgout 529425

total_pgfault 431213

total_pgmajfault 1

total_inactive_anon 12288

total_active_anon 58683392

total_inactive_file 587464704

total_active_file 290791424

total_unevictable 0






그런데. docker 메모리가 죽지 않도록 하려면. 다음과 같은 옵션을 docker run시 실행해야 한다. 


--oom-score-adj 값

--oom-kill-disable=true




관련된 도커 문서는 https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources에 존재한다.


문서에는 메모리 설정 내용이 포함되어 있다. 


Runtime constraints on resources

The operator can also adjust the performance parameters of the container:

OptionDescription
-m--memory=""Memory limit (format: <number>[<unit>]). Number is a positive integer. Unit can be one of bkm, or g. Minimum is 4M.
--memory-swap=""Total memory limit (memory + swap, format: <number>[<unit>]). Number is a positive integer. Unit can be one of bkm, or g.
--memory-reservation=""Memory soft limit (format: <number>[<unit>]). Number is a positive integer. Unit can be one of bkm, or g.
--kernel-memory=""Kernel memory limit (format: <number>[<unit>]). Number is a positive integer. Unit can be one of bkm, or g. Minimum is 4M.



잘 파신 분의 블로그

https://blog.2dal.com/2017/03/27/docker-and-oom-killer/


Posted by 김용환 '김용환'


jenkin migration할 때 어떤 plugin을 설치했는지 모를 때,

jenkins 홈디렉토리에 plugins 디렉토리를 찾아 설치할 수 있다.


jenkins docker에 plugin 목록으로 사용되니 알아두면 좋다.


JENKINS_HOME이 /var/lib/jenkins/plugins 이거라면 아래와 같이 실행해 플러그인 설치 목록을 확인할 수 있다. 


$ cd  /var/lib/jenkins/plugins


$ ls -al *.jpi  | awk '{print $9}'  | sed 's/.jpi//'

antisamy-markup-formatter

ant

build-timeout

changelog-history

config-file-provider

credentials

external-monitor-job

git-client

github-api

github

github-oauth

git

icon-shim

javadoc

job-restrictions

junit

ldap

locale

mailer

mapdb-api

matrix-auth

matrix-project

naginator

pam-auth

parameterized-trigger

plain-credentials

pyenv

python

ruby-runtime

scm-api

script-security

shiningpanda

ssh-agent

ssh-credentials

ssh-slaves

structs

subversion

token-macro

windows-slaves

workflow-step-api


Posted by 김용환 '김용환'

[python] pickle 예시

python 2018.09.12 14:57



자바의 serialization/deserialization은 언어/jvm 레벨에서 이루어지지만,


파이썬에서는 모듈 단에서 이루어진다. 대표적인 모듈이 pickle이다.


https://docs.python.org/3/library/pickle.html




파이썬에서 list를 바로 파일로 저장할 수 없다. 



>>> mylist = ['a', 'b', 'c', 'd']

>>> with open('test.txt','wb') as f:

...     pickle.dump(mylist,f)

...

>>> with open('test.txt','rb') as f:

...     yourlist=pickle.load(f)

...

>>> yourlist

['a', 'b', 'c', 'd']




주의할 점은 bytes가 아니라 string으로 읽고 저장, 즉 'wb', 'rb'를 해야 한다.


>>> with open('test.txt','w') as f:

...     pickle.dump(mylist,f)

...

Traceback (most recent call last):

  File "<stdin>", line 2, in <module>

TypeError: write() argument must be str, not bytes


'python' 카테고리의 다른 글

파이썬의 선(Zen of Python)  (0) 2018.09.23
[python] pickle 예시  (0) 2018.09.12
[python] urlsplit 예제  (0) 2018.09.12
파이썬 모듈 프로그래밍 예시 - __init__.py  (0) 2018.09.07
[python] whois 모듈  (0) 2018.09.03
[python] OptionParser 활용하는 사례  (0) 2018.07.04
Posted by 김용환 '김용환'

[python] urlsplit 예제

python 2018.09.12 13:12



python에서 URL을 파싱하려면 urllib.parse 모듈의 urlsplit 함수를 사용한다. urlsplit 함수는 URL을 각 구성 요소로 분리한다.




>>> from urllib.parse import urlsplit


>>> components = urlsplit('http://example.webscraping.com/places/default/view')


>>> print(components)

SplitResult(scheme='http', netloc='example.webscraping.com', path='/places/default/view', query='', fragment='')


>>> print(components.path)

/places/default/view





'python' 카테고리의 다른 글

파이썬의 선(Zen of Python)  (0) 2018.09.23
[python] pickle 예시  (0) 2018.09.12
[python] urlsplit 예제  (0) 2018.09.12
파이썬 모듈 프로그래밍 예시 - __init__.py  (0) 2018.09.07
[python] whois 모듈  (0) 2018.09.03
[python] OptionParser 활용하는 사례  (0) 2018.07.04
Posted by 김용환 '김용환'