2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Oracle Cloud] 便利ツールoci-utilsの使い方メモ

Posted at

はじめに

プラットフォーム・イメージを使用して、Computeを作成した場合、oci-utilsという便利ツールがプリ・インストールされています。

先日、oci-utilsのマニュアルをみていたら、存在を知らなかったツールもたくさんありました。知ってると便利な場面があるかもしれない!と思ったので、個人的な備忘録です。

前提

  • OEL6のプラットフォーム・イメージには、2021年6月現在oci-utilsは含まれていないようです。
# cat /etc/oracle-release 
Oracle Linux Server release 6.10
# rpm -q oci-utils
package oci-utils is not installed
  • OEL7とOEL8のプラットフォーム・イメージには含まれています。ここでは、以下のバージョンのoci-utilsを前提に記載します
# cat /etc/oracle-release 
Oracle Linux Server release 7.9
# rpm -q oci-utils
oci-utils-0.12.3-2.el7.noarch
# cat /etc/oracle-release 
Oracle Linux Server release 8.4
# rpm -q oci-utils
oci-utils-0.12.3-2.el8.noarch

oci-utilsに含まれるコマンド

以下は、マニュアルに記載されている、oci-utilsに含まれるコマンド群です

  • ocid
  • /usr/libexec/oci-growfs
  • /usr/bin/oci-iscsi-config
  • /usr/bin/oci-metadata
  • /usr/bin/oci-network-config
  • /usr/bin/oci-network-inspector
  • /usr/bin/oci-notify
  • /usr/bin/oci-public-ip

ocid

ocidデーモンは、Computeに複数のVNICをアタッチしたときに追加したVNIC (セカンダリVNIC) のIPを自動で構成してくれるサービスです。

oci-utilsのサービス・コンポーネント。systemdで開始されたデーモンとして実行されます。このサービスは、iSCSIおよびVNICデバイス構成で変更をスキャンし、インスタンスのOCIメタデータとパブリックIPアドレスをキャッシュします。

デフォルトでは無効になっています。

# systemctl list-unit-files ocid.service
UNIT FILE    STATE   
ocid.service disabled

( 以前は、同じようにセカンダリVNICを設定するスクリプト/usr/libexec/secondary_vnic_all_configure.sh がプリ・インストールされていた気がするんですが、最近のプラットフォーム・イメージには含まれていないようです。 )

セカンダリVNICを作成した後にOS上でネットワーク・インタフェースを確認すると、以下のようにデバイス(ens5)としては認識していますが、

# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 02:00:17:02:e1:ff brd ff:ff:ff:ff:ff:ff
★3: ens5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 02:00:17:00:7f:3c brd ff:ff:ff:ff:ff:ff
★が追加したVNIC

IPアドレスは自動設定してくれません

# ip -f inet -o addr
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
2: ens3    inet 10.0.0.104/26 brd 10.0.0.127 scope global dynamic ens3\       valid_lft 82323sec preferred_lft 82323sec
★ ens5にIPは割り当てれられていない

そこで、ocidサービスを起動させると、セカンダリVNICのIPを自動設定してくれます。

# systemctl start ocid
# systemctl status ocid
● ocid.service - Oracle Cloud Infrastructure utilities daemon
   Loaded: loaded (/etc/systemd/system/ocid.service; disabled; vendor preset: enabled)
   Active: active (running) since Fri 2021-06-25 11:52:47 GMT; 13s ago
 Main PID: 29788 (python3)
   Memory: 132.4M
   CGroup: /system.slice/ocid.service
           └─29788 /usr/bin/python3 /usr/lib/python3.6/site-packages/oci_utils/impl/ocid-main.py --no-daemon

Jun 25 11:52:42 oel7-test sudo[29964]:     root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/sbin/ip link set dev ens5 mtu 9000 up
Jun 25 11:52:42 oel7-test sudo[29968]:     root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/bin/mkdir --parents /etc/NetworkManager/conf.d/
Jun 25 11:52:42 oel7-test sudo[29972]:     root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/bin/touch /etc/NetworkManager/con..._3C.conf
Jun 25 11:52:42 oel7-test sudo[29976]:     root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/bin/sh -c /usr/bin/cat > /etc/Network..._3C.conf
Jun 25 11:52:42 oel7-test sudo[29981]:     root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/bin/cp --archive /etc/iproute2/rt_tab...bles.bck
Jun 25 11:52:42 oel7-test sudo[29985]:     root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/bin/sh -c /usr/bin/cat > /etc/iproute2/rt_tables
Jun 25 11:52:42 oel7-test sudo[29990]:     root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/bin/rm -f /etc/iproute2/rt_tables.bck
Jun 25 11:52:42 oel7-test sudo[29994]:     root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/sbin/ip route add default via 10....ble ort3
Jun 25 11:52:42 oel7-test sudo[29998]:     root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/sbin/ip rule add from 10.0.0.190 lookup ort3
Jun 25 11:52:47 oel7-test systemd[1]: Started Oracle Cloud Infrastructure utilities daemon.
Hint: Some lines were ellipsized, use -l to show in full.
↑system statusコマンドのログ部分を見ると、IPを割り当てているのがわかる

