Skip to content

Commit 67a0c8c

Browse files
dacbd0x2b3bfa0
andauthored
Allow for configuring a specific CML version (#255)
* got test -update * Simplify semver handling Co-authored-by: Helio Machado <0x2b3bfa0+git@googlemail.com>
1 parent 9a780d9 commit 67a0c8c

10 files changed

+92
-11
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ require (
1818
github.com/aws/aws-sdk-go-v2/service/s3 v1.18.0
1919
github.com/aws/aws-sdk-go-v2/service/sts v1.7.2
2020
github.com/aws/smithy-go v1.9.0
21+
github.com/blang/semver/v4 v4.0.0
2122
github.com/brianvoe/gofakeit/v6 v6.9.0
2223
github.com/cloudflare/gokey v0.1.0
2324
github.com/gobwas/glob v0.2.3
25+
github.com/google/go-github/v42 v42.0.0
2426
github.com/hashicorp/hcl/v2 v2.8.0 // indirect
2527
github.com/hashicorp/terraform-plugin-sdk/v2 v2.8.0
2628
github.com/rclone/rclone v1.57.0

go.sum

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,14 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
221221
github.com/billziss-gh/cgofuse v1.5.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM=
222222
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
223223
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
224+
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
224225
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
226+
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
227+
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
225228
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
226229
github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
227230
github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
231+
github.com/bradleyfalzon/ghinstallation/v2 v2.0.3/go.mod h1:tlgi+JWCXnKFx/Y4WtnDbZEINo31N5bcvnCoqieefmk=
228232
github.com/brianvoe/gofakeit/v6 v6.9.0 h1:UCGhPCKLiqBc910TKS7LcOGf74NozftibFCbGIS6GZQ=
229233
github.com/brianvoe/gofakeit/v6 v6.9.0/go.mod h1:palrJUk4Fyw38zIFB/uBZqsgzW5VsNllhHKKwAebzew=
230234
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
@@ -389,6 +393,7 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
389393
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
390394
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
391395
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
396+
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
392397
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
393398
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
394399
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -447,7 +452,11 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
447452
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
448453
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
449454
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
455+
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
450456
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
457+
github.com/google/go-github/v39 v39.0.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE=
458+
github.com/google/go-github/v42 v42.0.0 h1:YNT0FwjPrEysRkLIiKuEfSvBPCGKphW5aS5PxwaoLec=
459+
github.com/google/go-github/v42 v42.0.0/go.mod h1:jgg/jvyI0YlDOM1/ps6XYh04HNQ3vKf0CVko62/EhRg=
451460
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
452461
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
453462
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=

iterative/resource_runner.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ func resourceRunner() *schema.Resource {
5151
Required: true,
5252
ForceNew: true,
5353
},
54+
"cml_version": &schema.Schema{
55+
Type: schema.TypeString,
56+
Optional: true,
57+
ForceNew: true,
58+
Default: "",
59+
},
5460
"labels": &schema.Schema{
5561
Type: schema.TypeString,
5662
Optional: true,
@@ -303,7 +309,7 @@ sudo systemctl is-enabled cml.service && return 0
303309
304310
{{- if not .container}}
305311
{{- if .setup}}{{.setup}}{{- end}}
306-
sudo npm config set user 0 && sudo npm install --global @dvcorg/cml
312+
{{.setupCML}}
307313
{{- end}}
308314
309315
{{- if not .container}}
@@ -335,7 +341,7 @@ export KUBERNETES_CONFIGURATION={{escape .KUBERNETES_CONFIGURATION}}
335341
{{.runner_startup_script}}
336342
{{- end}}
337343
338-
HOME="$(mktemp -d)" exec cml-runner \
344+
HOME="$(mktemp -d)" exec $(which cml-runner || echo "cml runner") \
339345
{{if .name}} --name {{escape .name}}{{end}} \
340346
{{if .labels}} --labels {{escape .labels}}{{end}} \
341347
{{if .idle_timeout}} --idle-timeout {{escape .idle_timeout}}{{end}} \
@@ -453,6 +459,7 @@ func provisionerCode(d *schema.ResourceData) (string, error) {
453459
data["KUBERNETES_CONFIGURATION"] = os.Getenv("KUBERNETES_CONFIGURATION")
454460
data["container"] = isContainerAvailable(d.Get("cloud").(string))
455461
data["setup"] = strings.Replace(string(setup[:]), "#/bin/sh", "", 1)
462+
data["setupCML"] = utils.GetCML(d.Get("cml_version").(string))
456463

457464
return renderScript(data)
458465
}

iterative/resource_runner_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ func generateSchemaTestData(cloud string, t *testing.T) *schema.ResourceData {
6565
"driver": "15 value with \"quotes\" and spaces",
6666
"labels": "16 value with \"quotes\" and spaces",
6767
"instance_gpu": "17 value with \"quotes\" and spaces",
68+
"cml_version": "18 value with \"quotes\" and spaces",
6869
"runner_startup_script": "echo \"custom startup script\"",
6970
})
7071
}

iterative/testdata/script_template_cloud_aws.golden

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ if [ ! -f "$FILE" ]; then
3737
echo OK | sudo tee "$FILE"
3838
fi
3939

40-
sudo npm config set user 0 && sudo npm install --global @dvcorg/cml
40+
sudo npm config set user 0 && sudo npm install --global 18 value with "quotes" and spaces
4141
sudo tee /usr/bin/cml.sh << 'EOF'
4242
#!/bin/sh
4343
export AWS_SECRET_ACCESS_KEY='0 value with "quotes" and spaces'
4444
export AWS_ACCESS_KEY_ID='1 value with "quotes" and spaces'
4545
export AWS_SESSION_TOKEN='2 value with "quotes" and spaces'
4646
47-
HOME="$(mktemp -d)" exec cml-runner \
47+
HOME="$(mktemp -d)" exec $(which cml-runner || echo "cml runner") \
4848
--name '10 value with "quotes" and spaces' \
4949
--labels '16 value with "quotes" and spaces' \
5050
--idle-timeout 11 \

iterative/testdata/script_template_cloud_azure.golden

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ if [ ! -f "$FILE" ]; then
3737
echo OK | sudo tee "$FILE"
3838
fi
3939

40-
sudo npm config set user 0 && sudo npm install --global @dvcorg/cml
40+
sudo npm config set user 0 && sudo npm install --global 18 value with "quotes" and spaces
4141
sudo tee /usr/bin/cml.sh << 'EOF'
4242
#!/bin/sh
4343
export AZURE_CLIENT_ID='3 value with "quotes" and spaces'
4444
export AZURE_CLIENT_SECRET='4 value with "quotes" and spaces'
4545
export AZURE_SUBSCRIPTION_ID='5 value with "quotes" and spaces'
4646
export AZURE_TENANT_ID='6 value with "quotes" and spaces'
4747
48-
HOME="$(mktemp -d)" exec cml-runner \
48+
HOME="$(mktemp -d)" exec $(which cml-runner || echo "cml runner") \
4949
--name '10 value with "quotes" and spaces' \
5050
--labels '16 value with "quotes" and spaces' \
5151
--idle-timeout 11 \

iterative/testdata/script_template_cloud_gcp.golden

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ if [ ! -f "$FILE" ]; then
3737
echo OK | sudo tee "$FILE"
3838
fi
3939

40-
sudo npm config set user 0 && sudo npm install --global @dvcorg/cml
40+
sudo npm config set user 0 && sudo npm install --global 18 value with "quotes" and spaces
4141
sudo tee /usr/bin/cml.sh << 'EOF'
4242
#!/bin/sh
4343
export GOOGLE_APPLICATION_CREDENTIALS_DATA='7 value with "quotes" and spaces'
4444
45-
HOME="$(mktemp -d)" exec cml-runner \
45+
HOME="$(mktemp -d)" exec $(which cml-runner || echo "cml runner") \
4646
--name '10 value with "quotes" and spaces' \
4747
--labels '16 value with "quotes" and spaces' \
4848
--idle-timeout 11 \

iterative/testdata/script_template_cloud_invalid.golden

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ if [ ! -f "$FILE" ]; then
3737
echo OK | sudo tee "$FILE"
3838
fi
3939

40-
sudo npm config set user 0 && sudo npm install --global @dvcorg/cml
40+
sudo npm config set user 0 && sudo npm install --global 18 value with "quotes" and spaces
4141
sudo tee /usr/bin/cml.sh << 'EOF'
4242
#!/bin/sh
4343
44-
HOME="$(mktemp -d)" exec cml-runner \
44+
HOME="$(mktemp -d)" exec $(which cml-runner || echo "cml runner") \
4545
--name '10 value with "quotes" and spaces' \
4646
--labels '16 value with "quotes" and spaces' \
4747
--idle-timeout 11 \

iterative/testdata/script_template_cloud_kubernetes.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
sudo systemctl is-enabled cml.service && return 0
33
export KUBERNETES_CONFIGURATION='8 value with "quotes" and spaces'
44

5-
HOME="$(mktemp -d)" exec cml-runner \
5+
HOME="$(mktemp -d)" exec $(which cml-runner || echo "cml runner") \
66
--name '10 value with "quotes" and spaces' \
77
--labels '16 value with "quotes" and spaces' \
88
--idle-timeout 11 \

iterative/utils/helpers.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,74 @@
11
package utils
22

33
import (
4+
"context"
5+
"fmt"
46
"os"
7+
"strings"
58

69
"github.com/aohorodnyk/uid"
10+
"github.com/blang/semver/v4"
11+
"github.com/google/go-github/v42/github"
712
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
813
)
914

15+
func GetCML(version string) string {
16+
// default latest if unset
17+
if version == "" {
18+
client := github.NewClient(nil)
19+
release, _, err := client.Repositories.GetLatestRelease(context.Background(), "iterative", "cml")
20+
if err != nil {
21+
// GitHub API failed
22+
return getNPMCML("@dvcorg/cml")
23+
}
24+
for _, asset := range release.Assets {
25+
if *asset.Name == "cml-linux" {
26+
return getGHCML(*asset.BrowserDownloadURL)
27+
}
28+
}
29+
}
30+
// handle semver
31+
ver, err := semver.Make(strings.TrimPrefix(version, "v"))
32+
if err == nil {
33+
return getSemverCML(ver)
34+
}
35+
// user must know best, npm install <string>
36+
if version != "" {
37+
return getNPMCML(version)
38+
}
39+
// original fallback, some error has forced this
40+
return getNPMCML("@dvcorg/cml")
41+
}
42+
43+
func getGHCML(v string) string {
44+
return fmt.Sprintf(`sudo mkdir -p /opt/cml/
45+
sudo curl --location --url %s --output /opt/cml/cml-linux
46+
sudo chmod +x /opt/cml/cml-linux
47+
sudo ln -s /opt/cml/cml-linux /usr/bin/cml`, v)
48+
}
49+
50+
func getNPMCML(v string) string {
51+
npmCML := "sudo npm config set user 0 && sudo npm install --global %s"
52+
return fmt.Sprintf(npmCML, v)
53+
}
54+
55+
func getSemverCML(sv semver.Version) string {
56+
directDownloadVersion, _ := semver.ParseRange(">=0.10.0")
57+
if directDownloadVersion(sv) {
58+
client := github.NewClient(nil)
59+
release, _, err := client.Repositories.GetReleaseByTag(context.Background(), "iterative", "cml", "v"+sv.String())
60+
if err == nil {
61+
for _, asset := range release.Assets {
62+
if *asset.Name == "cml-linux" {
63+
return getGHCML(*asset.BrowserDownloadURL)
64+
}
65+
}
66+
}
67+
}
68+
// npm install
69+
return getNPMCML("@dvcorg/cml@v" + sv.String())
70+
}
71+
1072
func MachinePrefix(d *schema.ResourceData) string {
1173
prefix := ""
1274
if _, hasMachine := d.GetOk("machine"); hasMachine {

0 commit comments

Comments
 (0)