Cinderで管理しているVolumeが削除できない(RDO版 python-cinder-2014.1-2.el7.noarch)

ボリュームが消せない...

cinderコマンドやhorizonからボリュームを削除しようとするとerror_deletingのまま削除できない現象に当たったので調べてみた。

エラーメッセージ(/var/log/cinder/volume.log)

cinderのボリュームノードでは以下のログが出力されている。

2014-09-04 13:40:57.017 18535 WARNING cinder.context [-] Arguments dropped when creating context: {'user': u'299a108b970b4407af22
b8da11ad3e6c', 'tenant': u'f537390fb838414082c266d476897231', 'user_identity': u'299a108b970b4407af22b8da11ad3e6c f537390fb838414
082c266d476897231 - - -'}
2014-09-04 13:40:57.084 18535 ERROR oslo.messaging.rpc.dispatcher [req-a7d9b1b8-19b5-4fc2-9ee3-3172c862acde 299a108b970b4407af22b
8da11ad3e6c f537390fb838414082c266d476897231 - - -] Exception during message handling: No target id found for volume 5f3e641b-a7b
2-407f-a239-cf63d1124106.
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher Traceback (most recent call last):
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/oslo/messaging/rpc/dis
patcher.py", line 133, in _dispatch_and_reply
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     incoming.message))
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/oslo/messaging/rpc/dis
patcher.py", line 176, in _dispatch
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     return self._do_dispatch(endpoint, method, ctxt, args)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/oslo/messaging/rpc/dis
patcher.py", line 122, in _do_dispatch
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     result = getattr(endpoint, method)(ctxt, **new_args)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/volume/manager.py", line 144, in lvo_inner1
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     return lvo_inner2(inst, context, volume_id, **kwargs)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/openstack/common/lockutils.py", line 233, in inner
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     retval = f(*args, **kwargs)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/volume/manager.py", line 143, in lvo_inner2
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     return f(*_args, **_kwargs)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/volume/manager.py", line 416, in delete_volume
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     {'status': 'error_deleting'})
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/openstack/common/excutils.py", line 68, in __exit__
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     six.reraise(self.type_, self.value, self.tb)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/volume/manager.py", line 400, in delete_volume
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     self.driver.remove_export(context, volume_ref)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/volume/drivers/lvm.py", line 540, in remove_export
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     self.target_helper.remove_export(context, volume)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/volume/iscsi.py", line 232, in remove_export
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     volume['id'])
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/db/api.py", line 234, in volume_get_iscsi_target_num
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     return IMPL.volume_get_iscsi_target_num(context, volume_id)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/db/sqlalchemy/api.py", line 119, in wrapper
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     return f(*args, **kwargs)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher   File "/usr/lib/python2.7/site-packages/cinder/db/sqlalchemy/api.py", line 1344, in volume_get_iscsi_target_num
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher     raise exception.ISCSITargetNotFoundForVolume(volume_id=volume_id)
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher ISCSITargetNotFoundForVolume: No target id found for volume 5f3e641b-a7b2-407f-a239-cf63d1124106.
2014-09-04 13:40:57.084 18535 TRACE oslo.messaging.rpc.dispatcher
2014-09-04 13:40:57.089 18535 ERROR oslo.messaging._drivers.common [req-a7d9b1b8-19b5-4fc2-9ee3-3172c862acde 299a108b970b4407af22b8da11ad3e6c f537390fb838414082c266d476897231 - - -] Returning exception No target id found for volume 5f3e641b-a7b2-407f-a239-cf63d1124106. to caller
2014-09-04 13:40:57.090 18535 ERROR oslo.messaging._drivers.common [req-a7d9b1b8-19b5-4fc2-9ee3-3172c862acde 299a108b970b4407af22b8da11ad3e6c f537390fb838414082c266d476897231 - - -] ['Traceback (most recent call last):\n', '  File "/usr/lib/python2.7/site-packages/oslo/messaging/rpc/dispatcher.py", line 133, in _dispatch_and_reply\n    incoming.message))\n', '  File "/usr/lib/python2.7/site-packages/oslo/messaging/rpc/dispatcher.py", line 176, in _dispatch\n    return self._do_dispatch(endpoint, method, ctxt, args)\n', '  File "/usr/lib/python2.7/site-packages/oslo/messaging/rpc/dispatcher.py", line 122, in _do_dispatch\n    result = getattr(endpoint, method)(ctxt, **new_args)\n', '  File "/usr/lib/python2.7/site-packages/cinder/volume/manager.py", line 144, in lvo_inner1\n    return lvo_inner2(inst, context, volume_id, **kwargs)\n', '  File "/usr/lib/python2.7/site-packages/cinder/openstack/common/lockutils.py", line 233, in inner\n    retval = f(*args, **kwargs)\n', '  File "/usr/lib/python2.7/site-packages/cinder/volume/manager.py", line 143, in lvo_inner2\n    return f(*_args, **_kwargs)\n', '  File "/usr/lib/python2.7/site-packages/cinder/volume/manager.py", line 416, in delete_volume\n    {\'status\': \'error_deleting\'})\n', '  File "/usr/lib/python2.7/site-packages/cinder/openstack/common/excutils.py", line 68, in __exit__\n    six.reraise(self.type_, self.value, self.tb)\n', '  File "/usr/lib/python2.7/site-packages/cinder/volume/manager.py", line 400, in delete_volume\n    self.driver.remove_export(context, volume_ref)\n', '  File "/usr/lib/python2.7/site-packages/cinder/volume/drivers/lvm.py", line 540, in remove_export\n    self.target_helper.remove_export(context, volume)\n', '  File "/usr/lib/python2.7/site-packages/cinder/volume/iscsi.py", line 232, in remove_export\n    volume[\'id\'])\n', '  File "/usr/lib/python2.7/site-packages/cinder/db/api.py", line 234, in volume_get_iscsi_target_num\n    return IMPL.volume_get_iscsi_target_num(context, volume_id)\n', '  File "/usr/lib/python2.7/site-packages/cinder/db/sqlalchemy/api.py", line 119, in wrapper\n    return f(*args, **kwargs)\n', '  File "/usr/lib/python2.7/site-packages/cinder/db/sqlalchemy/api.py", line 1344, in volume_get_iscsi_target_num\n    raise exception.ISCSITargetNotFoundForVolume(volume_id=volume_id)\n', 'ISCSITargetNotFoundForVolume: No target id found for volume 5f3e641b-a7b2-407f-a239-cf63d1124106.\n']

