ОС «Аврора» — веб-сервер в кармане

226f003dddf3d194a125053c205928b3.png


Привет, читатель!

В начале июня я опубликовал обзор на смартфон с ОС «Аврора». После этого взялся изучать документацию к SDK, решил написать пару небольших приложений и портировать один проект на телефон. В процессе понял, что для выполнения команд, просмотра файлов и доставки пакетов требуется консоль. В какой-то момент стало любопытно покопаться и посмотреть, какие приложения есть в репозиториях «Авроры» и с чем из этого можно поиграться. Выбор оказался весьма широк, но самым интересным для меня был исполнитель интерпретируемого языка. Если вам интересно, какой код можно запустить со смартфона на «Авроре» и какие могут возникнуть нюансы, прошу под кат!

Используйте оглавление, если не хотите читать текст полностью:

→ Подготовка
→ Настройка окружения
→ ShareMeet
→ SQLite
→ Заключение

Подготовка


Как подготовить смартфон


Большинство настроек будем проводить через терминал, как в серверной версии Linux-системы. Если любите хардкор, можно вбивать команды в консольном приложении телефона. Чуть удобнее делать это с помощью клавиатуры, подключенной по проводу или через Bluetooth.

Однако для максимального комфорта предлагаю подключиться к смартфону по SSH. Это значительно упростит ввод команд и копирование, а также позволит работать через любимую IDE. OpenSSH server есть в репозиториях, но завести его для работы на версии ОС 4.0 не удалось.

Итак, переходим в меню смартфона по пути НастройкиСистемаСредства разработчика, включаем режим разработчика и задаем пароль для подключения.

20ffc6bebe758faeebcd415b09aab7e5.png


Настройки → Система → Средства разработчика.

Далее идем в НастройкиСистемаАдминистрирование, указываем пароль для администратора и включаем приложение терминала.

e99ab82a0214248870469cc5fe6fef88.png


Настройки → Система → Администрирование.

Как подготовить сеть


Если в домашней сети есть доступ к панели управления маршрутизатором, рекомендую выставить в его настройках DHCP статический IP-адрес для телефона. Это позволит подключаться к устройству по одному и тому же адресу как из консоли, так и при отладке приложения из IDE.

7e9a782578ee7773091090ea7b8dcf0e.png


Пример на MikroTik (другого маршрутизатора у меня нет, но подход аналогичен).

Для подключения к консоли телефона возможны и другие варианты: раздать Wi-Fi с другого телефона, использовать мобильный интернет или же подключиться кабелем Type-C, установив дополнительно соответствующие драйвера. Альтернативный вариант — подключить USB сетевую карту и патчкордом подцепить интернет — возможности ограничены только фантазией! Способ подключения зависит только от того, как вам удобнее работать.

40a25bffe75272f37160c3030a5bdb14.png


После подключения к одной локальной сети любым из способов выше можно выполнить тестовое подключение к телефону. Рекомендую сразу обменяться ключами, это позволит подключаться без ввода пароля. Обратите внимание, если будете использовать подключение из среды разработки, указывайте одинаковые пути к ключам SSH.

Процесс настройки SSH-авторизации по ключу и разбор некоторых ошибок описан в Академии Selectel.
ssh-copy-id defaultuser@IP //IP - адрес телефона в локальной сети
ssh defaultuser@IP


ea61d44aafbf0c242d11e8ca8a8215e1.png


Указывайте тот же ключ в настройках среды разработки «Авроры».

Установка пакетов


Python не установлен по умолчанию в используемой версии ОС, но это не проблема. Помню, лет восемь назад пытался проделать такую операцию со смартфоном на Android — сплошные костыли и никакого удовольствия. За это время, на мой взгляд, мало что изменилось. И хотя в Git и Play Market есть нужные пакеты, подходящих устройств для проверки на рынке не появилось. В «Аврору» же Python добавляется одной командой:

devel-su // переходим в суперпользователя
pkcon install python3 git nano


oc2p7egxfswgdcnzdsqi16jqtlq.png

Настройка окружения


С давних пор являюсь сторонником использования venv+pip в качестве инструментов для работы с Python. Да, виртуальная среда весит довольно много. Однако она позволяет поставить необходимые библиотеки для работы, не засоряя системные пути. Создаем директорию проекта и в ней venv для сервера:

python3 -m venv venv && source venv/bin/activate
python3 -m pip install flask


Если проект запушили в систему контроля версий (GitLab, GitHub, Bitbucket), просто склонируйте его, создайте venv и разверните библиотеки:

git clone … 
cd project
python3 -m venv venv && source venv/bin/activate
python3 -m pip install -r requirements.txt


В начале решил проверить, запустится ли вообще веб-сервер. Для этого взял пример с официального туториала Flask, быстро накидал файлы приложения, HTML-странички и докинул таблицы стилей. В короткие сроки получил рабочее приложение:

fcfeafe11ec09739ece4afd4d2a9efe5.png


Простая страничка, развернутая на карманном сервере с экраном.

Просто так запускать одну страничку не особо интересно, поэтому с женой за пару вечеров написали небольшое приложение ShareMeet. Результат работы лежит в открытом репозитории GitHub.

ShareMeet


