Vyatta専用コマンドを深堀りしてみた。

前回のエントリ で書いた通り、configureコマンドやsetコマンドはシェルスクリプトでは使えませんでした。単にVyattaを運用するだけなら、そのまま ${vyatta_sbindir}/my_* コマンドを使えば良いのでしょう。でも何故使えなかったのでしょうか。なんでそのままにしておくのは気持ち悪くて、夜もぐっすり眠れません。精神衛生上よろしくありませんね。

ですので、このモヤモヤを解消するため、オペレーションモード、設定モードについてそれぞれ調べてみました。

オペレーションモードの専用コマンドを探る。

まず、aliasコマンドを実行してみると分かります。

$ alias
alias add='_vyatta_op_run add'
alias clear='_vyatta_op_run clear'
alias clone='_vyatta_op_run clone'
alias configure='_vyatta_op_run configure'
alias connect='_vyatta_op_run connect'
alias copy='_vyatta_op_run copy'
alias debug='_vyatta_op_run debug'
alias delete='_vyatta_op_run delete'
alias disconnect='_vyatta_op_run disconnect'
alias format='_vyatta_op_run format'
alias generate='_vyatta_op_run generate'
alias init-floppy='_vyatta_op_run init-floppy'
alias install-image='_vyatta_op_run install-image'
alias install-system='_vyatta_op_run install-system'
alias ls='ls --color=auto'
alias no='_vyatta_op_run no'
alias ping='_vyatta_op_run ping'
alias ping6='_vyatta_op_run ping6'
alias reboot='_vyatta_op_run reboot'
alias release='_vyatta_op_run release'
alias remove='_vyatta_op_run remove'
alias rename='_vyatta_op_run rename'
alias renew='_vyatta_op_run renew'
alias reset='_vyatta_op_run reset'
alias restart='_vyatta_op_run restart'
alias set='_vyatta_op_run set'
alias show='_vyatta_op_run show'
alias shutdown='_vyatta_op_run shutdown'
alias telnet='_vyatta_op_run telnet'
alias terminal='_vyatta_op_run terminal'
alias traceroute='_vyatta_op_run traceroute'
alias traceroute6='_vyatta_op_run traceroute6'
alias undebug='_vyatta_op_run undebug'
alias update='_vyatta_op_run update'

“_vyatta_op_run hoge”の形でaliasが設定されているのは全てVyatta専用のコマンドです。_vyatta_op_runは、/etc/bash_completion.d/vyatta-op-runで定義されている関数です。

_vyatta_op_run ()
{
    local -i estat
    local tpath=$vyatta_op_templates
    local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; )
    shopt -s extglob nullglob

    _vyatta_op_last_comp=${_vyatta_op_last_comp_init}
    false; estat=$?

    i=1
    for arg in "$@"
        do
        if [ -f "$tpath/$arg/node.def" ] ; then
            tpath+=/$arg
        elif [ -f $tpath/node.tag/node.def ] ; then
            tpath+=/node.tag
        else
            echo "Invalid command" >&2
            eval $restore_shopts
            return 1
        fi
        let "i+=1"
    done

    local run_cmd=$(_vyatta_op_get_node_def_field $tpath/node.def run)
    local ret=0
    if [ -n "$run_cmd" ]; then
        if [[ -t 1 &&  "$1" == "show" && \
            ! $run_cmd =~ ^\(LESSOPEN=\|less\|pager\|tail\|/opt/vyatta/bin/vyatta-tshark-interface-port.pl\).* ]] ; then
            eval "($run_cmd) | ${VYATTA_PAGER:-cat}"
        else
            eval "$run_cmd"
        fi
    else
        echo "Incomplete command" >&2
        ret=1
    fi
    eval $restore_shopts
    return $ret
}

この中の”$run_cmd”が実際に実行するvyatta用のコマンドが設定されます。$run_cmdが、”show”だった場合、showコマンドで設定やステータスの情報を表示し、それ以外の場合は、$tpath/$arg/node.defで定義されているコマンドを実行します。このコマンドの引数などが不完全な場合は、”Incomplete command”と実行される、というわけです。$tpathは、$vyatta_op_templatesが代入されていますがこの変数は入れ子になっており、実際に実行するコマンドは/opt/vyatta/share/vyatta-op/templates/ ${arg}として、実行されるコマンドの処理内容は/opt/vyatta/share/vyatta-op/templates/${arg}/node .defに定義されています。例えば、