調べてみる...

どうやらコレを引き当てている様子

1084046 NEW https://bugzilla.redhat.com/show_bug.cgi?id=1084046
  cinder: can't delete a volume (raise exception.ISCSITargetNotFoundForVolume)

launchpadでも報告されている

cinder-2014.1.1では修正されるみたい ということで、

にある通り、パッチを当てて無事削除できるようになりました

--- /usr/lib/python2.7/site-packages/cinder/volume/iscsi.py.org  2014-04-22 05:09:40.000000000 +0900
+++ /usr/lib/python2.7/site-packages/cinder/volume/iscsi.py 2014-09-04 15:29:37.916931574 +0900
@@ -19,6 +19,7 @@
 from oslo.config import cfg

 from cinder.brick import exception
+from cinder import exception
 from cinder.brick.iscsi import iscsi
 from cinder.openstack.common.gettextutils import _
 from cinder.openstack.common import log as logging

超訳: Heat Orchestration Template (HOT) Guide

Heatがさっぱりわからなかったので、ひとまずテンプレートガイドを読んでみたついでに和訳してみました(オリジナルはこちら)。

Heat Orchestration Template (HOT) Guide

  • 原文
    HOT is a new template format meant to replace the Heat CloudFormation-compatible format (CFN) as the native format supported by the Heat over time. This guide is targeted towards template authors and explains how to write HOT templates based on examples. A detailed specification of HOT can be found at Heat Orchestration Template (HOT) Specification.

  • 和訳
    HOTはHeatが利用するネイティブフォーマットをHeat CloudFormation互換フォーマット(CFN)から置き換えることを意図した新たなテンプレートフォーマットです。
    このガイドはテンプレート作成者を対象として、用例を交えつつHOTテンプレートの作成方法を説明します。