Мы написали приложение, которое позволяет устройствам обмениваться трафиком через TCP-порты в одной сети Wi-Fi (если настройки самой сети этого не запрещают). Это актуально, например, на конференциях, когда нужно оперативно отправить кому-то совместное фото или видео с проведенным только что экспериментом.

Выкладывать файлы в облако и пересылать ссылку не всегда удобно: скорость соединения может быть невысокой, а заинтересованному лицу нужно бежать. Так и возникло предложение: сделать небольшой файлообменник, который можно «натравить» на папку в системе и позволять клиентам скачивать оттуда материалы.

39c0b0c360d9f1da61ebd1cac65aae5e.png


MVP — три страницы основного функционала.

MVP приложения было получено за первый вечер: сервис позволяет скачивать файлы из локальной директории. При разворачивании приложения на «мобильном сервере» потребовалось доставить дополнительные пакеты и библиотеки Python:

# pkcon install python3-devel gcc gcc-c++
$ python3 -m pip install flask flask-dotenv // в активированном venv


Как теперь пользователям сказать, где они могут оперативно скачать ваши файлы? Сделаем простенький генератор QR-кодов с ссылкой на наше устройство. Изначально планировал для этого использовать библиотеку flask-qrcode, чтобы генерировать и на лету отдавать картинку в браузер. Однако она требует библиотеку pillow, которая, в свою очередь, хочет множество установленных пакетов в ОС. Части из них под «Аврору» 4.0 не было. Пришлось делать обходное решение на базе библиотеки qrcode.

Она умеет на лету генерировать QR-коды в форматах PNG или SVG. Последний является нативным для HTML. Генерируем картинку следующим кодом:

ip = [(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]
link = f'http://{ip}:5000/shared_files'
qr_link = qrcode.make(link,
        image_factory=qrcode.image.svg.SvgPathImage)
qr_svg = qr_link.to_string(encoding='unicode')


И встраиваем в страницу:

{{ svg_img|safe }}


Как видно выше, код для определения адреса интерфейса тоже не самый оптимальный. Изначальный вариант был на порядок короче, но библиотека socket некорректно выполняет запрос и не получает адрес на интефрейсе.

socket.gethostbyname(socket.gethostname()) # вариант получения IP адреса интерфейса


SQLite


Дополнительно добавили форму для обратной связи. А чтобы хранить отзывы, пригодится база данных. В репозиториях создателей «Авроры» нашлись пакеты СУБД SQLite. Это отличный вариант для разработки MVP. Да, по сути это набор библиотек, который позволяет обращаться к файлу формата db.

Доставляем новые библиотеки и библиотеки:

#pkcon install sqlite python3-sqlite
$python3 -m pip install flask-sqlalchemy // в активированном venv


Подготавливаем код структуры БД в Python. Необходима одна таблица с данными: кто, во сколько и что написал. Дополнительно предложим пользователям оставить контакт, по которому с ним можно связаться:

class Comments(db.Model):
    id: so.Mapped[int] = so.mapped_column(primary_key=True)
    name: so.Mapped[str] = so.mapped_column(sa.String(256), index=True)
    contact: so.Mapped[Optional[str]] = so.mapped_column(sa.String(256))
    comment: so.Mapped[str] = so.mapped_column(sa.String(1000))
    create_date: so.Mapped[datetime] = so.mapped_column(default=lambda: datetime.now(timezone.utc))


Применяем миграцию для формирования файла базы данных:

python3 -m flask db init


Далее создаем маршрут, который отдает страницу с формой, получает от нее ответ и записывает полученную информацию в БД:

@app.route('/add_comment', methods=['GET', 'POST'])
def add_comment():
    form = CommentForm()
    if form.validate_on_submit():
        …
        comment = Comments(name=name, contact=contact, comment=comment)
        db.session.add(comment)
        db.session.commit()
        flash(f'{name}, Ваш комментарий добавлен! Благодарю за обратную связь!')
        return redirect(url_for('add_comment'))
    return render_template('add_comment.html', form=form)


На этом основной каркас приложения завершен. Пользователи могут подключиться к веб-серверу по QR-коду, забрать необходимые файлы, дать комментарии и оставить свои контакты.

Пробовал запускать небольшие тесты locust с созданным приложением. Телефон может стабильно работать с 25 пользователями единовременно со средним временем отклика 500 мс.

72c088d5c67c6a8639100def2c5cd628.png


Заключение


Это было достаточно забавное приключение по установке интерпретатора Python и разворачиванию небольшого веб-приложения на мобильном телефоне. Есть ли у этого практическая польза? Не уверен. Но в качестве MVP получился вполне себе удобный походный вариант. Созданное приложение можно в дальнейшем упаковать в rpm-пакет и передать коллегам и друзьям для личных нужд. Например, сбора информации у группы тестирования идеи. Однако вести разработку исключительно в таком варианте, по-моему, нецелесообразно до обновления ОС.

Разработанное приложение буду использовать по его целевому назначению — делиться файлами и использовать как демонстрацию возможностей мобильной платформы. По возможности буду его обновлять и поддерживать, но существенно функционал не изменится. В планах — собрать rpm-пакет и, возможно, сделать пайплайн автосборки.

В комментариях делитесь своими идеями: есть ли у такой разработки будущее, проводили ли вы сами подобные эксперименты, что можно улучшить и так далее. Подозреваю, это далеко не последняя статья о разработке под «Аврору».

© Habrahabr.ru