$ show interfaces

とするとインタフェースの設定状況を確認できますが、これは、templates/show/interfaces/node.defで定義されており、その内容は

help: Show network interface information
run: ${vyatta_bindir}/vyatta-show-interfaces.pl --action=show-brief

となっています。この場合は

  • help: show interfacesコマンドのヘルプメッセージ
  • run: show interfacesコマンドが実行する内容( ${vyatta_bindir}/vyatta -show-interfaces.pl –action=show-brief)

というワケです。

なので、オペレーションモードのコマンドをシェルスクリプトにする場合は、シェルスクリプト内でaliasを使えるように、”expand_aliases”を有効にしてやり/etc/bash_completion.d/vyatta-opを読み込みんでやると、オペレーションモードと同じコマンドが使えるようになります。

#!/bin/vbash
shopt -s expand_aliases
. /etc/bash_completion.d/vyatta-op
show interfaces

または、下記のようにalias展開前のコマンドを記述して

#!/bin/vbash
. /etc/bash_completion.d/vyatta-op-run
_vyatta_op_run show interfaces

とするか、node.defのrunで設定されている実行コマンドを記述して

#!/bin/sh
${vyatta_bindir}/vyatta-show-interfaces.pl --action=show-brief

とすればシェルスクリプトでもオペレーションモードのコマンドを使えるようになります。ただし、設定モードに変更するために、

_vyatta_op_run configure

と記述してスクリプトを実行すると、対話形式で設定モードに切り替わってしまうので、その後ろに書いている設定モードのコマンドは実行されません。

オペレーションモードのtabキーの動きを探る。

vbashでは、tab補完が効きますが、何も入力していない状態でtabキーを一回押すと、

add             debug           install-image   release         set             traceroute6
clear           delete          install-system  remove          show            undebug
clone           disconnect      no              rename          shutdown        update
configure       format          ping            renew           telnet
connect         generate        ping6           reset           terminal
copy            init-floppy     reboot          restart         traceroute

のように実行可能なVyatta専用のコマンドが表示されます。これは、/opt/vyatta/share/vyatta-op/templates/以下をlsで見た場合と同じです。

$ ls /opt/vyatta/share/vyatta-op/templates/
add        connect  disconnect   install-image   ping6    rename   set       terminal     update
clear      copy     format       install-system  reboot   renew    show      traceroute
clone      debug    generate     no              release  reset    shutdown  traceroute6
configure  delete   init-floppy  ping            remove   restart  telnet    undebug

再度tabキーを押すと、各コマンドの概要が表示されます。

Possible completions:
  add           Add an object to a service
  clear         Clear system information
  clone         Clone an object
  configure     Enter configure mode
  connect       Establish a connection
  copy          Copy data
  debug         Enable debugging of specified routing protocol
  delete        Delete a file
  disconnect    Take down a connection
  format        Format a device
  generate      Generate an object
  init-floppy   Format and prepare a floppy to save the config.boot file
  install-image Install new system image to hard drive
  install-system
                Install system to hard drive
  no            Disable or reset operational variable
  ping          Send Internet Control Message Protocol (ICMP) echo request
  ping6         Send IPv6 Internet Control Message Protocol (ICMP) echo request
  reboot        Reboot the system
  release       Release specified variable
  remove        Remove an object from service
  rename        Re-name something.
  renew         Renew specified variable
  reset         Reset a service
  restart       Restart a service
  set           Set system or shell options
  show          Show system information
  shutdown      Shutdown the system
  telnet        Telnet to <hostname|IPv4 address>
  terminal      Control terminal behaviors
  traceroute    Track network path to <hostname|IPv4 address>
  traceroute6   Track network path to <hostname|IPv6 address>
  undebug       Disable specified debugging
  update        Run an update command

これは、node.defの、”help:”で設定されている内容が表示されます。

設定モードの専用コマンドを探る。

一方、設定モードで使用するcommitやsave, loadコマンドなどは、/etc/bash_completion.d/vyatta-cfgで定義されています。