Status

  • 原文
    HOT support is still under development and needs more work to provide access to all functionality currently available via the CFN compatible template interface. This guide will be updated periodically whenever new features get implemented for HOT.

  • 和訳
    HOTサポートは現在も開発中で、全ての機能に対してCFN互換フォーマットのテンプレートインターフェイス経由でアクセスするために多くの作業を必要としています。
    このガイドはHOTに新機能が実装される毎に更新されます。

Writing a hello world HOT template

  • 原文
    This section gives an introduction on how to write HOT templates, starting from very basic steps and then going into more and more detail by means of examples.

  • 和訳
    このセクションでは、HOTテンプレートの記述方法の基本的から始めて、続いてより詳細な部分について用例を用いて紹介していきます。

A most basic template

  • 原文
    The most basic template you can think of may contain only a single resource definition using only predefined properties (along with the mandatory Heat template version tag). For example, the template below could be used to simply deploy a single compute instance.

  • 和訳
    あなたが考えることのできる、最も基本的なテンプレートは、前定義されたプロパティを利用した単一のリソース定義でしょう(Heatテンプレートの必須タグであるversionも加える必要があります)。

heat_template_version: 2013-05-23

description: Simple template to deploy a single compute instance

resources:
  my_instance:
    type: OS::Nova::Server
    properties:
      key_name: my_key
      image: F18-x86_64-cfntools
      flavor: m1.small
  • 原文
    Each HOT template has to include the heat_template_version key with value ‘2013-05-23’ (the current version of HOT). While the description is optional, it is good practice to include some useful text that describes what users can do with the template. In case you want to provide a longer description that does not fit on a single line, you can provide multi-line text in YAML, for example:

  • 和訳
    それぞれのHOTテンプレートには、heat_template_versionキーと、その値として現在のHOTのバージョン番号である'2013-05-23'を含める必要があります。
    descriptionキーはオプションですが、利用者がそのテンプレートを利用して何ができるのか、など幾つかの有用な情報を記載することを推奨します。単一の行に収まらない長い説明を提供したい場合は、YAML形式で複数行のテキストを記載することが可能です。
    ※'>'は改行を半角スペースに置き換える、ただし最終行の改行は保存される

description: >
  This is how you can provide a longer description
  of your template that goes over several lines.
  • 原文
    The resources section is required and must contain at least one resource definition. In the example above, a compute instance is defined with fixed values for the ‘key_name’, ‘image’ and ‘flavor’ parameters.

    Note that all those elements, i.e. a key-pair with the given name, the image and the flavor have to exist in the OpenStack environment where the template is used. Typically a template is made more easily reusable, though, by defining a set of input parameters instead of hard-coding such values.

  • 和訳
    resourcesセクションは必須で、少なくとも1つのリソース定義が含まれている必要があります。上記の例では、nova-computeの仮想マシンインスタンスの固定値としてkey_name , image , flavor の値が定義されています。
    ※テンプレートで利用するキーペアの名称(key_name)、imageで指定するイメージID、flavorで指定するフレーバ名が全てOpenStack環境上に登録済みである必要があります。典型的なテンプレートは、このような値をハードコードする代わりに入力パラーメタとすることで再利用しやすいよう構成されています。

Template input parameters

  • 原文
    Input parameters defined in the parameters section of a HOT template (see also Parameters Section) allow users to customize a template during deployment. For example, this allows for providing custom key-pair names or image IDs to be used for a deployment. From a template author’s perspective, this helps to make a template more easily reusable by avoiding hardcoded assumptions.

    Sticking to the example used above, it makes sense to allow users to provide their custom key-pairs, provide their own image, and to select a flavor for the compute instance. This can be achieved by extending the initial template as follows:

  • 和訳
    利用者は、HOTテンプレートのparametersセクションで定義(参照: Parameters Section)された入力パラメータの値を、テンプレート適用時にカスタマイズすることができます。
    例えば、展開時にキーペア名(key_name)やイメージID(image)をカスタマイズして指定することを可能となり、テンプレート作成者視点ではキーの値を想定してハードコードすることを回避することで、より再利用しやすいテンプレートを作るために役立ちます。

    上記の例のように、利用者が自身のキーペアやイメージ、仮想マシンインスタンスのフレーバを選択して展開できるようにすることは合理的といえます。 以下のように初期テンプレートを拡張することにより設定することができます。

