D3에서 긴 텍스트에 대한 처리

이전 포스팅의 텍스트 줄바꿈 처리는 모든 브라우져에서 동작 하지 않는다. 확인 해본 결과 Firefox에서는 동작 하지만, 많이 사용되는 Chrome에서는 동작 하지 않는다.

모든 브라우져에서 동작하기 위한 코드를 찾아본 결과 Wrapping Long Labels을 발견 할 수 있었다.

위의 코드에서 wrap을 해주는 매소드에 보면 text 태그 하단에 들어가는 tspan이라는 태그를 발견 하였는데, 이를 이용하여 여러 라인 처리를 하는 것을 확인했다. 이를 활용하면 긴 문장에 대한 여러 방법으로 처리가 가능 하다.

function wrap(text, width) {
  text.each(function() {
    var text = d3.select(this),
        words = text.text().split(/\s+/).reverse(),
        word,
        line = [],
        lineNumber = 0,
        lineHeight = 1.1, // ems
        y = text.attr("y"),
        dy = parseFloat(text.attr("dy")),
        tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
    while (word = words.pop()) {
      line.push(word);
      tspan.text(line.join(" "));
      if (tspan.node().getComputedTextLength() > width) {
        line.pop();
        tspan.text(line.join(" "));
        line = [word];
        tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
      }
    }
  });
}

SVG tspan element을 보면 tspan 요소는 SVG에서 여러 텍스트를 그리는데 사용되는 테그로 설명 된다. 해당 태그를 이용하면 첨부된 소스를 사용하지 않고도 여러 라인의 문자열 처리가 가능하다.

라이선스 관련

Released under the GNU General Public License, version 3.

참고 자료

  1. Wrapping Long Labels
  2. SVG tspan element


Posted by lahuman

MongoDB] 설치 & 권한 설정

CentOS 7에서 MongoDB를 설치하고 권한을 설정하여 권한이 없는 사용자는 조회/등록/수정/삭제 기능을 사용하지 못하게 한다. MongoDB는 3.6 버젼 기준으로 설명한다.

1. 패키지 매니저에 MongoDB 추가

먼저 /etc/yum.repos.d/mongodb-org-3.6.repo 파일을 생성하고 다음 내역을 추가 한다.

[mongodb-org-3.6]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc

2. MongoDB 설치

MongoDB 패키지 설치를 진행 한다.

sudo yum install -y mongodb-org

설치가 완료 되면 mongod 프로세스를 시작한다.

sudo service mongod start

프로세스에 대한 정지 명령어는 다음과 같다.

sudo service mongod stop

만약 MongoDB를 삭제 하려면, mongod 프로세스를 정지 하고 mongodb 패키지를 삭제 한다.

sudo yum erase $(rpm -qa | grep mongodb-org)

설치가 완료 되었으면 설치된 MongoDB로 접속 하여 테스트를 진행 한다.

mongo --host 127.0.0.1:27017

3. MongoDB 사용자 추가

먼저 admin 권한을 설정한다.