$ grep '()' /etc/bash_completion.d/vyatta-cfg | egrep -v '^\s|declare|vyatta|get|print|generate|reset|really' | more
show ()
commit ()
commit-confirm ()
confirm ()
compare ()
save ()
reboot ()
rollback ()
shutdown ()
load ()
merge ()
top ()
edit ()
up ()
exit ()
run ()
loadkey()

オペレーションモードと同様にtabキーを押すと、コマンドが表示されます。

comment         commit-confirm  confirm         delete          edit            load            merge           rollback        save            show
commit          compare         copy            discard         exit            loadkey         rename          run             set

tabキーもう一回押して表示されるhelpは、オペレーションモードとは異なり、/etc/bash_completion.d/vyatta-cfgの中で変数_get_help_text_helpsに設定されています。

_get_help_text_helps=( \
  "Confirm prior commit-confirm" \
  "Add comment to this configuration element" \
  "Commit the current set of changes" \
  "Commit the current set of changes with 'confirm' required" \
  "Compare configuration revisions" \
  "Copy a configuration element" \
  "Delete a configuration element" \
  "Discard uncommitted changes" \
  "Edit a sub-element" \
  "Exit from this configuration level" \
  "Load configuration from a file and replace running configuration" \
  "Load user SSH key from a file" \
  "Load configuration from a file and merge running configuration" \
  "Rename a configuration element" \
  "Rollback to a prior config revision (requires reboot)" \
  "Run an operational-mode command" \
  "Save configuration to a file" \
  "Set the value of a parameter or create a new element" \
  "Show the configuration (default values may be suppressed)" \
)

設定モードで使えるコマンドは、この/etc/bash_completion.d/vyatta-cfgで定義されているコマンド以外に、aliasで設定されているものもあります。

$ configure
# alias
alias comment='/opt/vyatta/sbin/my_comment'
alias copy='/opt/vyatta/sbin/my_copy'
alias delete='/opt/vyatta/sbin/my_delete'
alias discard='/opt/vyatta/sbin/my_discard'
alias ls='ls --color=auto'
alias rename='/opt/vyatta/sbin/my_rename'
alias set='/opt/vyatta/sbin/my_set'
[edit]

先ほどのmy_setコマンドが設定されていることが分かります。ここで、オペレーションモードの時と同じように、

#!/bin/vbash
shopt -s expand_aliases
. /etc/bash_completion.d/vyatta-cfg
set interfaces ethernet eth0 description hoge

としても、残念ながら/etc/bash_completion.d/vyatta-cfgの読み込み時に、

# ./test.sh
/etc/bash_completion.d/vyatta-cfg: line 888: bind: warning: line editing not enabled
/etc/bash_completion.d/vyatta-cfg: line 889: bind: warning: line editing not enabled
/etc/bash_completion.d/vyatta-cfg: line 890: bind: warning: line editing not enabled
/etc/bash_completion.d/vyatta-cfg: line 892: bind: warning: line editing not enabled
/etc/bash_completion.d/vyatta-cfg: line 893: bind: warning: line editing not enabled
[edit]

のようにコケてしまいます [1] 。オペレーションモードでこのスクリプトを実行するとwarningは出ませんがやはり設定はできていません。 前回のエントリ のように素直に ${vyatta_sbindir}/my_* コマンドを使うのがよいでしょう。

各レベルのパラメータの定義を探る。

オペレーションモードのコマンドを定義していたのが/opt/vyatta/share/vyatta-op/templates/以下でしたが、設定モードで使う各レベルのパラメータは/opt/vyatta/share/vyatta-cfg/templates/の下で定義されています。

VyattaはDebianベースのディストロです。Vyattaの最新版の6.3はDebian GNU/Linux Squeezeのi386, amd64がベースになっており、Vyatta独自のソフトウェアもDebianパッケージとして提供されています。前者はvyatta-opパッケージで、後者はvyatta-cfgパッケージで基本的に提供されています。vyatta-cfgパッケージで提供されているテンプレートはinterfacesだけでsystem,serviceなどのテンプレートは他のパッケージ(systemならvyatta-cfg-system, NATならvyatta-natなど)で提供されています。例えば、ホスト名の設定は、

# set system host-name hoge

と設定しますが、これはvyatta-cfg-systemパッケージのtemplates/system/host-name/node.defで定義されています。これの中を見てみると、

type: txt
help: Set system host name (default: vyatta)
default: "vyatta"
syntax:expression: pattern $VAR(@) "^[[:alpha:]][-.[:alnum:]]*[[:alnum:]]$"
                   ; "invalid host name $VAR(@)"
update: sudo sh -c " \
  hostname '$VAR(@)'
  echo '$VAR(@)' > /etc/hostname
  touch /etc/hosts
  sed -i '/^127.0.1.1/d' /etc/hosts
  echo -e \"127.0.1.1\t $VAR(@)\t #vyatta entry\" >> /etc/hosts
  if [ x$VAR(../domain-name/@) != x ]; then
    echo -e \"127.0.1.1\t $VAR(@).$VAR(../domain-name/@)\t #vyatta entry\" \
      >> /etc/hosts
    echo \"$VAR(@).$VAR(../domain-name/@)\" > /etc/mailname
  else
    echo \"$VAR(@)\" > /etc/mailname
  fi"
delete: sudo sh -c " \
  echo 'vyatta' > /etc/hostname
  hostname 'vyatta'
  touch /etc/hosts
  sed -i '/^127.0.1.1/d' /etc/hosts
  echo -e \"127.0.1.1\t vyatta\t #vyatta entry\" >> /etc/hosts
  if [ x$VAR(../domain-name/@) != x ]; then
    echo -e \"127.0.1.1\t vyatta.$VAR(../domain-name/@)\t #vyatta entry\" \
      >> /etc/hosts
    echo \"vyatta.$VAR(../domain-name/@)\" > /etc/mailname
  else
    echo \"vyatta\" > /etc/mailname
  fi"

となっています。この内容は、

  • type: とりうるパラメータの種類(ここではtxt)
  • help: コマンドのヘルプ
  • default: デフォルト値(デフォルトではホスト名はvyatta)
  • sytax:expression: 書式のパターン(ホスト名の先頭一文字目は半角英字、2文字目以降は半角英数もしくはハイフン、またはピリオド、最後の文字は半角英数を許可)
  • update: ホスト名更新時に実行される処理(/etc/hostname, /etc/hosts, /etc/mailnameを指定したホスト名およびドメイン名があればそれで更新)
  • delete: ホスト名削除時に実行される処理(update時に更新されるファイルをホスト名を”vyatta”として更新)

ですので、オペレーションモードでのコマンドの定義と基本的には同じだということが分かります。

${vyatta_sbindir}/my_* コマンドを探る。

それでは、先ほどの my_* コマンドについてもう少し突っ込んで見てみます。これらのコマンドの実体は ${vyatta_sbindir}/my_cli_bin へのシンボリックリンクになっています。

  $ ls -l ${vyatta_sbindir}/my*
  -rwxr-xr-x 1 root root 19512 Jul 21 09:31 /opt/vyatta/sbin/my_cli_bin
  -rwxr-xr-x 1 root root 32416 Jul 21 09:31 /opt/vyatta/sbin/my_cli_shell_api
  lrwxrwxrwx 1 root root    10 Jul 21 16:37 /opt/vyatta/sbin/my_comment -> my_cli_bin
  lrwxrwxrwx 1 root root    10 Jul 21 16:37 /opt/vyatta/sbin/my_commit -> my_cli_bin
  lrwxrwxrwx 1 root root    10 Jul 21 16:37 /opt/vyatta/sbin/my_copy -> my_cli_bin
  lrwxrwxrwx 1 root root    10 Jul 21 16:37 /opt/vyatta/sbin/my_delete -> my_cli_bin
  lrwxrwxrwx 1 root root    10 Jul 21 16:37 /opt/vyatta/sbin/my_discard -> my_cli_bin
  lrwxrwxrwx 1 root root    10 Jul 21 16:37 /opt/vyatta/sbin/my_move -> my_cli_bin
  lrwxrwxrwx 1 root root    10 Jul 21 16:37 /opt/vyatta/sbin/my_rename -> my_cli_bin
  lrwxrwxrwx 1 root root    10 Jul 21 16:37 /opt/vyatta/sbin/my_set -> my_cli_bin


