2013-10-11

Visual Studio 인코딩 설정하기



Visual Studio 6.0 에서는 내부 인코딩이 "멀티바이트 문자 집합"이었으나, Visual Studio 2012 는 기본으로 "유니코드 문자 집합"을 사용한다. 어떤 사정에 의해서 "멀티바이트 문자 집합"을 사용하려면 아래와 같이 한다.

프로젝트 속성 (Alt+F7) → 구성 속성 → 일반 → 문자집합 에서 "멀티바이트 문자 집합 사용" 또는 "유니코드 문자 집합 사용" 선택

2013-09-29

Django : Template에서 Session값 이용하기



views.py 에서 세션을 참조하려면, 아래와 같이 사용하지만, Template 에서는 같은 문법을 사용할 수 없다.
request.session['세션이름'] = '값'
Template에서 Session을 이용하는 방법을 알아보자. settings.py 에 다음을 추가한다.
TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.request',
)
views.py 에서는 render 함수를 이용해서 리턴한다.
return render(request, 'session_test.html')
Template에서는 아래와 같이 사용한다.
{{ request.session.세션이름 }}

2013-05-28

Django : login_required 데코레이터


Django 의 내장 authentication 모듈을 사용하지 않는 경우, 직접 제작을 해야 하는데, login_required 라는 데코레이터가 없어서, 매번 View 에서 접근 로직을 작성해주어야 해서 번거로웠다. 아래와 같이 별도의 데코레이터를 작성해두면 로직이 바뀌더라도 하나만 변경하면 되니까 코드 관리가 좀 더 편할 것이다.

def login_required(function=None):
    def _dec(view_func):
        def _view(request, *args, **kwargs):
 
            # 아래 로직을 적당히 자신의 사이트에 맞게 고쳐서 쓰면 될 것이다.
            if "login_yn" not in request.session:
                return HttpResponseRedirect('/')
            else:
                return view_func(request, *args, **kwargs)
 
        _view.__name__ = view_func.__name__
        _view.__dict__ = view_func.__dict__
        _view.__doc__ = view_func.__doc__
        return _view
 
    if function is None:
        return _dec
    else:
        return _dec(function)

2013-03-14

(Perl) Hitachi Storage 장애 체크 (Web)

히다찌 스토리지에서는 상태점검을 위해서 웹인터페이스를 제공하고 있다. 해당 웹페이지의 메뉴에서 Warning Information 에서 문제가 있으면 로그가 표시되는데, 여기에 아무것도 없으면 장애가 없는 것이고, 뭔가 하나라도 있으면 장애가 있다는 것이다.

해당 페이지의 첫번째 TEXTAREA 태그의 내용을 확인하며 되며, 이를 위해서 WWW::Mechanize 모듈을 사용하였다. 그리고, 장애 발견시 담당자에게 문자를 보내도록 하였다.

Strawberry Perl 5.16.2 에서 테스트하였으며, 사용하는 모듈은 모두 기본으로 내장되어 있어서 별도로 설치할 필요없다.

#!perl
# ------------------------------------------------------------------------------
# (1) 히다찌 스토리지의 웹관리화면의 경고창을 조회하여 Warning Information 항목에 
#     내용이 있으면 장애로 간주하고 담당자에게 문자메시지를 보낸다.
#
# (2) 하루에 2번 작동한다.
#
# Perl Version : 5.16.2
# ------------------------------------------------------------------------------
use 5.016;
use strict;
use warnings;
use diagnostics;
 
use DBI;
use WWW::Mechanize;
# ------------------------------------------------------------------------------
 