# ip -f inet -o addr
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
2: ens3    inet 10.0.0.104/26 brd 10.0.0.127 scope global dynamic ens3\       valid_lft 82151sec preferred_lft 82151sec
★3: ens5    inet 10.0.0.190/26 scope global ens5\       valid_lft forever preferred_lft forever

★ens5にIPが割り振られた

ちなみにですがOCIDを使ってIPを構成した場合、以下のようにポリシー・ベースのルーティング・ルールを自動設定してくれます。このルーティング・ルールにより、セカンダリVNICあての通信を、(セカンダリVNICに割り当てた)サブネットのGWにルーティングしてくれるようになる(※)ため、スタティック・ルートを設定する手間が省けます。

※ Computeが宛先になる場合の通信です。Computeがクライアントになる場合の通信でセカンダリVNIC側のGWを経由したい場合は、スタティック・ルートの設定が必要です。

# ip rule show
0:      from all lookup local
32765:  from 10.0.0.190 lookup ort3 ★これ(10.0.0.190は、セカンダリVNICに割り当てたIP)
32766:  from all lookup main
32767:  from all lookup default

# ip route show table ort3
default via 10.0.0.129 dev ens5 ★ (10.0.0.129は、セカンダリVNICに割り当てたセグメントのGW)

OS起動時に、自動でセカンダリVNICにIPを割り当てたい場合は、ocidの自動起動を有効にします。

# systemctl enable ocid
Created symlink from /etc/systemd/system/multi-user.target.wants/ocid.service to /etc/systemd/system/ocid.service.

/usr/libexec/oci-growfs

oci-growfsは、rootファイルシステムを拡張するためのツールです

インスタンスのルート・ファイルシステムを構成したサイズに拡張します。

Boot Volume拡張後、以下のようにデバイスをスキャンして

# sudo dd iflag=direct if=/dev/oracleoci/oraclevda of=/dev/null count=1
# echo "1" | sudo tee /sys/class/block/`readlink /dev/oracleoci/oraclevda | cut -d'/' -f 2`/device/rescan

oci-growfsを使用して、パーティションとrootファイルシステムを拡張します

# df -Ph /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        42G  3.2G   39G   8% /

### OEL7での実行結果。OEL8の場合出力が微妙に異なります。
# /usr/libexec/oci-growfs 
CHANGE: partition=3 start=17188864 old: size=87668702 end=104857566 new: size=108640222 end=125829086
Confirm? [y/n]y
CHANGED: partition=3 start=17188864 old: size=87668702 end=104857566 new: size=108640222 end=125829086
meta-data=/dev/sda3              isize=256    agcount=5, agsize=2515200 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=0        finobt=0, sparse=0, rmapbt=0
         =                       reflink=0
data     =                       bsize=4096   blocks=10958587, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=4912, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 10958587 to 13580027

# df -Ph /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        52G  3.2G   49G   7% / ★ 42Gから52Gに拡張

/usr/bin/oci-metadata

oci-metadataは、インスタンス・メタデータを整形して表示してくれます

コンピュート・インスタンスのメタデータが表示されます。コマンドライン・オプションを指定しないと、使用可能なすべてのメタデータがリストされます。メタデータに含まれるのは、インスタンスOCID、表示名、コンパートメント、シェイプ、リージョン、可用性ドメイン、作成日、状態、イメージ、および指定するカスタム・メタデータ(SSH公開キーなど)です。

インスタンス・メタデータは、以下のように169.254.169.254にアクセスすることで取得することができますが、
( インスタンス・メタデータのマニュアル )