heat_template_version: 2013-05-23

description: Simple template to deploy a single compute instance

parameters:
  key_name:
    type: string
    label: Key Name
    description: Name of key-pair to be used for compute instance
  image_id:
    type: string
    label: Image ID
    description: Image to be used for compute instance
  instance_type:
    type: string
    label: Instance Type
    description: Type of instance (flavor) to be used

resources:
  my_instance:
    type: OS::Nova::Server
    properties:
      key_name: { get_param: key_name }
      image: { get_param: image_id }
      flavor: { get_param: instance_type }
  • 原文
    In the example above, three input parameters have been defined that have to be provided by the user upon deployment. The fixed values for the respective resource properties have been replaced by references to the corresponding input parameters by means of the get_param function (see also Intrinsic Functions).

    You can also define default values for input parameters which will be used in case the user does not provide the respective parameter during deployment. For example, the following definition for the instance_type parameter would select the ‘m1.small’ flavor unless specified otherwise be the user.

  • 和訳
    上記の例には、3つの入力パラメータが展開時に利用者から指定されなければならないことが定義されています。それぞれのリソースプロパティの値は、get_param関数(参照: Intrinsic Functions) を利用してキー(key_name , image , flavor)に対応する入力パラメータへの参照に置き換えられています。

    利用者が展開時に入力パラメータを指定しなかった場合に使用されるデフォルト値も定義することができます。
    以下の例ではflavorキーの値が参照する入力パラメータ(instance_type)を利用者が指定しなかった場合は'm1.small'がフレーバとして選択されることになります。

parameters:
  instance_type:
    type: string
    label: Instance Type
    description: Type of instance (flavor) to be used
    default: m1.small
  • 原文
    Another option that can be specified for a parameter is to hide its value when users request information about a stack deployed from a template. This is achieved by the hidden attribute and useful, for example when requesting passwords as user input:

  • 和訳
    また、パラメータのオプションで、利用者がテンプレートに関する情報を要求した場合に、その値を非表示にできます。これは利用者にユーザ情報入力を要求するような場合にパスワード情報を隠し属性として隠蔽することを可能にします。

parameters:
  database_password:
    type: string
    label: Database Password
    description: Password to be used for database
    hidden: true
Restricting user input
  • 原文
    In some cases you might want to restrict the values of input parameters that users can supply. For example, you might know that the software running in a compute instance needs a certain amount of resources so you might want to restrict the instance_type parameter introduced above. Parameters in HOT templates can be restricted by adding a constraints section (see also Parameter Constraints). For example, the following would allow only three values to be provided as input for the instance_type parameter:

  • 和訳
    場合によっては、入力パラメータとして利用者が指定する値を制限したい場合があるかもしれません。例えば、nova-compute上の仮想マシンインスタンスで実行されるソフトウェアが利用するリソースの量を予め把握しており、上記のinstance_typeパラメータの値に制約を儲けたい場合などです。
    HOTテンプレート内の各パラメータはconstraintsセクション(参照: Parameter Constraints)で制限することができます。例えば以下の例では、instance_typeの入力パラメータとして3つの値(m1.medium , m1.large , m1.xlarge)のみを許可します。

parameters:
  instance_type:
    type: string
    label: Instance Type
    description: Type of instance (flavor) to be used
    constraints:
      - allow_values: [ m1.medium, m1.large, m1.xlarge ]
        description: Value must be one of m1.medium, m1.large or m1.xlarge.
  • 原文
    The constraints section allows for defining a list of constraints that must all be fulfilled by user input. For example, the following list of constraints could be used to clearly specify format requirements on a password to be provided by users:

  • 和訳
    constraintsセクションには、利用者がパラメータ入力時に満たさなければならない全ての制約のリストを定義することができます。例えば、次の制約のリストにより利用者が入力するパスワード要件を明示的に指定することができます。