# ------------------------------------------------------------------------------
sub send_sms {
    my $msg = shift(@_);
 
    my $dsn = "DBI:ODBC:Driver={SQL Server};Server=서버주소;Database=데이터베이스이름";
 
    my $sql = "insert arreo_sms ( CMP_MSG_ID, 
               CMP_USR_ID, 
               WRT_DTTM, 
               RCV_PHN_ID, 
               CALLBACK, 
               SND_DTTM, 
               SND_MSG , 
               SND_PHN_ID, 
               RSRVD_ID ) 
               values ('011' + CONVERT(varchar, GETDATE(), 12) + REPLACE(CONVERT(varchar, GETDATE(), 14), ':', '') + SUBSTRING(CONVERT(VARCHAR, RAND(), 109), 3, 2), 
               '00000', 
               CONVERT(varchar, GETDATE(), 112) + REPLACE(CONVERT(varchar, GETDATE(), 8), ':', ''), 
               '받는사람전화번호',
               '보내는사람전화번호',
               CONVERT(varchar, GETDATE(), 112) + REPLACE(CONVERT(varchar, GETDATE(), 8), ':', ''), 
               '$msg', 
               'ADMIN', 
               'ADMIN' ) ";
 
    my $dbh = DBI->connect($dsn, '아이디', '비밀번호') || die $DBI::errstr;
    $dbh->do($sql);
    $dbh->disconnect;
}
# ------------------------------------------------------------------------------
 
 
# ------------------------------------------------------------------------------
# Start
# ------------------------------------------------------------------------------
my %devices = ( "HITACHI_STORAGE1", "http://172.16.0.21/cgiShowMsgInf/ShowMsgInf.cgi/CLK/inf_msg",
                "HITACHI_STORAGE2", "http://172.16.0.22/cgiShowMsgInf/ShowMsgInf.cgi/CLK/inf_msg" );
 
foreach my $device_key (keys %devices) {
    my $mech = WWW::Mechanize->new();
    $mech->get( $devices{$device_key} );
    my @customer_text_inputs = $mech->find_all_inputs( type => 'textarea' );
    my $msg = "";
    if ($customer_text_inputs[0]->value eq "\n") {
        $msg = "Hitachi Storage $device_key : Normal";
        # send_sms($msg);
    } else {
        $msg = "Hitachi Storage $device_key : Error";
        send_sms($msg);
    }
    say $msg;
}

2013-03-13

Python : SAN 스위치 장애 체크 (Telnet)

이번에는 Python 에서 SAN 스위치 장애를 체크하는 스크립트를 만들어보았다. Perl 의 경우와 거의 같다.

Python 2.7.3 에서 테스트하였으며, pymssql 를 별도로 설치해야 한다.

# -*- coding: cp949 -*-
# ------------------------------------------------------------------------------
# (1) SAN 스위치의 Telnet에 연결하여, switchstatusshow 명령의 결과에 따라서
#     HEALTHY 가 아니면 장애로 간주하고 담당자에게 문자메시지를 보낸다.
#
# (2) 하루에 1번 작동한다.
#
# Python Version : 2.7.3
# 
# [필요한 패키지]
# easy_install pymssql
#
# Normal Status ----------------------------------------------------------------
# SwitchState:    HEALTHY
# ------------------------------------------------------------------------------
import telnetlib
import pymssql

# ------------------------------------------------------------------------------
def send_sms(msg):
    sql = """ insert arreo_sms ( CMP_MSG_ID, 
        CMP_USR_ID, 
        WRT_DTTM, 
        RCV_PHN_ID, 
        CALLBACK, 
        SND_DTTM, 
        SND_MSG , 
        SND_PHN_ID, 
        RSRVD_ID ) 
        values ('011' + CONVERT(varchar, GETDATE(), 12) + REPLACE(CONVERT(varchar, GETDATE(), 14), ':', '') + SUBSTRING(CONVERT(VARCHAR, RAND(), 109), 3, 2), 
        '00000', 
        CONVERT(varchar, GETDATE(), 112) + REPLACE(CONVERT(varchar, GETDATE(), 8), ':', ''), 
        '%s',
        '01055555555',
        CONVERT(varchar, GETDATE(), 112) + REPLACE(CONVERT(varchar, GETDATE(), 8), ':', ''), 
        '%s', 
        'ADMIN', 
        'ADMIN' ) """ % ("메시지받을사람의전화번호", msg)
    conn = pymssql.connect(host='서버주소', user='아이디', password='비밀번호', database='DB이름')
    cur = conn.cursor()
    cur.execute(sql)
    conn.commit()
    conn.close()

# ------------------------------------------------------------------------------

