며칠동안 생고생을 하면서 알아낸 방법입니다.

VMWare fusion4 에서 아무리 환경 설정에서 vt-x 를 활성화 해서 Ubuntu 를 설치해 봤자 vmx 가 활성화 안됩니다.

결국 nova 의 compute 데몬이 실행이 안되지요..

해결방법은 게스트 OS 의 vmx 파일에서 아래의 내용을 추가하면 됩니다.

vhv.enable = "TRUE"
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

댓글을 달아 주세요

Nova 소스 위치

OpenStack/Nova 2011. 12. 20. 10:14
소스 원본 : /usr/share/pyshared/nova
링       크 : /usr/lib/python2.7/dist-packages/nova



Posted by Kubernetes Korea co-leader seungkyua@gmail.com

댓글을 달아 주세요

Nova Boot 순서

OpenStack/Nova 2011. 11. 4. 18:00

nova 에서 instance 를 생성할 때 호출되는 Sequence 흐름을 표현한다.
모듈별 흐름으로 보면 다음과 같다.

API -> COMPUTE -> RabbitMQ -> SCHEDULER -> RabbitMQ -> COMPUTE

1. api/openstack/servers.py -> create()
     1-1. api/openstack/create_instance_helper.py -> create_instance()
            - request 로 넘어온 값을 추출
            - glance Image 서버에 접근할 수 있는 객체 생성
            - glance 로 부터 image id, kernel id, ramdisk id 를 조회
            1-1-1. compute/instance_types.py -> get_instance_type_by_flavor_id()
                      - db로 부터 instance type 을 조회
            1-1-2. compute/api.py -> create()
                      - 넘어온 파라미터에 대한 체크
                      1-1-2-1. create_db_entry_for_new_instance()
                                   1-1-2-1-1. self.db.security_group_get_by_name()
                                                   - db에서 security group name 으로 id를 조회
                                   1-1-2-1-2. self.db.instance_create()
                                                   - instance 테이블에 기본 값만 추가하여 instance id 를 생성
                                   1-1-2-1-3. self.db.instance_add_security_group()
                                                   - security_group_instance_association 테이블에 값을 추가
                                   1-1-2-1-4. self._update_image_block_device_mapping()
                                                   - glance 에서 가져온 image 메타데이터 mappings 정보를 이용
                                                   1-1-2-1-4-1. self.db.block_device_mapping_update_or_create()
                                                                      - 파라미터로 넘어온 mappings 값이 있으면
                                                                         block_device_mapping 테이블에 저장
                                   1-1-2-1-5. self._update_block_device_mapping()
                                                   - glance 에서 가져온 image 메타데이터 block_device_mappings
                                                      정보를 이용
                                                   1-1-2-1-5-1. self.db.block_device_mapping_update_or_create()
                                                                      - 파라미터로 넘어온 mappings 값이 있으면
                                                                         block_device_mapping 테이블에 저장
                                   1-1-2-1-6. self._update_block_device_mapping()
                                                   - 파라미터로 넘어온 mappings 정보를 이용
                                                   1-1-2-1-6-1. self.db.block_device_mapping_update_or_create()
                                                                      - 파라미터로 넘어온 mappings 값이 있으면
                                                                         block_device_mapping 테이블에 저장
                                   1-1-2-1-7. self.update()
                                                   1-1-2-1-7-1. self.db.instance_update()
                                                                      - instances 테이블에 vm_state 와 task_state 값을
                                                                        BUILDING, SCHEDULING 으로 수정

                      1-1-2-2. _ask_scheduler_to_create_instance()
                                   1-1-2-2-1. rpc.cast(context,
                                                               FLAGS.scheduler_topic,
                                                               {"method": "run_instance",
                                                                    "args": {"topic": FLAGS.compute_topic,
                                                                                "instance_id": instance_id,
                                                                                "request_spec": request_spec,
                                                                                "availability_zone": availability_zone,
                                                                                "admin_password": admin_password,
                                                                                "injected_files": injected_files,
                                                                                "requested_networks": requested_networks}})
                                                   - rpc.cast 로 scheduler 의 run_instance 메소드를 호출 