parameters:
  database_password:
    type: string
    label: Database Password
    description: Password to be used for database
    hidden: true
    constraints:
      - length: { min: 6, max: 8 }
        description: Password length must be between 6 and 8 characters.
      - allowed_pattern: "[a-zA-Z0-9]+"
        description: Password must consist of characters and numbers only.
      - allowed_pattern: "[A-Z]+[a-zA-Z0-9]*"
        description: Password must start with an uppercase character.
  • 原文
    Note that you can define multiple constraints of the same type. Especially in the case of allowed patterns this not only allows for keeping regular expressions simple and maintainable, but also for keeping error messages to be presented to users precise.

  • 和訳
    同じタイプの制約を複数定義することが可能であることに注意してください。特に、上記のようなケースでは正規表現をシンプルに記述できることによるメンテナンス性の向上だけでなく、利用者に的確なエラーメッセージを提示することも可能にしています。

Providing template outputs

  • 原文
    In addition to template customization through input parameters, you will typically want to provide outputs to users, which can be done in the outputs section of a template (see also Outputs Section). For example, the IP address by which the instance defined in the example above can be accessed should be provided to users. Otherwise, users would have to look it up themselves. The definition for providing the IP address of the compute instance as an output is shown in the following snippet:

  • 和訳
    入力パラメータによるテンプレートのカスタマイズに加えて、通常はテンプレートのoutputsセクション(参照: Outputs Section)でカスタマイズされた出力を利用者に提供することになるでしょう。
    例えば、ここまでの例で作成した仮想マシンインスタンスにアクセスするためのIPアドレス情報は出力情報として利用者に提供されるべきでしょう。そうでなければ、利用者自身がアクセスするための情報を探さなければなりません。以下は、仮想マシンインスタンスIPアドレス情報を出力するためのテンプレート定義部分です。

outputs:
  instance_ip:
    description: The IP address of the deployed instance
    value: { get_attr: [my_instance, first_address] }
  • 原文
    Output values are typically resolved using intrinsic function such as the get_attr function in the example above (see also Intrinsic Functions).

  • 和訳
    出力される値は、通常、上記の例にある通りget_attr関数のような組み込み関数(参照: Outputs Section)を利用して出力されます。

用語

  • CFN: Heat CloudFormation-compatible format
  • HOT: Heat Orchestration Template

OpenStack Dashboard(Horizon)で操作可能な機能を図にしてみた

Horizonで操作できる機能

単純にHorizonの機能を図にしてみたらこうなった(Icehouse版)。 ユーザビリティ確保のために重複している機能はあるけれど、全体的な機能提供ポリシーのようなものは、この図からも伺えます。あるレベルまでは、それぞれのカテゴリで一貫した粒度でユーザインターフェイスを提供しているのがわかります。 以下の画像をクリックするとflickrに置いてあるオリジナルのpngファイルに飛びます。ダウンロードはご自由にどうぞ。 OpenStack_Operation_on_Horizon

pudbを利用したPythonスクリプトのデバッグ

pudbについて

Pythonのデバッガといえば、謹製のpdbが第一候補にあげられます。

