Skip to content

Commit

Permalink
feat(convert): export ENV vars (#411)
Browse files Browse the repository at this point in the history
* feat(convert): export ENV vars

We could have passed these into the "build_env:" directive, however it
appears environment substitution is also allowed such as
PATH=/usr/local/sbin:$PATH for that layer, which is harder to figure
out. Instead just "export" them in the "run:" directive.

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>

* ci(convert): add a workflow to convert upstream repos

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>

---------

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
  • Loading branch information
rchincha authored Mar 2, 2023
1 parent 5a2e32b commit e577430
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 37 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ jobs:
REGISTRY_URL: localhost:5000
- name: Upload code coverage
uses: codecov/codecov-action@v3
- if: github.event_name == 'release' && github.event.action == 'published'
uses: actions/cache@v3
- uses: actions/cache@v3
id: restore-build
with:
path: stacker
key: ${{ github.event.release.tag_name }}-${{ steps.short-sha.outputs.sha }}
key: ${{ steps.short-sha.outputs.sha }}
82 changes: 82 additions & 0 deletions .github/workflows/convert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: "convert dockerfiles"

on:
schedule:
- cron: '0 0 * * *'

env:
REGISTRY_URL: localhost:5000

jobs:
ci:
uses: ./.github/workflows/build.yaml
with:
# note >-, args needs to be strings to be used as inputs
# for the reusable build.yaml workflow
go-version: >-
["1.20.x"]
privilege-level: >-
["priv"]
convert:
name: "convert"
runs-on: ubuntu-20.04
# needs ci for the cached stacker binary
needs: ci
steps:
- uses: benjlevesque/short-sha@v2.1
id: short-sha
- uses: actions/cache@v3
id: restore-build
with:
path: stacker
key: ${{ steps.short-sha.outputs.sha }}
- name: zot registry
env:
ZOT_HOST: localhost
ZOT_PORT: 5000
run: |
# start a zot instance (minimal)
podman run -p ${ZOT_PORT}:${ZOT_PORT} ghcr.io/project-zot/zot-minimal-linux-amd64:latest
# check if reachable
while true; do x=0; curl -f http://${REGISTRY_URL}/v2/ || x=1; if [ $x -eq 0 ]; then break; fi; sleep 1; done
- name: alpine
run: |
export PATH=$PATH:$GITHUB_WORKSPACE
git clone https://github.com/alpinelinux/docker-alpine.git
chmod -R a+rwx docker-alpine
cd docker-alpine
mkdir -p /out
chmod -R a+rwx /out
stacker convert --docker-file Dockerfile --output-file stacker.yaml --substitute-file stacker-subs.yaml
stacker build -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=alpine
stacker publish -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=alpine --skip-tls --url docker://${REGISTRY_URL} --layer alpine --tag latest
rm -f stacker.yaml stacker-subs.yaml
stacker clean
cd $GITHUB_WORKSPACE
rm -rf docker-alpine
- name: elasticsearch
run: |
export PATH=$PATH:$GITHUB_WORKSPACE
git clone https://github.com/elastic/dockerfiles.git
chmod -R a+rwx dockerfiles
cd dockerfiles/elasticsearch
stacker convert --docker-file Dockerfile --output-file stacker.yaml --substitute-file stacker-subs.yaml
stacker build -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=elasticsearch
stacker publish -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=elasticsearch --skip-tls --url docker://${REGISTRY_URL} --layer elasticsearch
rm -f stacker.yaml stacker-subs.yaml
stacker clean
cd $GITHUB_WORKSPACE
rm -rf dockerfiles
- name: python
run: |
export PATH=$PATH:$GITHUB_WORKSPACE
git clone https://github.com/docker-library/python.git
cd python/3.11/alpine3.17
chmod -R a+rw .
stacker convert --docker-file Dockerfile --output-file stacker.yaml --substitute-file stacker-subs.yaml
stacker build -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=python
stacker publish -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=python --skip-tls --url docker://${REGISTRY_URL} --layer python --tag latest
rm -f stacker.yaml stacker-subs.yaml
stacker clean
cd $GITHUB_WORKSPACE
rm -rf python
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
id: restore-build
with:
path: stacker
key: ${{ github.event.release.tag_name }}-${{ steps.short-sha.outputs.sha }}
key: ${{ steps.short-sha.outputs.sha }}
- if: github.event_name == 'release' && github.event.action == 'published'
name: Publish artifacts on releases
uses: svenstaro/upload-release-action@v2
Expand Down
16 changes: 12 additions & 4 deletions pkg/stacker/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"

Expand Down Expand Up @@ -32,6 +33,7 @@ type Converter struct {
currLayer string
subs map[string]string
args []string
env map[string]string
// per-layer state
currDir string
currUid string
Expand Down Expand Up @@ -98,6 +100,11 @@ func (c *Converter) convertCommand(cmd *Command) error {
}
c.output[c.currLayer] = &layer
case "run":
// setup the environment
for k, v := range c.env {
layer.Run = append(layer.Run, fmt.Sprintf("export %s=%s", k, v))
}

// replace any ARGs first
for i, val := range cmd.Value {
for _, arg := range c.args {
Expand All @@ -123,7 +130,8 @@ func (c *Converter) convertCommand(cmd *Command) error {

for _, line := range cmd.Value {
// patch some cmds
line = strings.ReplaceAll(line, "mkdir", "mkdir -p ")
re := regexp.MustCompile(`\bmkdir\b`)
line = re.ReplaceAllString(line, "mkdir -p")

if c.currUid == "" {
// picking 'bash' here
Expand Down Expand Up @@ -183,11 +191,11 @@ func (c *Converter) convertCommand(cmd *Command) error {
}
}

if layer.Environment == nil {
layer.Environment = map[string]string{}
if c.env == nil {
c.env = map[string]string{}
}

layer.Environment[cmd.Value[0]] = val
c.env[cmd.Value[0]] = val
case "workdir":
layer.Run = append(layer.Run, fmt.Sprintf("cd %s", cmd.Value[0]))
c.currDir = cmd.Value[0]
Expand Down
32 changes: 3 additions & 29 deletions test/convert.bats
Original file line number Diff line number Diff line change
Expand Up @@ -30,37 +30,11 @@ EOF
# build should now work
## docker build -t test
mkdir -p /out
stacker build -f stacker.yaml --substitute-file stacker-subs.yaml
rm -f stacker.yaml stacker-subs.yaml
stacker clean
}

@test "build alpine image" {
git clone https://github.com/alpinelinux/docker-alpine.git
chmod -R a+rwx docker-alpine
cd docker-alpine
mkdir -p /out
chmod -R a+rwx /out
stacker convert --docker-file Dockerfile --output-file stacker.yaml --substitute-file stacker-subs.yaml
stacker build -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=alpine
if [ -z "${REGISTRY_URL}" ]; then
skip "skipping test because no registry found in REGISTRY_URL env variable"
fi
stacker publish -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=alpine --skip-tls --url docker://${REGISTRY_URL} --tag latest
rm -f stacker.yaml stacker-subs.yaml
stacker clean
}

@test "build elasticsearch image" {
git clone https://github.com/elastic/dockerfiles.git
chmod -R a+rwx dockerfiles
cd dockerfiles/elasticsearch
stacker convert --docker-file Dockerfile --output-file stacker.yaml --substitute-file stacker-subs.yaml
stacker build -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=elasticsearch
stacker build -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=app
if [ -z "${REGISTRY_URL}" ]; then
skip "skipping test because no registry found in REGISTRY_URL env variable"
skip "skipping test because no registry found in REGISTRY_URL env variable"
fi
stacker publish -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=elasticsearch --skip-tls --url docker://${REGISTRY_URL} --tag latest
stacker publish -f stacker.yaml --substitute-file stacker-subs.yaml --substitute IMAGE=app --skip-tls --url docker://${REGISTRY_URL} --layer app --tag latest
rm -f stacker.yaml stacker-subs.yaml
stacker clean
}

0 comments on commit e577430

Please sign in to comment.