:command:`${vyatta_sbindir}/my_cli_bin` コマンド自体は、ELF形式の実行ファイルで、my_setコマンドやmy_commitコマンドなどのシンボリックリンクも含め、これはvyatta-cfgパッケージによって提供されています。
$ dpkg -S ${vyatta_sbindir}/my_cli_bin
vyatta-cfg: /opt/vyatta/sbin/my_cli_bin

このバイナリパッケージに含まれているドキュメントは、/usr/share/doc/vyatta-cfg/READMEくらいですが、このファイルには

This package has the Vyatta configuration system, including the configuration

back-end, the base configuration templates, and the config-mode CLI completion

mechanism.

と書かれています。では、vyatta-cfgパッケージのソースコードを見てみます。

apt-get source vyatta-cfg、じゃあないの?!

前述のとおりVyattaはDebianベースなので、

$ apt-get source vyatta-cfg

でソースパッケージを取得しよう!と思うかもしれません。が、デフォルトではdeb-srcのAPT Lineが無いのでできません。そこで、デフォルトで設定されている

deb http://packages.vyatta.com/vyatta stable main # community #

をコピーして、

deb-src http://packages.vyatta.com/vyatta stable main

を設定しても、残念ながらリポジトリにはソースパッケージは置いてないのでapt-get updateがコケます。困ってしまいましたね。

Vyattaのソースコードの入手方法。

これもちゃんと ドキュメントに記述があります 。ソースコードを入手するにはbuild-src.gitリポジトリをgit cloneを行います。そして、今回必要なvyatta-cfgパッケージのソースコードはsubmoduleとして入手します。