pdbの機能 本家サイト(http://docs.python.jp/2/library/pdb.html) から引用 〜
「 (条件付き)ブレークポイントの設定やソース行レベルでのシングルステップ実行、スタックフレームのインスペクション、ソースコードスティングおよびいかなるスタックフレームのコンテキストにおける任意のPythonコードの評価をサポートしています。」

pudbpdbCUI版と言っても良いくらいの機能を備えている上に、CUIによる使いやすいユーザインターフェイスを備えているのが特徴で、コードリーディングやデバッグに活用できる非常に有効なツールです。

pudbのインストール

pipを利用してpudbをインストールします。

$ pip install pudb
Downloading/unpacking pudb
  Downloading pudb-2014.1.tar.gz (46kB): 46kB downloaded
  Running setup.py egg_info for package pudb

Downloading/unpacking urwid>=1.1.1 (from pudb)
  Downloading urwid-1.2.1.tar.gz (578kB): 578kB downloaded
  Running setup.py egg_info for package urwid

    warning: no files found matching 'CHANGELOG'
Downloading/unpacking pygments>=1.0 (from pudb)
  Downloading Pygments-1.6.tar.gz (1.4MB): 1.4MB downloaded
  Running setup.py egg_info for package pygments

[...]

Successfully installed pudb urwid pygments
Cleaning up...

pudbを利用する

ここでは以下のサンプルプログラムを例にpudbの操作例を紹介します。

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import sys


class Foo(object):
    def __init__(self):
        pass

    def hello(self, name='stranger'):
        print 'Hello, %s!' % name


def usage():
    sys.stderr.write('Usage: hello.py <your name>\n')


def main():
    foo = Foo()
    try:
        foo.hello(sys.argv[1])
    except IndexError:
        usage()
        sys.exit(1)


if __name__ == '__main__':
    main()

##
## [EOF]
##

pudbコマンドラインオプション

pudbのコマンドラインオプションは以下の通りです。

$ pudb --help
Usage: pudb [options] SCRIPT-TO-RUN [SCRIPT-ARGUMENTS]

Options:
  -h, --help          show this help message and exit
  -s, --steal-output
  --pre-run=COMMAND   Run command before each program run

現在(2014/06/24)の時点で -sオプションはNotImplemented となっています。

$ pudb -s hello.py
Traceback (most recent call last):
  File "/Users/saitou/venv/test/bin/pudb", line 9, in <module>
    load_entry_point('pudb==2014.1', 'console_scripts', 'pudb')()
  File "/Users/saitou/venv/test/lib/python2.7/site-packages/pudb/run.py", line 30, in main
    steal_output=options.steal_output)
  File "/Users/saitou/venv/test/lib/python2.7/site-packages/pudb/__init__.py", line 48, in runscript
    dbg = _get_debugger(steal_output=steal_output)
  File "/Users/saitou/venv/test/lib/python2.7/site-packages/pudb/__init__.py", line 35, in _get_debugger
    dbg = Debugger(**kwargs)
  File "/Users/saitou/venv/test/lib/python2.7/site-packages/pudb/debugger.py", line 155, in __init__
    raise NotImplementedError("output stealing")
NotImplementedError: output stealing

pudbを起動する直前に実行するコマンドがあれば --pre-run に指定します。
例えば、lsコマンドを実行したければ --pre-run=/bin/ls のような書式で指定します。

pudbを起動する

pudbは2通りの方法で利用できます。

a) pudbコマンドで起動する

引数にfooを与えてhello.pyを起動します。

$ pudb hello.py foo

b) -m pudbpythonのオプションとして指定する

$ python -m pudb hello.py foo

初期設定(Ctrl+p)を行う

最初にpudbを起動すると設定画面からスタートします。[Ctrl+p]で随時設定画面を呼び出せます。設定項目は以下の通りです。 f:id:pyde:20140624144714p:plain

主な設定項目

  • Line Numbers:
  • [x]にした場合は、コードの行番号表示を行う
  • Prompt on quit:
  • [x]にした場合は、デバッグ対象スクリプトの実行完了後にpudbに処理を戻す
  • Shell:
  • [!]キーで切り替えるPythonシェルを選択する。カレントシェルに切り替わるclassicがオススメ。
  • Theme:
  • CUIのテーマ(見た目)を選択する
  • Changing this setting requires a restart of PuDB.
  • [x] rawを選択しておくと設定変更が即時反映する(ようにみえる)

ヘルプの表示(?)を行う

[?]キーでpudbのヘルプ機能を利用できる。

ヘルプ画面に表示されるpudbのキー操作は以下のとおり