# curl http://169.254.169.254/opc/v1/instance
{
  "availabilityDomain" : "ZnnM:AP-TOKYO-1-AD-1",
  "faultDomain" : "FAULT-DOMAIN-1",
  "compartmentId" : …

このメタデータを扱いやすくしてくれるコマンドのようです。オプションをつけずに実行すると、メタデータをyamlっぽく表示してくれます。

# oci-metadata
Instance details:
  Display Name: xxxxxx
  Region: ap-tokyo-1
  Canonical Region Name: ap-tokyo-1
  Availability Domain: ZnnM:AP-TOKYO-1-AD-1
  Fault domain: FAULT-DOMAIN-1
  OCID: ocid1.instance.oc1.ap-tokyo-1.anxhiljr75xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  Compartment OCID: ocid1.compartment.oc1..aaaaaaaaazxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  Instance shape: VM.Standard.E4.Flex
  Image ID: ocid1.image.oc1.ap-tokyo-1.aaaaaaaa4wphdui5ftyunwjeddul3kvtdy7v5kcslbmqkp3djmjcel5bjhda
  Created at: 1621488423834
  state: Running
  hostname: xxxxxx
  ociAdName: ap-tokyo-1-ad-1
  regionInfo:
    realmKey: oc1
    realmDomainComponent: oraclecloud.com
    regionKey: NRT
    regionIdentifier: ap-tokyo-1
  shapeConfig:
    ocpus: 1.0
    memoryInGBs: 2.0
    networkingBandwidthInGbps: 1.0
    maxVnicAttachments: 2
  agentConfig:
    monitoringDisabled: False
    managementDisabled: False
    allPluginsDisabled: True
    pluginsConfig: [{'name': 'Vulnerability Scanning', 'desiredState': 'DISABLED'}, {'name': 'OS Management Service Agent', 'desiredState': 'DISABLED'}, {'name': 'Custom Logs Monitoring', 'desiredState': 'DISABLED'}, {'name': 'Compute Instance Run Command', 'desiredState': 'DISABLED'}, {'name': 'Compute Instance Monitoring', 'desiredState': 'DISABLED'}, {'name': 'Block Volume Management', 'desiredState': 'DISABLED'}]
  Instance Metadata:
    ssh_authorized_keys: tokyo-1
  Availability Domain: ZnnM:AP-TOKYO-1-AD-1
  Fault domain: FAULT-DOMAIN-1
  OCID: ocid1.instance.oc1.ap-tokyo-1.anxhiljr75xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  Compartment OCID: ocid1.compartment.oc1..a
  Networking details:
  VNIC OCID: ocid1.vnic.oc1.ap-tokyo-1.abxhiljxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  VLAN Tag: 2124
  Private IP address: 10.XX.XX.XX
  MAC address: 02:00:17:XX:XX:XX
  Subnet CIDR block: 10.XX.XX.XX/24
  Virtual router IP address: 10.XX.XX.XX

-jオプションでjson形式で出力したり、

# oci-metadata -j
{
  "instance": {
    "availabilityDomain": "ZnnM:AP-TOKYO-1-AD-1",
    "faultDomain": "FAULT-DOMAIN-1",
…

メタデータから特定の値を取り出したいときは、-gと--valu-onlyを使って以下のような指定もできるようです

# oci-metadata -g "id" --value-only
ocid1.instance.oc1.ap-tokyo-1.anxhiljr75xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

/usr/bin/oci-public-ip

マニュアルによると、以下のように書いてあります

現在のシステムのパブリックIPアドレスが表示されます(人間が判読できる形式またはJSON形式)。

oci-publi-ipコマンドを実行すると、インターネットと通信する時に使用されるパブリックIPを表示してくれるようです

Internet GW経由でインターネット通信するホストの場合はComputeに付与したパブリックIPが、NAT GW経由でインターネット通信するホストの場合はNAT GWのパブリックIPが表示されました。

# oci-public-ip 
Public IP addresses: 
  Primary public IP: 138.3.XX.XX ★Private サブネットの場合はNAT GWのパブリックIPが表示された
  Other public IP(s): None

一部のホストでPublic IPアドレスを表示できなかったので、tcpdumpで調べたところ、どうやら3478と3479/udpを使って実際に外部と通信しているようで、インターネットへのエグレス・ルールに、これらのポートが許可されていない場合は利用できないようです。

表示できない場合は、以下のように表示されます

No public IP address found.

インターネットへの接続先を制御している環境では3478,3479/udpをわざわざ開けていないでしょうから、httpsの通信は許可されているのであれば、ifconfig.ioにアクセスした方が同じことができて、手軽そうな印象です

# curl https://ifconfig.io

/usr/bin/oci-iscsi-config

oci-iscsi-configは、アタッチしたBlock VolumeのiSCSIの情報を表示してくれます。

コンピュート・インスタンスにアタッチされたiSCSIデバイスをリストまたは構成します。コマンドライン・オプションを指定しないと、注意が必要なデバイスがリストされます。

権限がない環境で実行した場合、iSCSI接続したBlock Volumeの情報が出力されます。

ただし、このコマンドは、クラスタ・リソースの情報を取得するためにOCIのエンドポイントにアクセスするようで、認証・認可の設定をしていない環境では、一部エラーが出力されました。(ocidサービスが起動していない場合も、警告が出力されます)

# oci-iscsi-config -s
Currently attached iSCSI devices:

Target iqn.2015-12.com.oracleiaas:fa2750c7-db0b-xxxxxxxxxxxxxxxxx
   Persistent portal:    169.254.2.2:3260
      Current portal:    169.254.2.2:3260
               State:    LOGGED_IN
     Attached device:    sdb
                Size:    50G
    File system type:    xfs
          Mountpoint:    /vol1

error getting compartment: {'opc-request-id': 'C1A69366E8424484B110AE0ECC145CB0/29xxxxxxxxxxxxxxxxx', 'code': 'NotAuthorizedOrNotFound', 'message': 'Authorization failed or requested resource not found', 'status': 404}
OCI SDK Error:Compartment for this instance not found

No additional storage volumes found.

oci cliをインストールして権限を与えてあげると、エラーは表示されなくなりましたが、出力される情報は変わらなかったです。Additional storage volumeというのを探しにいっているのだと思いますが、何を表示してくれるのかは不明。

# oci-iscsi-config -s
Currently attached iSCSI devices:

Target iqn.2015-12.com.oracleiaas:fa2750c7-db0b-xxxxxxxxxxxxxxxxx
         Volume name:    blk-vol01
         Volume OCID:    ocid1.volume.oc1.ap-tokyo-1.abxhxxxxxxxxxxxxxxxxx
   Persistent portal:    169.254.2.2:3260
      Current portal:    169.254.2.2:3260
               State:    LOGGED_IN
     Attached device:    sdc
                Size:    50G
    File system type:    xfs
          Mountpoint:    /vol1

Other available storage volumes:

/usr/bin/oci-network-config

VNICの情報を出力してくれます

コンピュート・インスタンスにアタッチされている仮想ネットワーク・インタフェース・カード(VNIC)をリストまたは構成されます。クラウド内でセカンダリVNICがプロビジョニングされるときは、このスクリプトまたは同様のコマンドを使用してインスタンスに対して明示的に構成する必要があります

このコマンドもエラーなく表示させるためには、認証・認可の設定が必要です。
権限がない場合は、OSレベルで確認可能な情報のみ出力されます

# /usr/bin/oci-network-config -s
Failed to access OCI services: Failed to fetch instance ocid1.instance.oc1.ap-tokyo-1.anxhixxxxxxxxxxxxxxxxx
Failed to get API session.
Operating System level network configuration
CONFIG ADDR            SPREFIX         SBITS VIRTRT          NS         IND IFACE           VLTAG VLAN        STATE MAC               VNIC
-      10.0.X.X      10.0.0.XX       26    10.0.0.XX       -          2   ens3            XXXX  -           UP    02:00:17:02:XX:XX ocid1.vnic.oc1.ap-tokyo-1.abxhiljrury4xxxxxxxxxxxxxxxxxxxxxxx
-      10.0.X.X      10.0.0.XX      26    10.0.0.XX      -          3   ens5            XXX   -           UP    02:00:17:00:XX:XX ocid1.vnic.oc1.ap-tokyo-1.abxhiljrury4xxxxxxxxxxxxxxxxxxxxxxx

権限がある場合、以下のようにクラスタ・リソースの情報も出力してくれます

# /usr/bin/oci-network-config -s
VNIC configuration for instance oel7-test

VNIC 1: oel7-vnic2
     Hostname: XXX-XXX
     OCID: ocid1.vnic.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     MAC address: 02:00:17:00:XX:XX
     Public IP address: None
     Private IP address: 10.0.0.XXX
     Subnet: subnet10.0.0.128/26 (Subnet 'subnet10.0.0.128/26' (ocid1.subnet.oc1.ap-tokyo-1.aaaaaaaa5uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxq))

VNIC 2 (primary): oel7-test
     Hostname: XXX-XXX
     OCID: ocid1.vnic.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     MAC address: 02:00:17:02:XX:XX
     Public IP address: None
     Private IP address: 10.0.0.XXX
     Subnet: subnet10.0.0.64/26 (Subnet 'subnet10.0.0.64/26' (ocid1.subnet.oc1.ap-tokyo-1.aaaaaaaapmaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx))

Operating System level network configuration
CONFIG ADDR            SPREFIX         SBITS VIRTRT          NS         IND IFACE           VLTAG VLAN        STATE MAC               VNIC
-      10.0.X.X      10.0.X.X       26    10.0.X.X       -          2   ens3            XXXX  -           UP    02:00:17:02:XX:XX ocid1.vnic.oc1.ap-tokyo-1.abxhiljrury4xxxxxxxxxxxxxxxxxxxxxxx
-      10.0.X.X      10.0.X.X      26    10.0.X.X      -          3   ens5            XXXX  -           UP    02:00:17:00:XX:XX ocid1.vnic.oc1.ap-tokyo-1.abxhiljrury4xxxxxxxxxxxxxxxxxxxxxxx

/usr/bin/oci-network-inspector

VCN/サブネット/セキュリティ・リストの情報を一覧でずらっと出力してくれます。

指定されたコンパートメントまたはネットワークの詳細レポートを表示します。

こちらも、権限がないと一切情報が取得できません。

# oci-network-inspector 
No VCN information found

権限がある場合は、以下のように表示されます。-Cや-NオプションでコンパートメントやVCN単位で情報出力範囲を限定できるようです

#  oci-network-inspector 
Compartment: xxxx_compartment (ocid1.compartment.oc1..aaaaaaaazxxxxxxxxxxxxxxxxxxxxxxxxxxx)

  vcn: vcn10.0.X.X/24 (ocid1.vcn.oc1.ap-tokyo-1.amaaaaaa2xxxxxxxxxxxxxxxxxxxxxxxxxxx)
    Security List: security_list_private02
      Ingress: all            xx.xx.xx.xx/xx:-                       ---:-
      Egress : all                    ---:-                 xx.xx.xx.xx/xx:-
    Security List: security_list_private01
      Ingress: all            xx.xx.xx.xx/xx:-                       ---:-
      Ingress: all           xx.xx.xx.xx/xx:-                       ---:-
      Egress : tcp                    ---:-                 xx.xx.xx.xx/xx:443
    Security List: security_list_public
      Ingress: tcp       xx.xx.xx.xx/xx:-                       ---:22
…
      Egress : tcp                    ---:-                 xx.xx.xx.xx/xx:-
    Security List: Default Security List for vcn10.0.X.X/24
      Ingress: tcp              xx.xx.xx.xx/xx:-                       ---:22
      Ingress: icmp             xx.xx.xx.xx/xx:-                    code-4:type-3
      Ingress: icmp          xx.xx.xx.xx/xx:-                 code-None:type-3
      Egress : all                    ---:-                 xx.xx.xx.xx/xx:-

     Subnet: subnet10.0.X.X/26 (ocid1.subnet.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxx)
                Availibility domain: None
                Cidr_block: 10.0.X.X/26
                DNS Domain Name: xxxxxxxxxxxxxxxxxxxxxxxxxxx
       Security List: security_list_private02
         Ingress: all            xxxxxxxxxxxxxxxxxxxxxxxxxxx:-                       ---:-
         Egress : all                    ---:-                 xx.xx.xx.xx/xx:-
       Private IP: 10.0.0.xxxx(primary) Host: xxxxxxx
         Vnic: ocid1.vnic.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxa (AVAILABLE-ATTACHED)
         Instance: xxxx(RUNNING)
         Instance ocid: ocid1.instance.oc1.ap-tokyo-1.axxxxxxxxxxxxxxxxxxxxxxxxxxx
…
     Subnet: subnet10.0.X.X/26 (ocid1.subnet.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxx)
                Availibility domain: None
                Cidr_block: 10.0.X.X/26
                DNS Domain Name: xxxxxxxxxxxxxxxxxxxxxxxxxxx
       Security List: security_list_private01
…

/usr/bin/oci-notify

Oracle Cloud Infrastructure Notificationsサービス・トピックにメッセージを送信します。

このコマンドは、oci cliを、install python36-oci-cliパッケージを使用してインストールする必要があるようです。

# oci_cli is not installed; install python36-oci-cli.

トピックを設定してメッセージを飛ばすだけかな。試してはいません。

# oci-notify -h
Usage:
oci-notify -c <Notification topic OCID>
  Configuration.
oci-notify -t <Message title> -f <File containing the message body>
  Send a message.
oci-notify -h
  This help text.
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?