Skip to content

Commit

Permalink
Change installed az CLI version with clientVersion
Browse files Browse the repository at this point in the history
I've added clientVersion to the az mixin configuration so that you can
specify which version of the az CLI to install when porter builds the
bundle. By default, the latest version of the CLI is installed.

```yaml
mixins:
- az:
    clientVersion: 2.35.0
```

The mixin will use the clientVersion to build the apt package version
published by Microsoft, which follows the format
VERSION-1~DISTROCODENAME. So in the example above, the package version
is 2.35.0-1~stretch. If the user changes the debian version, then
stretch will change to match the version, e.g. buster, etc.

Signed-off-by: Carolyn Van Slyck <[email protected]>
  • Loading branch information
carolynvs committed Jul 22, 2022
1 parent e4ff4d3 commit 023e1a4
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 47 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ This is a mixin for Porter that provides the Azure (az) CLI.

## Mixin Configuration

### Client Version
By default, the most recent version of the az CLI is installed.
You can specify a specific version with the `clientVersion` setting.

```yaml
mixins:
- az:
clientVersion: 1.2.3
```
### Extensions
When you declare the mixin, you can also configure additional extensions to install
**Use the vanilla az CLI**
Expand Down
32 changes: 25 additions & 7 deletions pkg/az/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package az

import (
"fmt"
"text/template"

"get.porter.sh/porter/pkg/exec/builder"
"gopkg.in/yaml.v3"
Expand All @@ -18,9 +19,26 @@ type BuildInput struct {
// extensions:
// - NAME
type MixinConfig struct {
Extensions []string
ClientVersion string `yaml:"clientVersion,omitempty"`
Extensions []string `yaml:"extensions,omitempty"`
}

// The package version of the az cli follows this format:
// VERSION-1~DISTRO_CODENAME So if we are running on debian stretch and have a
// version of 1.2.3, the package version would be 1.2.3-1~stretch.
const buildTemplate string = `
RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \
apt-get update && apt-get install -y apt-transport-https lsb-release gnupg curl
RUN curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.asc.gpg
RUN echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list
RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \
apt-get update && apt-get install -y --no-install-recommends \
{{ if eq .ClientVersion ""}}azure-cli{{else}}azure-cli={{.ClientVersion}}-1~$(lsb_release -cs){{end}}
{{ range $ext := .Extensions }}
RUN az extension add -y --name {{ $ext }}
{{ end }}
`

// Build installs the az cli and any configured extensions.
func (m *Mixin) Build() error {
var input BuildInput
Expand All @@ -32,13 +50,13 @@ func (m *Mixin) Build() error {
return err
}

fmt.Fprintln(m.Out, `RUN apt-get update && apt-get install -y apt-transport-https lsb-release gnupg curl`)
fmt.Fprintln(m.Out, `RUN curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.asc.gpg`)
fmt.Fprintln(m.Out, `RUN echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list`)
fmt.Fprintln(m.Out, `RUN apt-get update && apt-get install -y azure-cli`)
tmpl, err := template.New("dockerfile").Parse(buildTemplate)
if err != nil {
return fmt.Errorf("error parsing Dockerfile template for the az mixin: %w", err)
}

for _, ext := range input.Config.Extensions {
fmt.Fprintf(m.Out, "RUN az extension add -y --name %s\n", ext)
if err = tmpl.Execute(m.Out, input.Config); err != nil {
return fmt.Errorf("error generating Dockerfile lines for the az mixin: %w", err)
}

return nil
Expand Down
70 changes: 30 additions & 40 deletions pkg/az/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,38 @@ package az

import (
"bytes"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"io/ioutil"
"testing"

"get.porter.sh/porter/pkg/test"

"github.com/stretchr/testify/require"
)

func TestMixin_Build(t *testing.T) {
const buildOutput = `RUN apt-get update && apt-get install -y apt-transport-https lsb-release gnupg curl
RUN curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.asc.gpg
RUN echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list
RUN apt-get update && apt-get install -y azure-cli
`

t.Run("build with config", func(t *testing.T) {
b, err := ioutil.ReadFile("testdata/build-input-with-config.yaml")
require.NoError(t, err)

m := NewTestMixin(t)
m.Debug = false
m.In = bytes.NewReader(b)

err = m.Build()
require.NoError(t, err, "build failed")

wantOutput := buildOutput + `RUN az extension add -y --name iot
`
gotOutput := m.TestContext.GetOutput()
assert.Equal(t, wantOutput, gotOutput)
})

t.Run("build without config", func(t *testing.T) {
b, err := ioutil.ReadFile("testdata/build-input-without-config.yaml")
require.NoError(t, err)

m := NewTestMixin(t)
m.Debug = false
m.In = bytes.NewReader(b)

err = m.Build()
require.NoError(t, err, "build failed")

gotOutput := m.TestContext.GetOutput()
assert.Equal(t, buildOutput, gotOutput)
})
}

testcases := []struct {
name string
inputFile string
wantOutputFile string
}{
{name: "build with config", inputFile: "testdata/build-input-with-config.yaml", wantOutputFile: "testdata/build-with-config.txt"},
{name: "build without config", inputFile: "testdata/build-input-without-config.yaml", wantOutputFile: "testdata/build-without-config.txt"},
}

for _, tc := range testcases {
t.Run("build with config", func(t *testing.T) {
b, err := ioutil.ReadFile(tc.inputFile)
require.NoError(t, err)

m := NewTestMixin(t)
m.Debug = false
m.In = bytes.NewReader(b)

err = m.Build()
require.NoError(t, err, "build failed")

test.CompareGoldenFile(t, tc.wantOutputFile, m.TestContext.GetOutput())
})
}
}
2 changes: 2 additions & 0 deletions pkg/az/testdata/build-input-with-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
config:
clientVersion: 1.2.3
extensions:
- iot

actions:
install:
- az:
Expand Down
11 changes: 11 additions & 0 deletions pkg/az/testdata/build-with-config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \
apt-get update && apt-get install -y apt-transport-https lsb-release gnupg curl
RUN curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.asc.gpg
RUN echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list
RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \
apt-get update && apt-get install -y --no-install-recommends \
azure-cli=1.2.3-1~$(lsb_release -cs)

RUN az extension add -y --name iot

9 changes: 9 additions & 0 deletions pkg/az/testdata/build-without-config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \
apt-get update && apt-get install -y apt-transport-https lsb-release gnupg curl
RUN curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.asc.gpg
RUN echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list
RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \
apt-get update && apt-get install -y --no-install-recommends \
azure-cli

0 comments on commit 023e1a4

Please sign in to comment.