Keys:
   Ctrl-p - edit preferences

   n - step over ("next")
   s - step into
   c - continue
   r/f - finish current function
   t - run to cursor
   e - show traceback [post-mortem or in exception state]

   H - move to current line (bottom of stack)
   u - move up one stack frame
   d - move down one stack frame

   o - show console/output screen

   b - toggle breakpoint
   m - open module

   j/k - up/down
   Ctrl-u/d - page up/down
   h/l - scroll left/right

   g/G - start/end
   L - show (file/line) location / go to line
   / - search
   ,/. - search next/previous

   V - focus variables
   S - focus stack
   B - focus breakpoint list
   C - focus code

   f1/?/H - show this help screen
   q - quit

   Ctrl-c - when in continue mode, break back to PuDB

   Ctrl-l - redraw screen

Command line-related:
   ! - invoke configured python command line in current environment
   Ctrl-x - toggle inline command line focus

   +/- - grow/shrink inline command line (active in command line history)
   _/= - minimize/maximize inline command line (active in command line history)

   Ctrl-v - insert newline
   Ctrl-n/p - browse command line history
   Tab - yes, there is (simple) tab completion

Sidebar-related (active in sidebar):
   +/- - grow/shrink sidebar
   _/= - minimize/maximize sidebar
   [/] - grow/shrink relative size of active sidebar box

Keys in variables list:
   \ - expand/collapse
   t/r/s/c - show type/repr/str/custom for this variable
   h - toggle highlighting
   @ - toggle repetition at top
   * - toggle private members
   w - toggle line wrapping
   n/insert - add new watch expression
   enter - edit options (also to delete)

Keys in stack list:
   enter - jump to frame

Keys in breakpoints view:
   enter - edit breakpoint
   d - delete breakpoint
   e - enable/disable breakpoint

pudbを操作する

pdbと同様に以下のように操作を行う。 変数の値はVariables:ペインに、ステップ実行中のスタック情報はStack:ペインに、設定したブレイクポイントの場所はBreakpoints:ペインにそれぞれ表示されます。

-nキーでステップオーバー -sキーでステップイン -bキーでブレイクポイントの設定 -VキーでVariables:ペインに移動 -SキーでStack:ペインに移動 -BキーでBreakpoints:ペインに移動 -Cキーでメインとなるコードペインに移動 -qでpudbを終了する

pudb操作画面

f:id:pyde:20140624144839p:plain

コマンドラインpythonコードを実行する

ステップ実行中にCommand line:ペインのPythonシェルから任意のPythonコードを実行可能です。 実行後に[clear]->[Ctrl+x]でコードペインに戻れます。

  • 例 print文で変数の値を表示 f:id:pyde:20140624144922p:plain

  • 例 Fooクラスのhello()メソッドを呼び出す f:id:pyde:20140624144952p:plain

pudbを終了する

設定でPrompt on quitがチェック[x]されている場合は、終了時にメニューが表示されて、再度実行(Restart)を選択することが可能です。 f:id:pyde:20140624144714p:plain

まとめ

pudbはpdbとほぼ同等の機能を有しています。Command line:ペインの操作の安定性に若干問題がありますが、それを補って余りあるユーザビリティを誇っています。これまでpdbを利用してきた方は一度試してみてください。非常に使いやすくデバッグ作業の効率化に貢献してくれる素敵なツールです。

Neutron Network Nodeの外側NICではgroをoffにする

仮想マシンインスタンスと外部の通信(ftp受信)でスループットが低い

通信経路

instance-A ---> hypervisor ---> network node ---> router -(internet)-> ftp.iij.ad.jp

スループットがやたらと低い

テストで仮想マシンインスタンス(instance-A)からftp.iij.ad.jpからCentOSのLiveCDイメージをダウンロードしてみると、以下の通り平均400kB/s程度しかスループットが出ない

CentOS-6.5-x86_64-LiveCD.iso:     ETA:  21:34  116.51/649.00 MB  421.35 kB/s

network nodeから直接同じ操作を実行してみると...6MB/s以上出ている

CentOS-6.5-x86_64-LiveCD.iso:     ETA:   0:50  327.91/649.00 MB    6.41 MB/s

原因

仮想マシンインスタンスNICのmodel typeやリンクの状態、仮想インスタンス同士の通信などは全く問題なさそう。 最終的にnetwork nodeのineternet接続側NICのオフロードエンジンが悪さをしているのではないかと予想してオフロードを無効化する設定を投入してみることにした。