devices = { "SAN_SW1" : "172.16.0.21",
            "SAN_SW2" : "172.16.0.22",
            "SAN_SW3" : "172.16.0.23",
            "SAN_SW4" : "172.16.0.24" }

for device_key in devices.keys() :
    tn = telnetlib.Telnet(devices[device_key])
    tn.read_until("login: ")
    tn.write("아이디\n")
    tn.read_until("Password: ")
    tn.write("비밀번호\n")
    tn.write("\n")
    tn.write("switchstatusshow\n")
    tn.write("exit\n")
    result = tn.read_all()
    for line in result.splitlines() :
        if "SwitchState:" in line :
            if "HEALTHY" in line :
                msg = device_key + " : Normal"
                print(msg)
                send_sms(msg)
            else :
                msg = device_key + " : Error"
                print(msg)
                send_sms(msg)

2013-03-11

(Perl) SAN 스위치 장애 체크 (Telnet)

대부분의 네트워크 장비에서는 콘솔로 작업을 할 수 있도록 ssh, telnet 등의 접속을 지원하고 있다. 가장 많이 이용되는 SAN 스위치 중의 하나인 브로케이드(EMC) 의 SAN 스위치에서는 switchstatusshow 명령을 통해서 장비의 상태를 확인할 수 있는데, SwitchState 항목을 체크하면 장비의 전체적인 상태를 알아볼 수 있다. 여기에서는 간단하게 Telnet 으로 접근하여 해당 항목이 HEALTHY 인지 여부에 따라서 정상이 아니면, 담당자에게 문자를 보낼 수 있다록 해보았다.

Strawberry Perl 5.16.2 에서 테스트하였으며, 사용하는 모듈은 모두 기본으로 내장되어 있어서 별도로 설치할 필요없다.

Ruby 에서도 한번 구현해보려고 했는데, 신형 장비(EMC)에는 잘 접속이 되었으나, 구 장비(Brocade)에는 로그인이 제대로 성공하지 못했다.

#!perl
# ------------------------------------------------------------------------------
# SAN 스위치 장애 체크 (Telnet)
# ------------------------------------------------------------------------------
# (1) SAN 스위치의 Telnet에 연결하여, switchstatusshow 명령의 결과에 따라서
#     HEALTHY 가 아니면 장애로 간주하고 담당자에게 문자메시지를 보낸다.
#
# (2) 하루에 1번 작동한다.
#
# Perl Version : 5.16.2
# 
# Normal Status ----------------------------------------------------------------
# SwitchState:    HEALTHY
# ------------------------------------------------------------------------------
use 5.016;
use strict;
use warnings;
use diagnostics;

use Net::Telnet;
use DBI;

# ------------------------------------------------------------------------------
sub send_sms {
    my $msg = shift(@_);

    my $dsn = "DBI:ODBC:Driver={SQL Server};Server=서버주소;Database=데이터베이스이름";
    
    # 아레오 SMS 의 경우
    my $sql = "insert arreo_sms ( CMP_MSG_ID, 
               CMP_USR_ID, 
               WRT_DTTM, 
               RCV_PHN_ID, 
               CALLBACK, 
               SND_DTTM, 
               SND_MSG , 
               SND_PHN_ID, 
               RSRVD_ID ) 
               values ('011' + CONVERT(varchar, GETDATE(), 12) + REPLACE(CONVERT(varchar, GETDATE(), 14), ':', '') + SUBSTRING(CONVERT(VARCHAR, RAND(), 109), 3, 2), 
               '00000', 
               CONVERT(varchar, GETDATE(), 112) + REPLACE(CONVERT(varchar, GETDATE(), 8), ':', ''), 
               '01055551234',
               '01055554321',
               CONVERT(varchar, GETDATE(), 112) + REPLACE(CONVERT(varchar, GETDATE(), 8), ':', ''), 
               '$msg', 
               'ADMIN', 
               'ADMIN' ) ";

    my $dbh = DBI->connect($dsn, '아이디', '비밀번호') || die $DBI::errstr;
    $dbh->do($sql);
    $dbh->disconnect;
}
# ------------------------------------------------------------------------------

