Как устранить исключения. OSError: [Errno 1] Операция не разрешена (Docker-контейнер)? - PullRequest
0 голосов
/ 13 января 2019

Я пытаюсь сканировать устройства BLE с помощью bluepy . Мой scan.py код - -

from bluepy.btle import Scanner, DefaultDelegate

class ScanDelegate(DefaultDelegate):
    def __init__(self):
        DefaultDelegate.__init__(self)

    def handleDiscovery(self, dev, isNewDev, isNewData):
        if isNewDev:
            print "Discovered device", dev.addr
        elif isNewData:
            print "Received new data from", dev.addr

# prepare scanner
scanner = Scanner().withDelegate(ScanDelegate())

# scan for 5 seconds
devices = scanner.scan(5.0)

for dev in devices:
    print "Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi)
    for (adtype, desc, value) in dev.getScanData():
        print "  %s = %s" % (desc, value)

Согласно документации (упоминается в самом последнем примечании) -

(1) LE scanning must be run as root

Это означает, что нам нужно запустить скрипт с sudo. Я запускаю это как -

sudo python scan.py

В основном bluepy-helper требует sudo для сканирования. Требуется установить возможности для blupe-helper для запуска кода без sudo. Согласно решению , я сделал -

sudo setcap 'cap_net_raw,cap_net_admin+eip' /usr/local/lib/python2.7/site-packages/bluepy/bluepy-helper

Из Терминала код сканирования теперь выполняется без sudo как -

python scan.py

Наконец я сделал Dockerfile -

FROM arm32v7/python:2.7.15-jessie
WORKDIR /usr/app/gfi_ble
COPY . /usr/app/gfi_ble
RUN chmod 755 ./setcap_for_bluepy_helper.sh
RUN pip install -r requirements.txt
CMD ["./setcap_for_bluepy_helper.sh", "--", "python", "src/scan.py"]

Содержимое setcap_for_bluepy_helper.sh is -

#!/bin/bash
cmd="$@"
>&2 setcap 'cap_net_raw,cap_net_admin+eip' /usr/local/lib/python2.7/site-packages/bluepy/bluepy-helper
exec $cmd

Образ успешно создан, но когда я запускаю контейнер, я получаю сообщение об ошибке вроде -

Creating con_gfi_ble ... done
Attaching to con_gfi_ble
con_gfi_ble | 2019-01-12 23:06:24+0000 [-] Unhandled Error
con_gfi_ble |   Traceback (most recent call last):
con_gfi_ble |     File "/usr/app/gfi_ble/src/scan.py", line 17, in new_devices
con_gfi_ble |       devices = scanner.scan(5.0)
con_gfi_ble |     File "/usr/local/lib/python2.7/site-packages/bluepy/btle.py", line 852, in scan
con_gfi_ble |       self.start(passive=passive)
con_gfi_ble |     File "/usr/local/lib/python2.7/site-packages/bluepy/btle.py", line 789, in start
con_gfi_ble |       self._startHelper(iface=self.iface)
con_gfi_ble |     File "/usr/local/lib/python2.7/site-packages/bluepy/btle.py", line 284, in _startHelper
con_gfi_ble |       preexec_fn = preexec_function)
con_gfi_ble |     File "/usr/local/lib/python2.7/subprocess.py", line 394, in __init__
con_gfi_ble |       errread, errwrite)
con_gfi_ble |     File "/usr/local/lib/python2.7/subprocess.py", line 1047, in _execute_child
con_gfi_ble |       raise child_exception
con_gfi_ble |   exceptions.OSError: [Errno 1] Operation not permitted
con_gfi_ble | 

Вопрос: Что означает исключения. Ошибка: [Errno 1] Операция не разрешена?

Мой код в порядке, когда я запускаю его из терминала. Что не так с контейнером? Любая идея!

1 Ответ

0 голосов
/ 13 января 2019

Контейнеры Docker работают с ограниченными возможностями. Это предотвращает выход корня из контейнера из контейнера путем запуска команд ядра без пространств имен и доступа к частям хоста вне контейнера, таким как необработанные сетевые интерфейсы или физические устройства. Вам нужно добавить возможности в контейнер извне, если они вам нужны, но помните, что это снижает безопасность, обеспечиваемую настройками докера по умолчанию.

Начиная с docker run, это выглядит так:

docker run --cap-add=NET_ADMIN --cap-add=NET_RAW ...

https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities

В составном файле это выглядит так:

version: '2'

services:
  app:
    image: your_image
    cap_add:
      - NET_ADMIN
      - NET_RAW

Ссылка: https://docs.docker.com/compose/compose-file/

Это не будет работать в режиме роя. Продолжается работа по добавлению возможности запуска команд с дополнительными возможностями в режиме роя. Если вам это нужно, есть ужасные обходные пути.

Обратите внимание, что вы не должны запускать sudo внутри контейнера. Это означает, что у всего есть доступ к самореализации, и он побеждает цель запуска чего-либо как пользователя. Вместо этого вы должны запустить контейнер как root и как можно скорее перейти к обычному пользователю, что является односторонней операцией.

...