instance-A ---> hypervisor ---> network node ---> router -(internet)-> ftp.iij.ad.jp
                                            ^
                                            |
                           network nodeのinternet接続側のNICが問題

NICのデフォルト状態

起動直後のNICのオフロードエンジン利用状況はethtool -k で確認できる。

$ ethtool -k eth0
Features for eth0:
rx-checksumming: on
tx-checksumming: on
    tx-checksum-ipv4: on
    tx-checksum-ip-generic: off [fixed]
    tx-checksum-ipv6: on
    tx-checksum-fcoe-crc: off [fixed]
    tx-checksum-sctp: off [fixed]
scatter-gather: on
    tx-scatter-gather: on
    tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: on
    tx-tcp-segmentation: on
    tx-tcp-ecn-segmentation: off [fixed]
    tx-tcp6-segmentation: on
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off [fixed]
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off [fixed]
receive-hashing: on
highdma: on [fixed]
rx-vlan-filter: on [fixed]
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: off [fixed]
tx-gre-segmentation: off [fixed]
tx-udp_tnl-segmentation: off [fixed]
tx-mpls-segmentation: off [fixed]
fcoe-mtu: off [fixed]
tx-nocache-copy: on
loopback: off [fixed]
rx-fcs: off [fixed]
rx-all: off
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]

manによるとethtoolで設定可能なフィーチャーは以下の通り。

       rx on|off
              Specifies whether RX checksumming should be enabled.

       tx on|off
              Specifies whether TX checksumming should be enabled.

       sg on|off
              Specifies whether scatter-gather should be enabled.

       tso on|off
              Specifies whether TCP segmentation offload should be enabled.

       ufo on|off
              Specifies whether UDP fragmentation offload should be enabled

       gso on|off
              Specifies whether generic segmentation offload should be enabled

       gro on|off
              Specifies whether generic receive offload should be enabled

       lro on|off
              Specifies whether large receive offload should be enabled

       rxvlan on|off
              Specifies whether RX VLAN acceleration should be enabled

       txvlan on|off
              Specifies whether TX VLAN acceleration should be enabled

       ntuple on|off
              Specifies  whether  Rx  ntuple filters and actions should be en‐
              abled

       rxhash on|off
              Specifies whether receive hashing offload should be enabled

対策

通信はftpでのファイル受信であるため、様々なフィーチャーの中でもgroをoffにしてみた。

$ sudo ethtool -K eth1 gro off

その後、実際にダウンロードしてみると、network node上から直接ダウンロードした場合と同程度のスループットが出た。

ncftp ...centos/6.5/isos/x86_64 > get CentOS-6.5-x86_64-LiveCD.iso   
CentOS-6.5-x86_64-LiveCD.iso:     ETA:   1:39   31.27/649.00 MB    6.25 MB/s 

コレで解決。NICのオフロードエンジンってちっとも良い印象ないな。

ubuntu12.04にpipでlxmlをインストールする

わすれないようにメモ。

普通にpipでインストールを試みると...

xmlversion.hが無いと叱られる... ちなみにdevelというvirtualenv環境で実施しています。

(devel)$ pip install lxml

<中略>
error: libxml/xmlversion.h: No such file or directory

compilation terminated.

error: command 'gcc' failed with exit status 1

2つのパッケージを追加する

aptでlibxml2-devlibxslt1-devを追加してやる

(devel)$ sudo apt-get install -y libxml2-dev libxslt1-dev

準備が整ったところでpipを利用してインストール

無事に成功。

(devel)$ pip install lxml

<中略>
Successfully installed lxml
Cleaning up...

RDO & packstac でIcehouse2を試す

社内セミナー用にHavanaのときに書いたQuickStartのスライドをIcehouseベータ版にあわせて更新してみた。

一応ちゃんと動いてる。Ceilometerが使うmongodbのあたりがうまく動作しないので、ひとまず除外してありますが、他の機能はこれで試せます。

正式版がリリースされたら、この資料も更新していくつもり。 WIDE春合宿で元木さんと一緒に講演した資料も盛り込んでみた。さんくす元木さん&中島さん。