2. scheduler/manager.py.SchedulerManager -> __getattr__()
    - run_instance 메소드가 없으니 __getattr__ 메소드가 호출됨
    2-1. _schedule()
           2-1-1. scheduler/multi.py -> __getattr__()
                     - schedule_run_instance 메소드가 없으니 __getattr__ 메소드가 호출
                     2-1-1-1. scheduler/chance.py.ChanceScheduler -> schedule_run_instance()
                                  - schedule_run_instance() 가 없어 AttributeError exception 이 발생
           2-1-2. scheduler/multi.py -> schedule()
                     2-1-2-1.  scheduler/chance.py.ChanceScheduler -> schedule()
           2-1-3. rpc.cast(context,
                                  db.queue_get_for(context, topic, host),
                                  {"method": method,
                                    "args": kwargs})
                     - rpc.cast 로 compute 의 run_instance 메소드를 호출  

3. compute/manager.py.ComputeManager -> run_instance()
    3-1. self._run_instance()
           3-1-1. self.db.instance_get()
                     - db 에서 instance 정보를 조회함
           3-1-2. virt/libvirt/connection.py.LibvirtConnection -> list_instances()
                     - libvirt 를 이용하여 kvm 에서 기동중인 instance vm id 를 조회
                     - instance['name'] 이 kvm 에서 조회되는 vm id 임
           3-1-3. self.db.instance_update()
                     - instances 테이블에 vm_state 와 task_state 를 BUILDING, NETWORKING 으로 변경
           - FLAGS.stub_network 이 False 이면
           3-1-3. network/api.py.API -> allocate_for_instance()
                  3-1-3-1. rpc.call(context, FLAGS.network_topic,
                                    {'method': 'allocate_for_instance',
                                     'args': args})
           3-1-4. self._instance_update()
                     3-1-4-1. self.db.instance_update()
                                  - instances 테이블에 vm_state 와 task_state 를 BUILDING,
                                     BLOCK_DEVICE_MAPPING으로 변경
           3-1-5. self._setup_block_device_mapping() 
                      3-1-5-1. self.db.block_device_mapping_get_all_by_instance()
                                   - instances 테이블과 block_device_mapping 테이블을 조인하여 조회
                                   - snapshot_id 값이 있고, volume_id 값이 없으면 아래가 호출됨
                      3-1-5-2. volume/apy.py.API -> create()
                                   3-1-5-2-1. self.db.snapshot_get()
                                   3-1-5-2-2. quota.py -> allowed_volumes()
                                   3-1-5-2-3. self.db.volume_create()
                                                   - volumes 테이블에 추가, status, attach_status 는 creating,
                                                      detached 로 세팅 
                                   3-1-5-2-4. rpc.cast(context,
                                                               FLAGS.scheduler_topic,
                                                               {"method": "create_volume",
                                                                "args": {"topic": FLAGS.volume_topic,
                                                                            "volume_id": volume['id'],
                                                                            "snapshot_id": snapshot_id}})
                                                  - rpc.cast 로 Volume 을 호출
 
                       3-1-5-3. volume/manager.py.VolumeManager -> create_volume()
                                    3-1-5-3-1. self.db.volume_get()
                                                    - volumes 테이블 정보 조회
                                    3-1-5-3-2. self.db.volume_update()
                                                    - volumes 테이블 host colume 에 떠있는 host 값 저장
                                    - snapshot_id 가 없으면 아래가 호출
                                    3-1-5-3-3. volume.san.py.HpSanISCSIDriver -> create_volume()
                                    - snapshot_id 가 있으면 아래가 호출
                                    3-1-5-3-4. self.db.snapshot_get() 
                                    3-1-5-3-5. volume.san.py.HpSanISCSIDriver ->
                                                                                              create_volume_from_snapshot()
                                    - iSCSI 를 노출
                                    3-1-5-3-6. volume.san.py.HpSanISCSIDriver -> create_export()
                                    3-1-5-3-7. self.db.volume_update()
                                                    - volumes 테이블의 status, launched_at 을 available,
                                                       utils.py -> utcnow() 로 수정

                       3-1-5-4. volume/apy.py.API -> wait_creation()
                                    - greenthread.sleep(1) 을 호출하여 volumes 테이블의 status 를 체킹
                       3-1-5-5. self.db.block_device_mapping_update()
                                    - block_device_mapping 테이블의 volume_id 값을 volumes 테이블의 id 로 세팅
                       3-1-5-6. volume/apy.py.API -> check_attach()
                                    - volumes 테이블을 조회하여 status 가 available 인지 체크
                       3-1-5-7. self._attach_volume_boot()
                                   3-1-5-7-1. volume/apy.py.API -> check_attach()
                                   3-1-5-7-2. volume/manager.py.VolumeManager -> setup_compute_volume()
                                                   - volumes 테이블을 조회하여 host 값이 현재의 host 와 같고
                                                      FLAGS.use_local_volumes 값이 True 이면
                                                   3-1-5-7-2-1. volume.san.py.HpSanISCSIDriver -> local_path()
                                                   - 아니면
                                                   3-1-5-7-2-2. volume.driver.py.ISCSIDriver -> discover_volume()
                                                                      3-1-5-7-2-2-1. self._get_iscsi_properties()
                                                                                            - self._execute('iscsiadm', '-m',
                                                                                                                  'discovery',
                                                                                                                  '-t', 'sendtargets',
                                                                                                                  '-p', volume['host'],
                                                                                                                   run_as_root=True)
                                                                                             - mount_device = ("/dev/disk/by-path/ip-
                                                                                                                       %s-iscsi-%s-lun-0" %
                                                                                                           (iscsi_properties['target_portal'],
                                                                                                            iscsi_properties['target_iqn']))
                                                                                             - export 가 안되면
                                                                                               FLAGS.num_iscsi_scan_tries만큼 반복
                                                   3-1-5-7-2-3. self.db.volume_attached()
                                                                      - volumes 테이블의 status, mountpoint, attach_status 값을
                                                                         in-use, device_name, attached 로 변경 
           3-1-6. self._instance_update()
                     3-1-6-1. self.db.instance_update()
                                  - instances 테이블에 vm_state 와 task_state 를 BUILDING, SPAWNING 으로 변경
           3-1-7. virt/libvirt/connection.py.LibvirtConnection -> spawn()
                     3-1-7-1. self.to_xml()
                                  3-1-7-1-1. self._prepare_xml_info()
                                                  3-1-7-1-1-1. virt/driver.py -> block_device_info_get_mapping()
                                                  3-1-7-1-1-2. virt/libvirt/vif.py.LibvirtBridgeDriver -> plug()
                                                                     - multi_host 가 False 이고 should_create_bridge 가 True
                                                                        - should_create_vlan 이 True 이면
                                                                           3-1-7-1-1-2-1. network/linux_net.py.
                                                                                                     LinuxBridgeInterfaceDriver
                                                                                                            -> ensure_vlan_bridge()
                                                                        - should_create_vlan 이 False 이면
                                                                           3-1-7-1-1-2-2. network/linux_net.py.
                                                                                                     LinuxBridgeInterfaceDriver 
                                                                                                            -> ensure_bridge()
                                                                     3-1-7-1-1-2-3. self._get_configurations()
                                                  3-1-7-1-1-3. compute/instance_types.py -> get_instance.type()
                                                  3-1-7-1-1-4. self._volume_in_mapping()
                                                  3-1-7-1-1-5. virt/driver.py -> block_device_info_get_ephemerals()
                                                  3-1-7-1-1-6. virt/driver.py -> block_device_info_get_root()
                                                  - root_device_name 이 있다면 그대로 데이터를 이용
                                                  - root_device_name 이 없다면
                                                  3-1-7-1-1-7. db.instance_update()
                                                  - local_device 가 True 라면
                                                  3-1-7-1-1-8. db.instance_update()
                                                  3-1-7-1-1-9. virt/driver.py -> block_device_info_get_swap()
                                                  - FLAGS.vnc_enabled and FLAGS.libvirt_type not in ('lxc', 'uml') 라면
                                                     xml_info['vncserver_host'] 및 xml_info['vnc_keymap'] 에 세팅
                     3-1-7-2. virt/libvirt/firewall.py.IptablesFirewallDriver -> setup_basic_filtering() 
                                  3-1-7-2-1. virt/libvirt/firewall.py.NWFilterFirewall -> setup_basic_filtering()
                                                  3-1-7-2-1-1. self._ensure_static_filters()
                                                  3-1-7-2-1-2. self._define_filter(self._filter_container())
                                  3-1-7-2-2. self.refresh_provider_fw_rules()
                                                  3-1-7-2-2-1. self._do_refresh_provider_fw_rules()
                                                                     3-1-7-2-2-1-1. self._purge_provider_fw_rules()
                                                                     3-1-7-2-2-1-2. self._build_provider_fw_rules()
                                                  3-1-7-2-2-2. self.iptables.apply()
                                                                     3-1-7-2-2-2-1. network/linux_net.py.IptablesManager
                                                                                                                                         -> apply()
                                                                                          3-1-7-2-2-2-1-1. self._modify_rules() 
                     3-1-7-3. virt/libvirt/firewall.py.IptablesFirewallDriver -> prepare_instance_filter()
                                  3-1-7-3-1. self.add_filters_for_instance()
                                                  3-1-7-3-1-1. network/linux_net.py.IpTablesTable -> add_chain()
                                                  3-1-7-3-1-2. self._filters_for_instance()
                                                  3-1-7-3-1-3. self._add_filters()
                                                  3-1-7-3-1-4. self.instance_rules()
                                                  3-1-7-3-1-3. self._add_filters()
                                  3-1-7-3-2. network/linux_net.py.IpTablesTable -> apply()
                                                  3-1-7-3-2-1. self._modify_rules()
                     3-1-7-4. self._create_image()
                                  .......
                     3-1-7-5. self._create_new_domain()
                                  .......
                     3-1-7-6. virt/libvirt/firewall.py.IptablesFirewallDriver -> apply_instance_filter()
                                  pass
                     3-1-7-7. utils.py.LoopingCall(_wait_for_boot)
                                  3-1-7-7-1. self.get_info()
                                                  - libvirt 로 부터 state를 주기적으로 받아와서 power_state.RUNNING 일 때
                                                     멈춤
                     3-1-7-8. utils.py.LoopingCall -> timer.start()
            3-1-8. self._get_power_state()
                     ........
           3-1-9. self._instance_update()
                     3-1-9-1. self.db.instance_update()
                                  - instances 테이블에 power_state, vm_state 와 task_state 를 libvirt를 조회하여
                                    compute/power_state.py.변수, ACTIVE, None 으로 변경
           3-1-10. utils.py -> usage_from_instance()
                      - instance 상태 변수를 넘겨서 usage_info dict 변수 값으로 변경하여 리턴
           3-1-11. notifier/api.py -> notify('compute.%s' % self.host,
                                                       'compute.instance.create',
                                                       notifier.INFO, usage_info)