$ git clone http://git.vyatta.com/build-iso.git
$ cd build-iso
$ git submodule init
(snip)
Submodule 'pkgs/vyatta-cfg' (http://git.vyatta.com/vyatta-cfg.git) registered for path 'pkgs/vyatta-cfg'
(snip)

submoduleの初期化後、submodule updateでpkg/vyatta-cfgリポジトリのコピーを行います。

$ git submodule update pkgs/vyatta-cfg
Cloning into 'pkgs/vyatta-cfg'...
Submodule path 'pkgs/vyatta-cfg': checked out '55dc3e317c138286de6353c21ab47c91fca9a2f4'

git submodule updateが完了すると、HEADがcheckoutされます。

$ cd pkgs/vyatta-cfg
$ git log
commit 55dc3e317c138286de6353c21ab47c91fca9a2f4
Merge: 02a2145 0b582e0
Author: rbalocca <rbalocca@vyatta.com>
Date:   Fri Dec 26 09:35:12 2008 -0800

    Merge branch 'islavista'
(snip)
$ ls
AUTHORS  COPYING  ChangeLog  Makefile.am  NEWS  README  configure.ac  debian  etc  scripts  src  templates

なお、単にソースコードを見るだけなら、gitweb経由で VyattaのGitリポジトリ は公開されています。 vyatta-cfgもその中で公開 されています。

my_cli_binのソースコードを見てみる。

最新のVyattaのリリースのバージョンはset versionコマンドで確認すると、VC6.3-2011.07.21だと分かります。

$ show version
Version:      VC6.3-2011.07.21
(snip)

vyatta-cfgのリポジトリのtagを確認するとVC6.3-2011.07.21にはamd64とi386とがあります。

$ git tag
(snip)
vyatta/VC6.3-2011.07.21/amd64
vyatta/VC6.3-2011.07.21/i386
vyatta/VC6.3-2011.10.04/amd64
vyatta/VC6.3-2011.10.04/i386

タグvyatta/VC6.3-2011.07.21/amd64をまずチェックアウトします。

$ git checkout vyatta/VC6.3-2011.07.21/amd64
Note: checking out 'vyatta/VC6.3-2011.07.21/amd64'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 64d54e8... 0.99.8+napa6

my_cli_binをgrepすると、src/cli_bin.cppがソースコードだと分かります。

$ git grep my_cli_bin
Makefile.am:sbin_PROGRAMS += src/my_cli_bin
Makefile.am:src_my_cli_bin_SOURCES = src/cli_bin.cpp
Makefile.am:      $(LN_S) my_cli_bin my_set; \
Makefile.am:      $(LN_S) my_cli_bin my_delete; \
Makefile.am:      $(LN_S) my_cli_bin my_rename; \
Makefile.am:      $(LN_S) my_cli_bin my_copy; \
Makefile.am:      $(LN_S) my_cli_bin my_comment; \
Makefile.am:      $(LN_S) my_cli_bin my_discard; \
Makefile.am:      $(LN_S) my_cli_bin my_move; \
Makefile.am:      $(LN_S) my_cli_bin my_commit
debian/vyatta-cfg.postinst.in:for bin in my_cli_bin my_cli_shell_api; do

これを見ると実行するコマンドのパスのbasenameが、*op_bin_name配列の要素にマッチすれば、その機能が実行される、ということが分かります。

static int op_idx = -1;
static const char *op_bin_name[] = {
  "my_set",
  "my_delete",
  "my_activate",
  "my_deactivate",
  "my_rename",
  "my_copy",
  "my_comment",
  "my_discard",
  "my_move",
  "my_commit",
  NULL
};
static const char *op_Str[] = {
  "Set",
  "Delete",
  "Activate",
  "Deactivate",
  "Rename",
  "Copy",
  "Comment",
  "Discard",
  "Move",
  "Commit",
  NULL
};
static const char *op_str[] = {
  "set",
  "delete",
  "activate",
  "deactivate",
  "rename",
  "copy",
  "comment",
  "discard",
  "move",
  "commit",
  NULL
};
(snip)
#define OP_Str op_Str[op_idx]
#define OP_str op_str[op_idx]
#define OP_need_cfg_node_args op_need_cfg_node_args[op_idx]
#define OP_use_edit_level op_use_edit_level[op_idx]
(snip)
static void
doSet(Cstore& cstore, const Cpath& path_comps)
{
  if (!cstore.validateSetPath(path_comps)) {
    bye("invalid set path\n");
  }
  if (!cstore.setCfgPath(path_comps)) {
    bye("set cfg path failed\n");
  }
}
(snip)
typedef void (*OpFuncT)(Cstore& cstore,
                        const Cpath& path_comps);
OpFuncT OpFunc[] = {
  &doSet,
  &doDelete,
  &doActivate,
  &doDeactivate,
  &doRename,
  &doCopy,
  &doComment,
  &doDiscard,
  &doMove,
  &doCommit,
  NULL
};

int
main(int argc, char **argv)
{
  int i = 0;
  while (op_bin_name[i]) {
    if (strcmp(basename(argv[0]), op_bin_name[i]) == 0) {
      op_idx = i;
      break;
    }
    ++i;
  }
(snip)
  Cstore *cstore = Cstore::createCstore(OP_use_edit_level);
  Cpath path_comps(const_cast<const char **>(argv + 1), argc - 1);

  // call the op function
  OpFunc[op_idx](*cstore, path_comps);
  delete cstore;
  exit(0);
}

masterブランチは古いので要注意。

ちなみに、vyatta-cfgのリポジトリはmasterブランチが結構古いままです。前述のとおり、2008年12月26日のものがHEADになっています。なので git submodule update直後にそのままソースコードを見ても見つかりません。git logで確認すると2010年7月28日にsrc/cli_bin.cppが初めてコミットされているのが分かりますね。気をつけましょう。

$ git log --reverse src/cli_bin.cpp
commit 639c835bc2730a4fbffd915f5b2028a68375ee7a
Author: An-Cheng Huang <ancheng@vyatta.com>
Date:   Wed Jul 28 14:30:32 2010 -0700

    add new cstore library

まとめ

以上をまとめると、オペレーションモードでは次の方法でシェルスクリプトにすることができます。

  • expand_aliasesを有効にし、/etc/bash_completion.d/vyatta-opを読み込むことで、Vyattaのコマンドをそのまま使う
  • もしくは/etc/bash_completion.d/vyatta-op-runを読み込み、_vyatta_op_runの引数としてVyattaのコマンドを使う

設定モードでは、

  • /etc/bash_completion.d/vyatta-cfgを読み込むだけではダメ
  • ${vyatta_sbindir}/my_cli_bin へのsymlinkになっている、 ${vyatta_sbindir}/my_cli_bin コマンドを使う

ということで、これでシェルスクリプトで、快適なVyattaを自動化した生活を送れるようになれますね。

[1]warningですが、実際に設定されていません。