2011/12/20 10:14

Nova 소스 위치

소스 원본 : /usr/share/pyshared/nova
링       크 : /usr/lib/python2.7/dist-packages/nova



저작자 표시 변경 금지
Trackback 0 Comment 0
2011/11/04 18:00

Nova Boot 순서


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)



저작자 표시 변경 금지
Trackback 0 Comment 1
  1. BlogIcon Jordan 11 2011/11/30 16:11 address edit & del reply

    와이어에 단어가 마이클 조던 / 에어 조던 신발 부여 향해 경의, 그들은 특별한 인식 마이크와 자신에게 감사를 지불하기 위해 에어 조던 신발 23 버전을 생산한다고합니다.

2011/11/02 17:26

python sqlalchemy 사용시 SQL Log 남기기

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) 




 
저작자 표시 변경 금지
Trackback 0 Comment 1
  1. BlogIcon the north face outlet 2011/12/10 17:52 address edit & del reply

    실행 중인 스크립트를 중단한다.

2011/10/22 16:42

Python에서 RabbitMQ Connection 및 Consumer 등록

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 에만 메세지를 보낼 수 있음




저작자 표시 변경 금지
Trackback 0 Comment 3
  1. BlogIcon Air Jordan 13 2011/11/21 11:51 address edit & del reply

    나이키는 비트와 분위기를 수행할 수있는 압력하지만 나이키와 마이클은 결국 resounding 패션의 모든 비평가 답변을 것입니다 전에 에어 조단 XI의 출시를 주저되었을 수도 있습니다 기분이되어 있어야합니다

  2. BlogIcon UGG Boots Sale 2011/11/21 11:51 address edit & del reply

    나이키는 비트와 분위기를 수행할 수있는 압력하지만 나이키와 마이클은 결국 resounding 패션의 모든 비평가 답변을 것입니다 전에 에어 조단 XI의 출시를 주저되었을 수도 있습니다 기분이되어 있어야합니다

  3. BlogIcon UGGs On Sale 2011/11/21 11:51 address edit & del reply

    당신은 캐주얼과 파티 착용을 위해 부츠의 시원한 한쪽을 찾고있다면, 사용자의 요구에 높이 세련된 UGG의 고전을 확인하십시오.우수한 품질의 Ugg 부츠 입고 일년 내내 완벽한하고 거친 사용을 견딜 수 있습니다.

2011/10/22 14:04

Python에서 MySQL Connection Pool을 활용할 수 있는 DB Session 구하기

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,
}





















 

저작자 표시 변경 금지
Trackback 0 Comment 1
  1. BlogIcon cheap true religion jeans 2011/12/10 17:49 address edit & del reply

    솔입니다

2011/10/21 18:36

Nova API context, body 값

[ 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
}
 
저작자 표시 변경 금지
Trackback 0 Comment 1
  1. BlogIcon cheap true religion jeans 2011/12/10 17:49 address edit & del reply

    솔입니다

2011/10/17 08:31

Nova Client 이해하기

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



 
저작자 표시 변경 금지
Trackback 0 Comment 2
  1. BlogIcon Christian Louboutin Shoes 2011/12/08 15:20 address edit & del reply

    신발의 언급에서, 나는 많은 사람들이 최고 명품 신발 브랜드, 기독교 Lou​​boutin 신발 생각할 수 있다고 생각합니다. 이러한 신발의 가장 독특한 특징은 붉은 옻칠 솔입니다.

  2. BlogIcon cheap true religion jeans 2011/12/10 17:49 address edit & del reply

    솔입니다

2011/08/31 14:13

CLI 에서 argv 에 덧붙혀서 args 를 동적으로 추가하고 싶을 때

python 에서 argv 를 이용하여 args 를 동적으로 추가하고자 한다면 다음과 같이 사용

1. sys.argv[1:] 를 이용
   -  main 의 프로그램명을 제외한 cli 에서 입력한 argv 가 입력됨

2.  argparse.ArgumentParser.add_argument 를 이용하여 환경설정 값을 args 로 추가
저작자 표시 변경 금지
Trackback 0 Comment 0
2011/08/30 13:06

Nova 모듈에서 나만의 log file 추가하기

일반적으로 노바의 로그는 /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 !! ****************')







 
저작자 표시 변경 금지
Trackback 0 Comment 1
  1. BlogIcon cheap true religion jeans 2011/12/10 17:51 address edit & del reply

    솔입니다

2011/06/22 18:07

Eclipse PHP Software Updates

Eclipse 에서 PHP SDK 를 설치하기위해서는 아래 플러그인 사이트에서 업데이트를 한다.

1. Software Update Site
    - PDT 를 update 하기 위해서 helios 사이트에서 Programming Languages -> PDT SDK Feature 를 설치한다.
        . http://download.eclipse.org/releases/helios/

    - 그런데 현재는 버그가 있군요.. 그래서 아래 사이트에서 설치해야 함..
        . name : PDT Update Site
        . URL : http://download.eclipse.org/tools/pdt/updates/2.2/milestones/

    - 3.0 은 설치가 안되던데.. 나중에 다시 테스트 
        . URL : http://ftp.daum.net/eclipse/tools/pdt/updates/3.0/milestones/
저작자 표시 변경 금지
Trackback 0 Comment 1
  1. BlogIcon Ugg Boots Sale 2011/11/25 12:09 address edit & del reply

    그것은 길이 아니지만 행동이 그 문제의 우수성 : 인생은 연극처럼.