Posted by Kubernetes Korea co-leader seungkyua@gmail.com

댓글을 달아 주세요

sqlalchemy 를 사용하면서 sql 문을 log 로 남기는 방법

1. create_engine() 의 전달인자 중에서 echo 값을 True 로 설정 

2. nova/db/sqlalchemy/session.py 66 라인에 값을 변경

engine_args = {

    "pool_recycle": FLAGS.sql_idle_timeout,

    "echo": True,

}



3. nova/db/sqlalchemy/models.py 878 라인의 값을 변경

engine = create_engine(FLAGS.sql_connection, echo=True)



4. nova/db/sqlalchemy/api.py 의 43 라인 변경

LOG = logging.getLogger("sqlalchemy.engine")

LOG.setLevel(logging.INFO)




5. nova.conf 값에 추가하여 처리할 수도 있음

# /etc/nova/nova.conf
--sql_echo=True

# nova/db/sqlalchemy/session.py
flags.DEFINE_bool('sql_echo', False, 'show sql log output')

# nova/db/sqlalchemy/session.py
engine_args = {

    "pool_recycle": FLAGS.sql_idle_timeout,

    "echo": FLAGS.sql_echo,

}

# nova/db/sqlalchemy/models.py
engine = create_engine(FLAGS.sql_connection, echo= FLAGS.sql_echo) 




 
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

