Как стать автором
Обновить

Комментарии 25

Такое бы, да для сборки яблочных приложений. Но ничего кроме специально подготовленных виртуалок ещё не видел. Может кто сталкивался?
Есть образ docker с Xcode, но как я понимаю там происходит проксирование в host систему. Суть контейнеров при этом теряется.
Для macOS существует проприетарная и платная альтернатива docker — anka build. Работает на основе Hypervisor.framework
`gradle` можно было поставить в `ENTRYPOINT`, например

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

Скажете «это тривиально, посмотри в интернетах»? Так тут вся статья тривиальная, если уж на то пошло

Согласен — проблема с правами пользователя имеет место быть.
Я знаю как минимум три или четыре решения, но нет ни одного прям красивого. Могу поделиться идеями, если интересно.
С другой стороны — в ci/cd процессе, суть не на машине разработчика, проблемы с правами скорее всего нет, тем более, если использовать dind.

> суть не на машине разработчика

Да, в сиае много вопросов отпадает, но как же «единство сборочного окружения»? :)

А идеями поделиться никогда не лишне! Я, например, колдую небольшой скрипт, который на старте контейнера создает пользователя с нужным uid и только после этого выполняет команду. А что делают ваши три или четыре варианта? :)

Я идей накидаю, а Вы там соберите в кучу.


Идея 1. Наивно можно запускать контейнер с ключом -u (--uid). Тогда исполняемый файл будет запускаться под юзером с указанным UID. Прокинуть айди текущего юзера можно через $(id -u). Проблема в том, что это работает, если все каталоги внутри образа с правами 777 и программа должна быть собрана и настроена портабельно. Это далеко не всегда так


Идея 2. Раз предыдущее не работает, то давайте мы сделаем docker-entrypoint.sh скрипт, будем в нем свитчится в нужного юзера и там же заchown'им и chmod'им все необходимые для работы каталоги. В принципе это работает, но выглядит не красиво: приходится передавать айди текущего юзера через переменную окружения (docker run ... -e UID=$(id -u)) внутрь контейнера. А потом через тот же gosu свитчиться в нужного юзера. При этом это не работает с ключом --uid из п.1, т.к. нам надо стартовать из-под рута. Дополнительно — это не решает проблемы с правами на корневой каталог, куда будут смонтированы файлы докера (он все равно будет под рутом). И в опеншифте такой контейнер не запустится.


Идея 3. Нам вообще не нравится писать колбасу вида
docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 /bin/bash -c "./pre.sh; gradle assembleDebug; ./post.sh" Итого — приходим к необходимости написания какой-то внешней обвязки в виде баш скрипта, алиаса или мейкфайла. Запомним это.


Идея 4.а Все проблемы с правами на каталог, который создает докер из-за ключа -v. Если перейти на полный синтаксис bind mount, то целевой каталог НЕ СОЗДАЕТСЯ автоматически, а это значит, что если мы создадим его в скрипте из Идея 3 руками, то с правами на каталог будет все ок, а права на файлы будут нормальные — см. Идея 1 и Идея 2


Идея 4.b Мы можем вообще не париться с вольюмами, а тупо писать файлы в volume, а вытаскивать их из них либо через временный контейнер с нужным юзером, либо через docker cp


Идея 4. c Ах, еще можно запустить в докер-контейнере тот же тар, а наружу прокинуть файл через пайп (что-то типа docker exec -it blablabla cat FILE | cat > FILE — тот кат, что справа уже выполняется на хосте с привилегиями текущего юзера, т.е. получается нам вообще без разницы, что внутри контейнера происходит)

Годно. Теперь, если кто-то будет использовать эту статью по назначению, обязательно наткнется на эти залежи и улучшит свой пайплайн ;)

Сам я же уже давольно давно использую «идею 2» с некоторыми вариациями — всё хорошо. (что до опеншифта, он мне не надыть, так что, проблем не возникает)

antaresm по поводу прав на каталоги и файлы артефактов есть что добавить?

Я просто на старте контейнера в нем создаю пользователя с uid равным идентификатору с хоста, и дальше выполняю под ним. Естественно, проверяю, запускается ли контейнер в ci окружении или у разработчика на хосте.

YMMV ;)

