Как вызвать побочные эффекты в трубе

Как вызвать побочные эффекты в трубе

Я запускаю minikube как локальную тестовую среду и использую многоэтапные сборки docker для сборки своих контейнеров. Minikube запускает версию docker, которая не поддерживает многоэтапные сборки. Minikube предлагает использовать встроенную среду docker для сборки контейнеров следующим образом:

#!/usr/bin/env bash
eval $(minikube docker-env)
docker build

Поскольку мне нужно использовать локальный экземпляр docker для сборки, я нашел docker save/load. Это значит, что мне нужно сделать следующее:

#!/usr/bin/env bash
docker build
docker save $IMG > /tmp/container.tar
eval $(minikube docker-env) # set up docker env vars
docker load -i /tmp/container.tar
eval $(minikube docker-env -u) # clean up env

Однако docker load может читать файл из stdin. Если бы я мог перенаправить вывод с моего docker-хоста на удаленный docker-хост, я мог бы сделать это без изменения/загрязнения сред моих пользователей. Поэтому мне было интересно, есть ли какой-то способ загрузить minikube env в среде pipe. Я нашел следующие работающие, но, конечно, оба docker-хоста одинаковы:

docker save $IMG | env -i docker load

Но мне бы хотелось что-то вроде следующего (псевдокод, я полагаю)

docker save $IMG | env -i side_effects(eval $(minikube docker-env)) docker load

Я попробовал просто вставить команду (не ожидал, что это сработает):

docker save $IMG | env -i eval $(minikube docker-env) docker load

И создаем функцию для загрузки значений:

function load_env { eval $(minikube docker-env) }
docker save $IMG | env -i load_env() docker load

Ни то, ни другое не сработало. Я не уверен, но предполагаю, что eval получал переданные данные. И eval не использует stdin. Последнее вызвало синтаксическую ошибку.

Наконец, я мог бы сделать что-то вроде этого:

#/usr/bin/env bash
hostenv=$(minikube docker-env | grep DOCKER_HOST | cut -f2 -d'='
certpath=$(minikube docker-env | grep DOCKER_CERT_PATH | cut -f2 -d'='
docker save $IMG | docker -H=$hostenv --tls=true --tlsverify=true \
    --tlscacert=$certpath/ca.pem --tlscert=$certpath/cert.pem \
    --tlskey=$certpath/key.pem

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

Редактировать: Я нашел улучшение по сравнению с вышеизложенным, я бы сказал, что оно, вероятно, менее хрупкое, но все равно более далекое от идеала:

dockerenv=$(minikube docker-env | sed 's/export//g' | sed 's/^#.*$//g' | sed 's/"//g')
docker save $IMG | env -i $dockerenv docker load

ТакДействительноЯ спрашиваю: есть ли надежный способ избежать временных файлов или загрязнения среды на компьютерах моих пользователей? (Если у кого-то есть лучшее название для этого вопросапожалуйстаизменить его - это только один из способов решить мою проблему).

решение1

Нашел простой ответ здесь:https://stackoverflow.com/a/44207110.

docker save $IMG | (eval $(minikube docker-env) && docker load)

Связанный контент