use admin
db.createUser(
  {
    user: "myUserAdmin",
    pwd: "abc123",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

MongoDB 서비스를 재시작 하고, 접속시 로그인을 해보자

# 접속시 ID/PW 작성
mongo --port 27017 -u "myUserAdmin" -p "abc123" --authenticationDatabase "admin"

# 접속후 Login
mongo --port 27017
use admin
db.auth("myUserAdmin", "abc123" )

# 계정 추가
use test
db.createUser(
  {
    user: "myTester",
    pwd: "xyz123",
    roles: [ { role: "readWrite", db: "test" },
             { role: "read", db: "reporting" } ]
  }
)

하지만 아직까지는 Login을 하지 않아도 조회/등록등의 기능이 가능하다.

4. MongoDB 권한 설정

/etc/mongod.conf 설정 파일에서 다음 항목을 수정한다.

security:
    authorization: "enabled"

MongoDB 서비스를 재기동 하고 접속 테스트를 한다.

sudo service mongod restart

로그인 이후에 데이터 조회나 등록을 하려고 하면 권한이 없다는 메시지가 표출 된다.

mongo --port 27017

> db.test.insert( {x:1, y:1} )
WriteResult({
	"writeError" : {
		"code" : 13,
		"errmsg" : "not authorized on test to execute command { insert: \"test\", ordered: true, $db: \"test\" }"
	}
})
> db.test.find( {} )
Error: error: {
	"ok" : 0,
	"errmsg" : "not authorized on test to execute command { find: \"test\", filter: {}, $db: \"test\" }",
	"code" : 13,
	"codeName" : "Unauthorized"
}
# 로그인 진행
> db.auth('myTester', 'xyz123')
1
> db.test.find( {} )
{ "_id" : ObjectId("5b0b8c26efefcbe94ba75c29"), "x" : 1, "y" : 1 }
> db.test.insert( {x:1, y:1} )
WriteResult({ "nInserted" : 1 })
> db.test.find( {} )
{ "_id" : ObjectId("5b0b8c26efefcbe94ba75c29"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("5b0b8d6753b23794e42015e9"), "x" : 1, "y" : 1 }

참고 자료


Posted by lahuman

Python]paramiko 모듈에서 su 명령어로 계정 전환

python에서 ssh에 연결 후 command를 실행하기 위해 사용하는 paramiko 모듈에서 간단하게 command를 실행하는 코드는 다음과 같다.

import paramiko

ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # host keys 관련 설정
ssh_client.connect('127.0.0.1', username='lahuman', password='pass')

stdin, stdout, stderr = ssh_client.exec_command('ls')
stdin.flush()
time.sleep(1)
print stdout.read()

## 결과
lahuman
  • host kyes 관련 설정은 ssh로 다른 서버로 접근시, key 값을 저장할 지에 대한 처리 이다. paramiko.AutoAddPolicy() 로 설정시 자동으로 yes 처리 된다.

ssh_client.exec_command(cmd)를 이용할 경우 매 명령어 마다 새로운 세션이 부여되어, 다른 계정으로 전환 후 작업을 진행 할 수 없다.

하나의 세션에서 작업을 연속되게 진행하고 싶다면 channel = ssh_client.invoke_shell()를 이용하면 된다.

import paramiko

def main():
    ssh_client = None
    recv_size = 9999
    try:
		ssh_client = paramiko.SSHClient()
		ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # host keys 관련 설정
		ssh_client.connect('127.0.0.1', username='lahuman', password='pass')

        channel = ssh_client.invoke_shell()
        channel.send('su -\n')
        outdata, errdata = waitStrems(channel)
        print outdata

        channel.send('pass\n')
        outdata, errdata = waitStrems(channel)
        print outdata

        channel.send('whoami\n')
        outdata, errdata = waitStrems(channel)
        print outdata

    finally:
        if ssh_client is not None:
            ssh_client.close()


def waitStrems(chan):
    time.sleep(1)
    outdata=errdata = ""

    while chan.recv_ready():
        outdata += chan.recv(1000)
    while chan.recv_stderr_ready():
        errdata += chan.recv_stderr(1000)

    return outdata, errdata

if __name__ == "__main__":
    main()


## 결과
Last login: Thu May 17 01:34:37 2018 from 10.0.2.2
su -
[lahuman@localhost ~]$ su -
Password: 

Last login: Thu May 17 01:35:10 EDT 2018
[root@localhost ~]# 
whoami
root
[root@localhost ~]# 

세션을 유지한 상태로 명령어를 실행하기 위해서는 channel을 가져오고 channel을 계속 유지 해야 한다.

각 명령의 결과가 문제 없이 종료 되었는지는

 while chan.recv_ready():
        outdata += chan.recv(1000)
    while chan.recv_stderr_ready():
        errdata += chan.recv_stderr(1000)

를 통해서 확인 한다.

참고 자료


Posted by lahuman