Т.е. если на хосте два юзера с ID 1000 и 1001, то один из них будет в обломе )
Хотя для линукс машин, в общем-то, это не очень типичный сценарий, а на маке с докером обычно нет проблем с правами на файлы )))))

> если на хосте два юзера с ID 1000 и 1001, то один из них будет в обломе

почему же?! это всё происходит динамически, во время старта контейнера. у каждого пользователя будет контейнер с его uid. мы же про сборочные контейнеры говорим, а не про сферические в вакууме.

Сорри, я не Вам писал, Вы ответили, а я невпопад повторно ответил )
Да, Вы правы — если пробрасывать uid в контейнер (мы рассмотрели способы как это сделать), но в статье автора — id user'а в контейнере зафиксирован. Соответственно, как мы выше определили — это норм для ci/cd, но не очень круто, когда разраб хочет "сборочный" контейнер запустить на своем ПК

Если нам нужны непосредственно артефакты как файлы, то у нас сам контейнер запускается под root, поэтому после сборки проблем достать артефакты не возникает;
В большинстве случаев же, gradle заливает полученный apk в HockeyApp или GooglePlay.
то у нас сам контейнер запускается под root

Ну, Вы имеете в виду, что docker run выполняется от root'а? Тогда да, проблем нет.
Как насчет работы на машине разработчика? Или в опеншифте (где рут внутри контейнера запрещен по вполне понятным причинам)

Да, docker run выполняется root'ом
Для разработчика локально запустить root тоже не проблема.
А для опеншифт как я уже писал мы не храним артефакт, а заливаем его на внешний ресурс
Для разработчика локально запустить root тоже не проблема.

Как минимум — лишнее действие. Как максимум — в компании может быть политика ИБ (хотя, конечно, может выглядеть глупо — рута не даем, а докер даем)))


А для опеншифт как я уже писал мы не храним артефакт, а заливаем его на внешний ресурс

Вы им вообще пользовались, извините? Речь про запуск сборщика в кластере.

не пользовались. поэтому я просто вам описал решение которое у нас на сервере CI используется. основная то проблема в правах, как я понял; Или, извините, я не правильно понял проблему

Да, основная проблема в правах.
Но как я выше подчеркнул — ее можно игнорировать, в случае, если вся история происходит в CI/CD конвейере на выделенном инстансе. Но ведь хочется больше!!! Масштабировать процесс на все ) и на машины разраба, и в кластере собирать (чтобы не платить за выделенную машину, а платить за фактические потребленное время сборок) и т.п.

Хотел добавить, что курлить артефакт из публичного репо без проверки sha — так себе идея.
Пример — собираете Вы такой свой образ, сидите в Корп сети, а там Корп прокси. Помимо того, что он курочит хттпс, он легко может вместо артефакта zip выдать страницу с ошибкой. Но курл ее честно скачает и положит во временный образ.
Другой вопрос, что процесс сборки скорее всего свалится на распаковке, но вот такой вектор атаки все равно остаётся...


Ну, и браво — Вы переизобрели концепцию временных "сборочных" контейнеров. Очень удобное продакшен решение, на самом деле. Учитывая, что его ещё можно отмасштабировать на машину разраба, если он не хочет захламлять основную систему дев-тулзами

В первом случае: у нас стоит внутренний репозиторий образов. Поэтому в нашем случае проверка излишняя.
На тему переизобретения: даже не пытаюсь присвоить это себе и в тексте про это ни слова. Просто, как показал опыт — мобильные разработчики обычно далеко от темы контейнеров и Docker и наверняка этот туториал будет много кому как минимум интересен.

Ссылка так-то на оф.сайт — https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip


На тему переизобретения: даже не пытаюсь присвоить это себе и в тексте про это ни слова. Просто, как показал опыт — мобильные разработчики обычно далеко от темы контейнеров и Docker и наверняка этот туториал будет много кому как минимум интересен.

Интересен, интересен. Я просто подчеркиваю, что описана в общем-то действительно неплохая практика.

НЛО прилетело и опубликовало эту надпись здесь
Или можно все сразу
RUN yes | sdkmanager --licenses
Есть ли у вас опыт запуска espresso тестов в docker контейнере (т.е. запуск эмулятора)?
Нет. Эмуляторы с тестами мы запускаем как обычно на отдельной машине
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории