ラズパイでNewConnectionErrorが発生したときのメモ

# はじめに

以前、[ラズパイでQiita APIを叩いて定期的にデータを取得する記事](https://qiita.com/dyamaguc/items/e549f59689c5a36ff9b2)を書きました。
その後しばらくして、停電を境にcronが動かなくなったので、自分の備忘録のために記録します。

# 起こったこと

プログラムや動作環境については[こちら](https://qiita.com/dyamaguc/items/e549f59689c5a36ff9b2)の記事に記載した通りなので、省略します。
QiitaのAPIを叩いてデータを取得するPythonスクリプト(insert.py)を実行すると、`NewConnectionError`と表示されるようになりました。
以下、実行時のエラーメッセージです。

```shell
$ python3 insert.py 
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 159, in _new_conn
    (self._dns_host, self.port), self.timeout, **extra_kw)
  File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 57, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
  File "/usr/lib/python3.7/socket.py", line 748, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -3] Temporary failure in name resolution

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 343, in _make_request
    self._validate_conn(conn)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 841, in _validate_conn
    conn.connect()
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 301, in connect
    conn = self._new_conn()
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 168, in _new_conn
    self, "Failed to establish a new connection: %s" % e)
urllib3.exceptions.NewConnectionError: <urllib3.connection.VerifiedHTTPSConnection object at 0x72986190>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 638, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 398, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='qiita.com', port=443): Max retries exceeded with url: /api/v2/authenticated_user/items (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x72986190>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "insert.py", line 63, in <module>
    data = collection()
  File "insert.py", line 15, in collection
    res = requests.get(url, headers=headers)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 516, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='qiita.com', port=443): Max retries exceeded with url: /api/v2/authenticated_user/items (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x72986190>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))
```

`Max retries exceeded with url`とも書かれているので、接続回数制限かなーなど、いろいろ調べてみましたが、なかなかコレというものが見つからず。。

初心に戻って外部インターネットとの接続をgoogleに対して`ping`コマンドで確認すると

```shell

$ ping google.com
ping: google.com: 名前解決に一時的に失敗しました
```

となり、名前解決ができていないことが原因だと思いました。確かにエラーメッセージに`Temporary failure in name resolution`と書いてあったので、納得しました。

# 対処

この場合は`dhclient`コマンドを実行し、再度`ping`コマンドを実行します。

```
$ sudo dhclient eth0
$ ping google.com
PING google.com (172.217.161.46) 56(84) bytes of data.
64 bytes from nrt12s23-in-f14.1e100.net (172.217.161.46): icmp_seq=1 ttl=52 time=8.57 ms
64 bytes from nrt12s23-in-f14.1e100.net (172.217.161.46): icmp_seq=2 ttl=52 time=12.7 ms
```

これで外部との接続は修復しました。
あとは起動時に自動で`dhclient`の設定が行われるようにします。
[こちらの記事](http://nagisa314.hatenablog.jp/entry/2015/06/16/144007)に従って、`/etc/init.d/`の中に`dhclient`というファイルを作ります。
まずは上記フォルダの中身を確認します。

```
$ ls /etc/init.d/
alsa-utils        cron            fake-hwclock       lightdm     paxctld       raspi-config  rsyslog       udev
avahi-daemon      dbus            hwclock.sh         mysql       plymouth      rng-tools     ssh           x11-common
bluetooth         dhcpcd          keyboard-setup.sh  networking  plymouth-log  rpcbind       sudo
console-setup.sh  dphys-swapfile  kmod               nfs-common  procps        rsync         triggerhappy
```
`dhclient`というファイルは無かったため、新たに作成します。

```shell
$ sudo vim /etc/init.d/dhclient
```
中身は次の2行のみ記載しています。

```shell

#!/bin/sh
dhclient eth0
```
あとは権限設定と自動実行に登録します。

```shell
$ sudo chmod 755 /etc/init.d/dhclient
$ cd /etc/init.d/
$ sudo update-rc.d dhclient defaults 
```

これでスクリプトが再び自動実行されるようになりました。