my %devices = ( "SAN_SW1", "172.16.0.21",
                "SAN_SW2", "172.16.0.22",
                "SAN_SW3", "172.16.0.23",
                "SAN_SW4", "172.16.0.24", );

foreach my $device_key (keys %devices) {
    my $tn = new Net::Telnet (Host => $devices{$device_key}, Timeout => 5, Prompt => '/> /');
    $tn->login("아이디", "비밀번호");
    my @lines = $tn->cmd("switchstatusshow");
    foreach my $line (@lines) {
        if ($line =~ /SwitchState/) {
            my $msg = "";
            if ($line =~ /HEALTHY/) {
                $msg = "$device_key : Normal";
                # send_sms($msg);
            } else {
                $msg = "$device_key : Error";
                send_sms($msg);
            }
            say $msg;
        }
    } 
    $tn->close();
}

2013-03-04

NetBSD 커널 컴파일하기




NetBSD 의 커널을 컴파일하는 방법을 정리해보았다. 같은 BSD 계열이라서 FreeBSD 와도 많이 비슷한 면이 있다.
  • 커널 설정 파일 생성하기
    # cd /usr/src/sys/arch/i386/conf/
    # cp GENERIC MYKERNEL
    
  • 커널 수동 빌드
    # config MYKERNEL
    # cd ../compile/MYKERNEL
    # make depend
    # make
    
  • build.sh 를 사용하여 커널 빌드하기
    # cd /usr; mkdir obj; chown root:wsrc obj
    # cd /usr/src
    # ./build.sh tools
    # ./build.sh kernel=MYKERNEL
    
  • 새로운 커널 설치하기
    # mv /netbsd /netbsd.old
    # cd /usr/src/sys/arch/i386/compile/obj/MYKERNEL
    # mv netbsd /
    
    # shutdown -r now
    

2013-03-02

NetBSD 설치후 작업



[NetBSD Logo]

BSD 계열의 유닉스인 NetBSD 를 설치하고 난 뒤에서 기본적으로 설치/설정할 것들을 정리해보았다. 특징적인 것은 pkgin 이라는 바이너리 패키지 관리도구로 인해서 쉽게 패키지를 설치/업그레이드를 할 수 있어서, Linux 처럼 쉽고 편하게 관리할 수 있다. BSD의 특징인 간단/명료/단순함도 함께 살아있다. 거기에 라이센스도 GPL 이 아닌 BSD 라이센스여서 더욱 자유롭다.
  • sshd_config 수정 / 재시작 : root로 로그인하는 것은 보안상 문제가 있지만, 편의를 위해 일단 이렇게 해놓자.
    # vi /etc/ssh/sshd_config
    PasswordAuthentication yes
    PermitRootLogin yes
    # /etc/rc.d/sshd restart
    
  • root, toor 계정쉘을 bash로 변경
    # pkgin install bash; chsh -s bash root; chsh -s bash toor
    # ln -s /usr/pkg/bin/bash /bin/bash
    
    쉘도 다시 설정했으니, 로그아웃하고 다시 로그인하자~!!!
  • 필요한 패키지 설치
    # pkgin install tmux vim ntp gnuls htop git curl wget gnu-watch readline sqlite3 libxslt libxml2 openssl gmake python27
    
  • Python 설정
    # cd /usr/pkg/bin/
    # ln -s python2.7 python
    
  • /etc/profile 에 PS1 설정
    if [ "`id -u`" -eq 0 ]; then
      PS1="\e[32;1m\]\u@\[\e[35;1m\] \[\e[0m\]\w]# "
    else
      PS1="\e[32;1m\]\u@\[\e[35;1m\] \[\e[0m\]\w]$ "
    fi
    
  • gls alias 적용
    # echo 'alias ls="gls --color=always"' >> /etc/profile; source /etc/profile
    
  • vim 적용
    # echo 'alias vi="vim"' >> /etc/profile; source /etc/profile
    
  • 언어 설정
    # echo 'export LANG=ko_KR.UTF-8' >> /etc/profile; source /etc/profile
    
  • 사용자 추가
    # useradd -m -G wheel -s /usr/pkg/bin/bash 아이디
    # passwd 아이디