댓글을 달아 주세요

I. Import 하기

from carrot import connection as carrot_connection
from carrot import messaging

II. Connection 객체 생성

params = dict(hostname=FLAGS.rabbit_host,
                    port=FLAGS.rabbit_port,
                    ssl=FLAGS.rabbit_use_ssl,
                    userid=FLAGS.rabbit_userid,
                    password=FLAGS.rabbit_password,
                    virtual_host=FLAGS.rabbit_virtual_host)

connection = carrot_connection.BrokerConnection(params);

III. Consumer 생성

consumer = messaging.Consumer( connection=self,
                                                  topic=topic,
                                                  proxy=proxy)

IV. Sample (http://nathanborror.com/posts/2009/may/20/working-django-and-rabbitmq/)

########## Set global variables ###################

AMQP_SERVER = 'localhost'
AMQP_PORT = 5672
AMQP_USER = 'guest'
AMQP_PASSWORD = 'guest'
AMQP_VHOST = '/'

########## Create a consumer ###################

>>> from flopsy import Connection, Consumer
>>> consumer = Consumer(connection=Connection())
>>> consumer.declare(queue='books', exchange='readernaut', routing_key='importer', auto_delete=False)

>>> def message_callback(message):
...     print 'Recieved: ' + message.body
...     consumer.channel.basic_ack(message.delivery_tag)
>>>
>>> consumer.register(message_callback)
>>> consumer.wait()


########## Create a publisher ###################

>>> from flopsy import Connection, Publisher
>>> publisher = Publisher(connection=Connection(), exchange='readernaut', routing_key='importer')
>>> publisher.publish('Test message!')
>>> publisher.close()



[ Pool 사용 ]

1. Publisher 가 cast 로 호출할 때 pools.Pool을 사용 (Connection 을 Pool로 연결)

from eventlet import pools

class Pool(pools.Pool):
    def create(self):
        LOG.debug('Pool creating new connection')
        return Connection.instance(new=True)

ConnectionPool = Pool(
        max_size=FLAGS.rpc_conn_pool_size,
        order_as_stack=True)

with ConnectionPool.item() as conn:
        publisher = DirectPublisher(connection=conn, msg_id=msg_id)

2. Consumer 가 메세지를 받을 때 GreenPool을 사용 (메소드를 Pool로 실행)

from eventlet import greenpool

self.pool = greenpool.GreenPool(FLAGS.rpc_thread_pool_size)
self.pool.spawn_n(self._process_data, msg_id, ctxt, method, args)

def _process_data(self, msg_id, ctxt, method, args):
...
 
3. Consumer 를 Thread로 변경하여 실행을 분기시키고자 할 때 eventlet.spawn을 사용
    - 코드를 wait() block 없이 계속 실행
    - 해당 Thread 가 return 값으로 넘어옮

import eventlet

self._rpc_consumer_thread = eventlet.spawn(_consumer_thread)
 
4. Report 와 같이 내부 LoopingCall 을 분기시켜 실행하고자 할 때 eventlet.greenthread 를 사용

from eventlet import greenthread

def _inner():
    ...
    greenthread.sleep(interval)
    ...

greenthread.spawn(_inner)




[ 용어 정리 ]
- queue      : Queue 이름을 의미
- exchange : Queue 와 Bind 하기 위한 exchange 이름을 의미
- exchange_type :
    . direct  : routing_key 가 정확하게 매칭되어야 함
    . topic   : routing_key 를 패턴 매칭으로 사용 가능
    . fanout : routing_key 가 필요 없이 모두 통신
- routing_key : Key 이름에 해당하는 Queue 에만 메세지를 보낼 수 있음




Posted by Kubernetes Korea co-leader seungkyua@gmail.com

댓글을 달아 주세요

  1. BlogIcon SteroIDS 2012.03.08 06:17  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사! ㅎ ㅎ
    즐거운 하루 되세요 ~

I. import 모듈

import eventlet.patcher
eventlet.patcher.monkey_patch()

import eventlet.db_pool
import sqlalchemy.orm
import sqlalchemy.pool

try:
    import MySQLdb
except ImportError:
    MySQLdb = None

II. orm sessionmaker 함수를 통한 session 생성

session = sqlalchemy.orm.sessionmaker(bind=engine,
                                                          autocommit=autocommit,
                                                          expire_on_commit=expire_on_commit)

III. sessionmaker의 첫번째 인수, bind 를 하기 위한 engine 을 생성하는 방법

engine = sqlalchemy.create_engine(FLAGS.sql_connection, **engine_args)

IV. create_engine을 하기 위한 engine_args dict 변수를 만드는 방법

engine_args = {
    "pool_recycle": FLAGS.sql_idle_timeout,
    "echo": False,
}
engine_args["pool_size"] = FLAGS.sql_max_pool_size
engine_args["pool_timeout"] = FLAGS.sql_pool_timeout
engine_args["creator"] = creator.create

V. creator (Connection Pool) 를 구하는 방법

creator = eventlet.db_pool.ConnectionPool(MySQLdb, **pool_args)

VI. ConnectionPool을 구하기 위한 pool_args 변수를 만드는 방법

# sqlalchemy.engine.url.make_url 을 이용하면 url 을 가지고 dict 형태로 변환이 가능하다.
connection_dict = sqlalchemy.engine.url.make_url(FLAGS.sql_connection)

pool_args = {
        "db": connection_dict.database,
        "passwd": password,
        "host": connection_dict.host,
        "user": connection_dict.username,
        "min_size": FLAGS.sql_min_pool_size,
        "max_size": FLAGS.sql_max_pool_size,
        "max_idle": FLAGS.sql_idle_timeout,
}





















 

Posted by Kubernetes Korea co-leader seungkyua@gmail.com

댓글을 달아 주세요

[ context ]
{'request_id': 'd3f06598-456a-41d4-8b64-0f363f1c881d',
  'user_id': 'test_user_id',
  'roles': [],
  'timestamp': '2011-10-21T09:21:40.225901',
  'is_admin': True,
  'auth_token': None,
  'project_id': 'test_project',
  'remote_address': '127.0.0.1',
  'read_deleted': False,
  'strategy': 'noauth'
}


[ body ]
{'server': {'name': 'ahn1',
                'imageRef': '3', 
                'key_name': None, 
                'flavorRef': '2', 
                'max_count': 1, 
                'min_count': 1
               }
}

* 'server' 에 더 추가될 수 있는 내용
'server': {'personality':
              'config_drive':
              'security_groups':
              'networks':
              'blob':
              'key_name':
              'user_data':
              'availability_zone':
              'reservation_id':
             }



[ image_meta ]
{'status': 'active',
 'properties': {'kernel_id': '2', 'ramdisk_id': '1'},
 'name': 'lucid_ami',
 'deleted': False,
 'container_format': 'ami',
 'created_at': '2011-10-17T23:30:45.570475',
 'disk_format': 'ami',
 'updated_at': '2011-10-17T23:30:50.942699',
 'id': 3,
 'min_disk': '0',
 'location': 'file:///var/lib/glance/images/3',
 'checksum': 'a36d714c27b2a0eabd2e32289ec70800',
 'owner': None,
 'is_public': True,
 'deleted_at': None,
 'min_ram': '0',
 'size': 524288000
}
 
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

댓글을 달아 주세요

Rackspace Nova Client 를 사용하여 API 서버에 호출하는 경로

1.  novaclient/shell.main() 이 entry point 임

2.  novaclient/v1_1/shell.do_boot() 를 호출
    - instance 생성시에 "nova boot ....." 처럼 호출하면 "do_" 를 붙힌 메소드가 호출된다.

3. novaclient/v1_1/client.py 를 이용하여 novaclient/v1_1/servers.ServerManager.create() 를 호출
    - novaclient/v1_1/servers.ServerManager 는 novaclient/v1_1/base.BootingManagerWithFind 를
      상속받았으므로 self._boot() 를 호출하면 novaclient/v1_1/base.BootingManagerWithFind._boot() 가 호출됨
    - novaclient/v1_1/base.BootingManagerWithFind._boot() 에서 self._create() 가 호출되면 
      상속받은 novaclient/v1_1/base.ManagerWithFind 에서 찾고 여기에 없으므로 그 위의 클래스인
      novaclient/v1_1/base.Manager._create() 를 호출

4. novaclient/client.post() -> novaclient/client.request() 를 호출하여 HTTP Request 를 던진다.
    - standard out 으로 print 하려면 환경변수에 NOVACLIENT_DEBUG 를 추가하면 된다.


[파일 호출 순서]
novaclient/shell.py -> novaclient/v1_1/shell.py -> novaclient/v1_1/client.py -> novaclient/v1_1/servers.py 
-> novaclient/v1_1/base.py -> novaclient/base.py -> novaclient/client.py



 
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

댓글을 달아 주세요

일반적으로 노바의 로그는 /var/log/nova/nova-xxx.log 형태로 남는다.

/etc/nova/nova.conf 에 보면 logdir=/var/log/nova 로 되어 있어서 해당 디렉토리에 서비스 모듈명의 이름으로 로그가 남는데 이는 프로세스별로 로그를 만드는 것이다.

만약 사용자 정의의 로그를 만들고 싶으면 다음과 같이 수정한다.

# vi /usr/lib/pymodules/python2.6/nova/log.py

def setup():
...
    reset()
    _ask_setup_log()   // 추가
...
askLogger = logging.getLogger('nova.ask')
def _ask_setup_log():

    if FLAGS.logdir:

        logname = '%s.log' % (os.path.join(FLAGS.logdir, 'nova-ask'),)

        global askLogger

        askLogger = logging.getLogger('nova.ask')

        askLogger.propagate = 0

        askHandler = WatchedFileHandler(logname)

        askHandler.setFormatter(_formatter)

        askLogger.addHandler(askHandler)

 
# vi /usr/lib/pymodules/python2.6/nova/scheduler/chance.py

...
from nova import log as logging
...

    logging.askLogger.debug('********* %s, %s *************', context, topic)


이와 같이 수정하면 /var/log/nova/nova-ask.log 가 생성되며 어떤 프로세스에서 호출하던지 해당 로그에 남게 되어 있다.


novaclient 모듈에서 로그를 추가하고 싶으면 다음과 같이 하면 된다.

# vi /usr/lib/pymodules/python2.6/novaclient/log.py

import logging

from logging.handlers import WatchedFileHandler


logger = logging.getLogger('nova.client')

logger.setLevel(logging.DEBUG)

fh = WatchedFileHandler('/var/log/nova/nova-client.log')

formatter = logging.Formatter('%(asctime)s %(levelname)s %(name)s [-] %(message)s from (pid=%(process)d) %(funcName)s %(pathname)s:%(lineno)d')

fh.setFormatter(formatter)

logger.addHandler(fh)


# vi /usr/lib/pymodules/python2.6/novaclient/shell.py

...
from log import logger
...

logger.debug('******* shell.py called !! ****************')







 
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

댓글을 달아 주세요

1. Virtual box 다운로드 및 설치
    http://www.virtualbox.org/wiki/Downloads

2. Vagrant 를 설치 후 이용하여 Virtual box 인스턴스 생성
     $> sudo gem update -- system

    RubyGems version 이 1.3.6 보다 낮아 에러가 난다면
    $> sudo gem install rubygems-update
    $> sudo update_rubygems

    $> sudo gem update -- system
    $> sudo gem install vagrant -- pre

    ※ Vagrant 를 체험하고 싶으면 아래와 같이 해볼 수 있다.
$> cd ~
$> vagrant box add lucid32 http://files.vagrantup.com/lucid32.box        ~/.vagrant/boxes/lucid32 디렉토리가 생김

만약 박스를 없애고 싶으면
$> vagrant box remove lucid32

$> mkdir OpenStack
$> cd OpenStack
$> mkdir vagrant
$> cd vagrant
$> vagrant init lucid32        -> Vagrant 파일이 생성됨
$> vagrant up                      -> ~/VirtualBox VMs 에 가상 서버가 생김

아직 ssh 는 가동되지 않았으므로 ssh 를 가동
$> vagrant ssh

ssh 접속이 실패하면 가상서버를 내렸다 다시 올린다. (버그가 있는 것 같음)

만약 가상서버를 내리 싶으면
$> vagrant destroy
    
3. Chef Recipes 를 받는다.
    $> cd ~
    $> git clone -v https://github.com/openstack/openstack-cookbooks openstack-cookbooks

4. Set Up Some Directories
    $> cd ~
    $> mkdir OpenStack
    $> cd OpenStack
    $> mkdir aptcache
    $> mkdir chef
    $> cd chef

5. chef-solo 기반으로 수행할 Vagrant file 을 받는다.
    chef 는 독립적으로 수행할 수 있는 chef-solo 방법과 chef server 를 설치하고 client 로 접속하여 설치하는 방법이 있다.

    $> curl -o Vagrantfile https://raw.github.com/gist/786945/solo.rb
    $> vi Vagrantfile
#aptdir = (ENV['APTCACHE'] or "#{ENV['HOME']}/aptcache/")
# 아래와 같이 수정
aptdir = (ENV['APTCACHE'] or "#{ENV['HOME']}/OpenStack/aptcache/") 

6. Running OpenStack Compute within a Vagrant Instance
    $> vagrant up

7. Virtual Machine 접속
    $> vagrant ssh
    $> sudo apt-get install euca2ools
    $> euca-add-keypair test > test.pem
    $> chmod 600 test.pem
    $> euca-run-instances -t m1.tiny -k test ami-tty
    $> ssh -i test.pem root@10.0.0.3

8. Virtual Machine 삭제
    $> vagrant destroy
    $> rm *.pem novarc






3. swift 다운로드
    http://www.openstack.org/projects/storage/ 

4. 도큐먼트 설치
    #> sudo easy_install -U sphinx              install Sphinx
    #> python setup.py build_sphinx           builds the document






 
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

댓글을 달아 주세요