1999 introduce versioneer (#59)

* Introduce versioneer package

to replace the naming.sh script in kairos-io/kairos

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement BootableName for bootable artifacts

also introduce Version and SoftwareVersion fields

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Refactor to introduce commondName

to be used with ContainerName

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement ContainerName and add missing tests

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Introduce NewArtifactFromJSON

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Introduce NewFromOSRelease

to be used within a Kairos image

See also discussion: https://github.com/kairos-io/kairos/discussions/2035

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Introduce 3 methods to find releases (TODO: implement them)

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Use existing OSRelease method and remove the new one

the existing method had to be adapted to accept and optional path to
the os-release file to allow the tests to pass a tmp file.

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Introduce TagList and some basic filtering of tags

also introduce RegistryInspector which finds tags from a container
registry for a specific repository.

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement OtherVersions method of TagList

to return different Kairos versions of the exact same artifact.

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* [WIP] Add TODOs for 2 more methods

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement Sorted() method on TagList

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement RSorted

and change OtherVersions test to ensure it also returns older versions too.

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement NewerVersions method

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Make json file pretty

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement OtherSoftwareVersions and NewerSoftwareVersions

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement NewerAnyVersions and OtherAnyVersions

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Make TagList a struct so that it has an "Artifact" field

Now the Artifact has a TagList method that returns a TagList which is
associated to the specific Artifact.

All methods of TagList are now available to the Artifact.

E.g.
tagList, _ := artifact.TagList("quay.io/kairos")
tagList.NewerAnyVersion(...)

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Use the field Artifact in TagList methods instead of needing an argument

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Fix linting errors

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Restructure files and introduce main.go for versioneer

to provide a user interface that will replace naming.sh script of the
kairos repository

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Fix imports

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement bootable-artifact-name cli command

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement BaseContainerName method

Signed-off-by: Dimitris Karakasilis <dimitris@spectrocloud.com>

* Create a wrapper command base-container-artifact-name

Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>

* Extract the cli command to the packag to be re-used in kairos-agent

Signed-off-by: Dimitris Karakasilis <dimitris@spectrocloud.com>

* Go back to original package structure

and just nest the cli

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Move the versioneer "main" package outside the tree

to allow it to be imported in kairos-agent

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Allow setting the cli flags using environment variables

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Implement os-release-variables command

to replace the logic in Earthly and Dockerfiles

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Fix test

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Fix TODO in Readme

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Dry the creation of the Artifact

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

---------

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
Signed-off-by: Dimitris Karakasilis <dimitris@spectrocloud.com>
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
Co-authored-by: Mauro Morales <mauro.morales@spectrocloud.com>
Co-authored-by: Dimitris Karakasilis <dimitris@spectrocloud.com>
This commit is contained in:
Dimitris Karakasilis 2023-12-05 15:46:08 +02:00 committed by GitHub
parent 9bbc110598
commit 29fc4851f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1678 additions and 19 deletions

17
bin/versioneer/main.go Normal file
View File

@ -0,0 +1,17 @@
package main
import (
"log"
"os"
"github.com/kairos-io/kairos-sdk/versioneer"
"github.com/urfave/cli/v2"
)
func main() {
app := &cli.App{Commands: versioneer.CliCommands()}
if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}

6
go.mod
View File

@ -21,7 +21,9 @@ require (
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/swaggest/jsonschema-go v0.3.62
github.com/twpayne/go-vfs/v4 v4.2.0
github.com/urfave/cli/v2 v2.26.0
github.com/zcalusic/sysinfo v1.0.1
golang.org/x/mod v0.10.0
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
@ -42,6 +44,7 @@ require (
github.com/containerd/continuity v0.4.2 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/docker/cli v23.0.5+incompatible // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/docker v23.0.5+incompatible // indirect
@ -73,15 +76,16 @@ require (
github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/swaggest/refl v1.3.0 // indirect
github.com/twpayne/go-vfs v1.7.2 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect
github.com/wayneashleyberry/terminal-dimensions v1.1.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.13.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.10.0 // indirect

23
go.sum
View File

@ -20,8 +20,6 @@ github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYew
github.com/MarvinJWendt/testza v0.5.2 h1:53KDo64C1z/h/d/stCYCPY69bt/OSwjq5KpFNwi+zB4=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek=
github.com/Microsoft/hcsshim v0.10.0-rc.8/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM=
github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA=
github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
@ -31,7 +29,7 @@ github.com/avast/retry-go v2.7.0+incompatible h1:XaGnzl7gESAideSjr+I8Hki/JBi+Yb9
github.com/avast/retry-go v2.7.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo=
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
github.com/bool64/dev v0.2.29 h1:x+syGyh+0eWtOzQ1ItvLzOGIWyNWnyjXpHIcpF2HvL4=
github.com/bool64/dev v0.2.31 h1:OS57EqYaYe2M/2bw9uhDCIFiZZwywKFS/4qMLN6JUmQ=
github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 h1:xz6Nv3zcwO2Lila35hcb0QloCQsc38Al13RNEzWRpX4=
@ -42,8 +40,6 @@ github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaD
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/containerd v1.7.5 h1:i9T9XpAWMe11BHMN7pu1BZqOGjXaKTPyz2v+KYOZgkY=
github.com/containerd/containerd v1.7.5/go.mod h1:ieJNCSzASw2shSGYLHx8NAE7WsZ/gEigo5fQ78W5Zvw=
github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4=
github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8=
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
@ -52,6 +48,7 @@ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -215,14 +212,12 @@ github.com/qeesung/image2ascii v1.0.1/go.mod h1:kZKhyX0h2g/YXa/zdJR3JnLnJ8avHjZ3
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.0 h1:uIkTLo0AGRc8l7h5l9r+GcYi9qfVPt6lD4/bhmzfiKo=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@ -237,14 +232,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7o2xQ=
github.com/swaggest/jsonschema-go v0.3.59 h1:BoPhtNvWbZRo1Wl6xvR3g6WL01COJTOAs6vMUnZgocM=
github.com/swaggest/jsonschema-go v0.3.59/go.mod h1:5WFFGBBte5JAWAV8gDpNRJ/tlQnb1AHDdf/ghgsVUik=
github.com/swaggest/jsonschema-go v0.3.62 h1:eIE0aRklWa2eLJg2L/zqyWpKvgUPbq2oKOtrJGJkPH0=
github.com/swaggest/jsonschema-go v0.3.62/go.mod h1:DYuKqdpms/edvywsX6p1zHXCZkdwB28wRaBdFCe3Duw=
github.com/swaggest/refl v1.2.0 h1:Qqqhfwi7REXF6/4cwJmj3gQMzl0Q0cYquxTYdD0kvi0=
github.com/swaggest/refl v1.2.0/go.mod h1:CkC6g7h1PW33KprTuYRSw8UUOslRUt4lF3oe7tTIgNU=
github.com/swaggest/refl v1.3.0 h1:PEUWIku+ZznYfsoyheF97ypSduvMApYyGkYF3nabS0I=
github.com/swaggest/refl v1.3.0/go.mod h1:3Ujvbmh1pfSbDYjC6JGG7nMgPvpG0ehQL4iNonnLNbg=
github.com/twpayne/go-vfs v1.7.2 h1:ZNYMAXcu2Av8c109USrSGYm8dIIIV0xPlG19I2088Kw=
@ -252,6 +243,8 @@ github.com/twpayne/go-vfs v1.7.2/go.mod h1:1eni2ntkiiAHZG27xfLOO4CYvMR4Kw8V7rYiL
github.com/twpayne/go-vfs/v4 v4.2.0 h1:cIjUwaKSCq0y6dT+ev6uLSmKjGTbHCR4xaocROqHFsE=
github.com/twpayne/go-vfs/v4 v4.2.0/go.mod h1:zEoSYKpoOQmqu2Rrjclu2TlDEK+I5ydlh58sGdPKNYI=
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI=
github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
github.com/wayneashleyberry/terminal-dimensions v1.1.0 h1:EB7cIzBdsOzAgmhTUtTTQXBByuPheP/Zv1zL2BRPY6g=
@ -259,6 +252,8 @@ github.com/wayneashleyberry/terminal-dimensions v1.1.0/go.mod h1:2lc/0eWCObmhRcz
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -299,8 +294,6 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=

View File

@ -4,6 +4,7 @@ import (
"bufio"
"bytes"
"encoding/json"
"errors"
"fmt"
"image"
"net"
@ -58,8 +59,21 @@ func UUID() string {
return fmt.Sprintf("%s-%s", id, hostname)
}
func OSRelease(key string) (string, error) {
release, err := godotenv.Read("/etc/os-release")
// OSRelease finds the value of the specified key in the /etc/os-release file
// or, if a second argument is passed, on the file specified by the second argument.
// (optionally file argument is there for testing reasons).
func OSRelease(key string, file ...string) (string, error) {
var osReleaseFile string
if len(file) > 1 {
return "", errors.New("too many arguments passed")
}
if len(file) > 0 {
osReleaseFile = file[0]
} else {
osReleaseFile = "/etc/os-release"
}
release, err := godotenv.Read(osReleaseFile)
if err != nil {
return "", err
}
@ -69,7 +83,7 @@ func OSRelease(key string) (string, error) {
// We try with the old naming without the prefix in case the key wasn't found
v, exists = release[key]
if !exists {
return "", fmt.Errorf("key not found")
return "", fmt.Errorf("%s key not found", kairosKey)
}
}
return v, nil

7
versioneer/README.md Normal file
View File

@ -0,0 +1,7 @@
_ -eer suffix : (in nouns) a person concerned with a particular thing` (https://www.oxfordlearnersdictionaries.com)
Versioneer is a library and a wrapping cli that is concerned with everything related to artifact names and versions in Kairos.
There is a standalone CLI in the bin/versioneer directory of thie repository. It's also embedded in kairos-agent
as a command "kairos-agent versioneer". This allows to use it wherever we have kairos-agent available (e.g. within a Kairos OS)
or inside Earthly (by running the standalone cli in an Earthly target).

View File

@ -0,0 +1,319 @@
[
"sha256-bc57857ffd4c3cbcd454b3efd4fcdce104e84efb46a4b79c2676ba215fa30f6c.sbom",
"sha256-53e6dd6ea9969dbe3fc8d3717a7186fb5a55dfb7597f22c74d6f4f6aa01fc725.sig",
"sha256-c1075897dbfb4d128b8ef41d7c844729bd7df78681af85390f7c3fee34249957.sbom",
"sha256-12c0aee581b6d4158f2733616a759624641ea80535a8583f13d9ae15b7ea27d2.sig",
"sha256-bc57857ffd4c3cbcd454b3efd4fcdce104e84efb46a4b79c2676ba215fa30f6c.att",
"sha256-c1075897dbfb4d128b8ef41d7c844729bd7df78681af85390f7c3fee34249957.att",
"sha256-674c65d0a67ac76d3a7cf32e534f41a6e24b470dba185cc1d047c4da0a100499.sbom",
"sha256-ab9cf9a4433c39d1de73678dff74a2be25ca29f1b56f24d579160b137d789d9f.sig",
"sha256-b1bad504a1ba8a95b1a144c5979ed42121eb394011cf52281dde4ede5ae60687.sbom",
"sha256-bce336e737eb1c7491004c7fc77a424cca4d34ac34c75bee8ca3c46cfb752ae8.sig",
"sha256-674c65d0a67ac76d3a7cf32e534f41a6e24b470dba185cc1d047c4da0a100499.att",
"sha256-b1bad504a1ba8a95b1a144c5979ed42121eb394011cf52281dde4ede5ae60687.att",
"sha256-daac44f67535565b171e077a7401b659a97cc8d6440c8a60c697e9bebc1a1210.sbom",
"sha256-08f67e61de3f5a88740b12f65e3f97a2e99bf41312215b91a5145caaa85a8dff.sig",
"sha256-daac44f67535565b171e077a7401b659a97cc8d6440c8a60c697e9bebc1a1210.att",
"sha256-266fce4b605b4a4b2d9bd3a100ee5adee3278dbef1ba011959e4c6550b888cf4.sbom",
"sha256-1134ede6b3bf8cd9f9f46f702260536952562791c31cee42693da7a97e77885b.sbom",
"sha256-02d452d47d4e32a8570c2d25b1dd90e9379b4d54cef6cb8e647fe7b7fe595784.sbom",
"sha256-138317a2fd06775deff30a9f844986bcff54f3b2ad214b56875f36f6cf469192.sbom",
"leap-15.5-core-arm64-generic-43dabf5",
"sha256-b692dacbb4bc08b8f6de53abe946adacd94a0a95e33c8f549f0aaa0942cc54df.sbom",
"sha256-b5642024966464e50f0bddd1ea85a8bc83707560a1ab370469e57d2cb1f62377.sig",
"sha256-5295aa0649c90265aaac626acd17c91e5b6af0fc83fc49f073a85cbd25f5e75b.sbom",
"sha256-a711db90351389a5e6c85e2f97d36f1fe56dcce39abeb02d7bfbea03387fa55a.sig",
"sha256-8d7642cb1503fb07ed25b9ce29369da1e0bbd53f173b8428f40c5e7f4dafbeb8.sbom",
"sha256-4c136a76ef9cf0856e99d0de35f2102b92d9023916e93bdaceea6bee54e055e2.sig",
"sha256-8d7642cb1503fb07ed25b9ce29369da1e0bbd53f173b8428f40c5e7f4dafbeb8.att",
"sha256-c2ed85b4d177bd1ebcb82ee17ac87f7ae47002b151a41eef9b72a89f36125d90.sbom",
"sha256-329f950ff973dd346a750ce27c54de25c340c0e131efdd8d6cef80c60e695954.sig",
"sha256-c2ed85b4d177bd1ebcb82ee17ac87f7ae47002b151a41eef9b72a89f36125d90.att",
"sha256-4441932660777023d722f0abd6cfbeb0b97f2ebc123c16d99eb511edb5b38164.sbom",
"sha256-fa1b5f306b5d2387e1243dc86d31bbd5cbcd49dcac24dfd8af22992aa9c8c413.sig",
"sha256-4441932660777023d722f0abd6cfbeb0b97f2ebc123c16d99eb511edb5b38164.att",
"sha256-6ea62d313a0c7103794dd6529a9fcd461f8444ad3ff4f509e710e117fa69a5aa.sbom",
"sha256-f809f828c0cf9d63a91b49b74665b55d5d056e40f5967ec758bf768396d8d71d.sig",
"sha256-6ea62d313a0c7103794dd6529a9fcd461f8444ad3ff4f509e710e117fa69a5aa.att",
"sha256-fbb215df2609adfe1cad720a30d0dc561af8d1e664f31f08d466086b72d6843c.sbom",
"sha256-4558c6c4c860e6f20176f96c33858429208d94ac0a7f3fbd6b1d4e0521a03219.sig",
"sha256-fbb215df2609adfe1cad720a30d0dc561af8d1e664f31f08d466086b72d6843c.att",
"sha256-db6227644b45aa49b22fc705556da901e43f8b9ac7137e334c814baee6aca46f.sbom",
"sha256-4e16fbe00b3863793fe8e004c872d80d52ff7c8168f7d395a4fc5d257eb3caea.sig",
"sha256-db6227644b45aa49b22fc705556da901e43f8b9ac7137e334c814baee6aca46f.att",
"sha256-55866a3b9ba1dae273d49281a7ce3948e80ff9f2833bcb5b06f7e0f37827285c.sbom",
"sha256-05826f2e564971b2b7a1bc010065f60aa49d7fe9ed2b91be76fa1a2b4f14feaa.sig",
"sha256-55866a3b9ba1dae273d49281a7ce3948e80ff9f2833bcb5b06f7e0f37827285c.att",
"sha256-75f13538abf023945ae3634ec5d72b1ce49714ecd246b9ec0d920e5af308f81a.sbom",
"sha256-d75b052624d00853b44f4839fed973fd173c31587af56c652b21855c12b8ce0a.sig",
"sha256-75f13538abf023945ae3634ec5d72b1ce49714ecd246b9ec0d920e5af308f81a.att",
"sha256-94870aae76d698da12affe26bd79dfb37484cdf78a60c8c05be004b9dae49549.sbom",
"sha256-a057b02932f3959aac4083ffcddbe9f3df343b7d0cf26961a9132c9116480a60.sig",
"sha256-94870aae76d698da12affe26bd79dfb37484cdf78a60c8c05be004b9dae49549.att",
"leap-15.5-core-arm64-generic-v2.4.2-rc1",
"sha256-c3114f3d722a8bde5a4e3ff678d8a36eeb03fb05c1d5dbb0387126cec17db591.sbom",
"sha256-e53bed40882b69aceab2990e95e882448a4eaf97b2d7d254fcfa5127c9885da7.sig",
"sha256-c3114f3d722a8bde5a4e3ff678d8a36eeb03fb05c1d5dbb0387126cec17db591.att",
"sha256-ce8731a1cfe7e0e4b1baaf2003fae08c0fadc747c46f778e5775bd757cec70af.sbom",
"sha256-8f8ef9478430bfb9bb3defa5ac64c0722bdbfe8aa41be4c3289057e55d200615.sig",
"sha256-ce8731a1cfe7e0e4b1baaf2003fae08c0fadc747c46f778e5775bd757cec70af.att",
"sha256-5afcbaef72a0719b66142ee5e298d13821e44f7280aeb386cfbb0d7f5779f2c2.sig",
"sha256-4f025944c90bc27141cf52900113592561791c4190c361c688128e4ba6d626cd.sig",
"sha256-a30ef1861f0ed93187487de75ecd2de882fbae8fefc24ff6257471aebf4d5770.sig",
"sha256-e9a946ef23d996676aac67c40655027da4629ac2d4b9bef39111ec7fd84f66d9.sig",
"sha256-258d90c207232f8bce97d54b5930fa63a5011c6a773de2cebe0bb80a8a71ceb0.sbom",
"sha256-dad10579dced98f7d4ecfbf8d598bfcbb2d4880150a15c4e2388d71cc7f3057e.sig",
"sha256-258d90c207232f8bce97d54b5930fa63a5011c6a773de2cebe0bb80a8a71ceb0.att",
"sha256-11e1989e7567573cd49eba37acd2188015e370016401ba641ddb257ee9a64a5f.sbom",
"sha256-d014f16eb0f78097169099fdaaf9f7a2447b6412e2a2ecc04ce6c03c029c4d10.sig",
"sha256-11e1989e7567573cd49eba37acd2188015e370016401ba641ddb257ee9a64a5f.att",
"sha256-11218f3bf9506f19fb2a56d974d46ff275ed31b7076ef0ee047ea378c007128d.sbom",
"sha256-a9770c4356c650a4c5c5eeb171675f13cf78f69130753eeb331980255d5ca636.sig",
"sha256-11218f3bf9506f19fb2a56d974d46ff275ed31b7076ef0ee047ea378c007128d.att",
"sha256-e2df7e43049dc747a0003b97d206c7d4e23efb0f568ae5948369d33557d6306e.sbom",
"sha256-471efb61b3b48942815debd13a5d435cecc388f0a75e59cd99f7423b8a511081.sig",
"sha256-e2df7e43049dc747a0003b97d206c7d4e23efb0f568ae5948369d33557d6306e.att",
"sha256-84008cb5cea000d77e9235728126edf11414d55efeb7a160bd3bd5f5dde4e4fa.sbom",
"sha256-cf85fc2e16644f7281358b26b0740e7e35fed7be5ed86fd6dee3449d8a87dbe8.sig",
"sha256-21740df6306c0d0a9823620f468b4b74dd37680b5cc4e52e5a473e1946f8688d.sig",
"sha256-84008cb5cea000d77e9235728126edf11414d55efeb7a160bd3bd5f5dde4e4fa.att",
"sha256-07f9f176338191e0d51a5ed62a1e3ee0228f5c1193c0e2aac3e0e84a0673c39d.sig",
"sha256-ad72aa2538b916dc87c620b59076041c9617bda1c3de723662ae001813e5c434.sig",
"sha256-3565ff6cdc638b5acbe84bb9159b4947124008e0cc646101eac2072537054703.sig",
"sha256-2611392c33936b4e0dd38e9629061ef706ebe1100d79ca3f274b38f275b03252.sig",
"sha256-1032bed841dd53da78148858744f66d5e9aecf0369c82273470fc6f018a8d092.sig",
"sha256-2c677fc4fc5e5c4d8c3b320ad03e72d9a65a96d3e7df1519a4735cbd9411afb1.sig",
"sha256-32583a14298c2edc525999c9b6135552b12634801f422273db462c48a44795a9.sig",
"sha256-ef6fefc97e73883b65ad5360ff17b225484b7066204eb42a8353d76214650ca3.sig",
"sha256-1ac4c7bfbe767aa3e854614dd402114498dd017466bce6417d68c31e78a4d9ed.sig",
"sha256-f4590445e8cf73d725b2382f26ac386e929e573eccb731792c0449df53524cf4.sig",
"sha256-af3e04af5c7ca45840a239ab7a0021e760018dd4874e144957d34d5f33754311.sbom",
"sha256-886a64488c1ae9f19e47d50b915aba50d3e66cca8c374664e676cdfdaa0f3d34.sig",
"sha256-af3e04af5c7ca45840a239ab7a0021e760018dd4874e144957d34d5f33754311.att",
"tumbleweed-core-amd64-rpi4-v2.4.2-rc1",
"sha256-103f63ae56542eed90a8ea4228433e04367e90e960c1b2ea3a7eacc9f1575b22.sbom",
"sha256-dd1fb33a9a0a058aa61d25b9b5b26ab13570810480ef8b8ab9123113932f127a.sig",
"sha256-103f63ae56542eed90a8ea4228433e04367e90e960c1b2ea3a7eacc9f1575b22.att",
"sha256-2646913d66a8c48957420a813d6e11a0706a1683e1a3115a9f43111ea5a0a819.sbom",
"sha256-33dd43fa535f58c098bb17d293f4f9cc84c029a548ef4a73d551249f53d5bf5f.sig",
"sha256-2646913d66a8c48957420a813d6e11a0706a1683e1a3115a9f43111ea5a0a819.att",
"sha256-34626b81eb021b295e06338b83662ae23e51779d6e89dcfcb158b73e326597cb.sig",
"leap-15.5-core-amd64-rpi4-v2.4.2-rc1",
"sha256-2f3308eab32bf5c8c599276d4bad73445873542193ff9c399577dbb2e904ac10.sbom",
"sha256-674bf0d64c60cbc9c63b71d30a2fd87dc1b3af9e3be2c06710ba239815b53e58.sig",
"sha256-2f3308eab32bf5c8c599276d4bad73445873542193ff9c399577dbb2e904ac10.att",
"sha256-8c83459d2e13e3f21051f24cb06a3a1bfddec20d2df7c03fad8f8a94e05834fc.sbom",
"sha256-855a7e086cbee3293416e6878486765558ca524c39d9d0cba09178befadef9c2.sig",
"sha256-8c83459d2e13e3f21051f24cb06a3a1bfddec20d2df7c03fad8f8a94e05834fc.att",
"sha256-c0273f2afd2cba509cc4cb87dd633e05fd37eed1ae58550ba3f5db0ec7f90521.sbom",
"sha256-a38f64c6626aa2beb6d197540d50184c889582048214d37b3e13d1146553350b.sig",
"sha256-c0273f2afd2cba509cc4cb87dd633e05fd37eed1ae58550ba3f5db0ec7f90521.att",
"leap-15.5-core-arm64-generic-v2.4.2-rc1-k3sv1.28.2-k3s1",
"leap-15.5-standard-arm64-generic-v2.4.2-rc1-k3sv1.28.2-k3s1",
"leap-15.5-core-arm64-rpi4-v2.4.2-rc1",
"sha256-6d7dc108432ec2b004aa256b55f524502c270f11cd1f50358d86db6ef228711b.sig",
"leap-15.5-core-arm64-rpi4-v2.4.2-rc1-img",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.28.2-k3s1",
"sha256-4a0071471b7871a48cf5f168ab012bff3df097f3e080b9d182f65c252f6a7062.sig",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.28.2-k3s1-img",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.26.9-k3s1",
"sha256-45f14e8358044e4122e4f259942dc40686c869ded048e98ffda750ebade00a9e.sig",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.27.6-k3s1",
"sha256-a8308436d9b5bef094f2d6b3bb5832e687b29a951a748256b94dcc6d6906e6a5.sig",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.26.9-k3s1-img",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.28.2-k3s1",
"sha256-dc13f00afe8414f3e736c5735139190b84cb00a82a4cfa7572cf2b6dce56e02e.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.26.9-k3s1",
"sha256-38eb32315e30ab4d926ba61ba8d7a85bb2c9c05e9cd4660f181bb3f9df809ba1.sig",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.27.6-k3s1-img",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.28.2-k3s1-img",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.26.9-k3s1-img",
"tumbleweed-core-arm64-rpi4-v2.4.2-rc1",
"sha256-5cc0764ac2e7893fbb1246967dcef6d53736fcc86c1c436b976c3aab26824368.sig",
"tumbleweed-core-arm64-rpi4-v2.4.2-rc1-img",
"leap-15.5-standard-amd64-generic-v2.4.2-rc1-k3sv1.26.9-k3s1",
"sha256-97ac9cbfbdd4c00bdf660d9e283d39c0eb0e13353185dbcdd80884a8d64a65e6.sig",
"tumbleweed-standard-amd64-generic-v2.4.2-rc1-k3sv1.27.6-k3s1",
"sha256-cc0804d6b236251efba898b3d48fc20c382ea95ad04ee012be2301bfe099d106.sig",
"tumbleweed-standard-amd64-generic-v2.4.2-rc1-k3sv1.28.2-k3s1",
"sha256-b026a576518a359c13105da8ffe756b6bb79ff14d2def5bd1f8f5d405dcdbf79.sig",
"leap-15.5-standard-amd64-generic-v2.4.2-rc1-k3sv1.27.6-k3s1",
"sha256-e6378474f40ec236e85917656bc8888ba9251a4befd106cba3c58ac92bc5361b.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.27.6-k3s1",
"sha256-269fea1387752fad685871d5451ccbc9c89984dff88fbabdfb08db736c8d2ba3.sig",
"leap-15.5-standard-amd64-generic-v2.4.2-rc1-k3sv1.28.2-k3s1",
"sha256-410f54ed0941278fc27d795f271e27e6d5fd44a804593f2c22b1e77f18ede8c1.sig",
"tumbleweed-standard-amd64-generic-v2.4.2-rc1-k3sv1.26.9-k3s1",
"sha256-4767a56c632856f09f6cf113ac63c2227fb00522e14914b70c067d3eb6962f3a.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc1-k3sv1.27.6-k3s1-img",
"leap-15.5-core-amd64-generic-v2.4.2-rc1",
"sha256-e74d0015864017f13f6d0b609540877ed334c6f963cebd8a20fe251e8c9b6095.sbom",
"sha256-efa3d930ba47b6526013adf1d9ea290589968e9fa15309ff8ce4e9e8f2acd149.sig",
"sha256-e74d0015864017f13f6d0b609540877ed334c6f963cebd8a20fe251e8c9b6095.att",
"sha256-fbbb9e1cb1a75b6fc1cad3d623fee05a5d548db9bb6c888ea8582ee702969ecb.sbom",
"sha256-b2cec01b24ca756ff0af6686ac12b3ba55747ebd0ec1a7ae1885a9a0b264a12c.sig",
"sha256-fbbb9e1cb1a75b6fc1cad3d623fee05a5d548db9bb6c888ea8582ee702969ecb.att",
"tumbleweed-core-amd64-generic-v2.4.2-rc1",
"sha256-1af5f50ce6612b1cd9feb5ea692f6021a0b61ea9ef4704c823d10003f360f146.sbom",
"sha256-384be36e5182d5331564165c4d7d63babbb0edb68ffd47c70e0f588ef1065557.sig",
"sha256-1af5f50ce6612b1cd9feb5ea692f6021a0b61ea9ef4704c823d10003f360f146.att",
"sha256-c1624f5506a0ab131e8fdb8aaa477f160b4b4fcd2e4f689d648147ac34e4b69c.sbom",
"sha256-0ca1b598fea000b953db684af14f5c38f8a4a70c4765565d09f7227ff7a29e97.sig",
"sha256-c1624f5506a0ab131e8fdb8aaa477f160b4b4fcd2e4f689d648147ac34e4b69c.att",
"sha256-152da50cd68a97fa3b9eab8a8a1b27ecbab2c6ace837f59795cf4a115eea19f9.sbom",
"sha256-66a1e906398bb0d471c4ff4cfbbf5f40a984604e0d2e7dedca5183993abd7dba.sig",
"sha256-152da50cd68a97fa3b9eab8a8a1b27ecbab2c6ace837f59795cf4a115eea19f9.att",
"tumbleweed-core-amd64-generic-v2.4.2-rc2",
"sha256-a2181a745c4a008b42bd52a707f0e3c17964b039f1614a9b8ea59fe27c922a18.sbom",
"sha256-7ad17fca0d79c261ee0da6ed57afbf8d2d2299bd69e1d583b7ebb6de9f5f8b91.sig",
"sha256-a2181a745c4a008b42bd52a707f0e3c17964b039f1614a9b8ea59fe27c922a18.att",
"leap-15.5-core-amd64-generic-v2.4.2-rc2",
"sha256-92a26e7cd3509ab0dce9c54465579d005431e38eceb1780637c0c79d92267eb4.sbom",
"sha256-b7c84cacbae4c0be91c3f01587ee93f03525cc1c79edd84e42f9b8f8e650f03a.sig",
"sha256-92a26e7cd3509ab0dce9c54465579d005431e38eceb1780637c0c79d92267eb4.att",
"leap-15.5-core-arm64-generic-v2.4.2-rc2-k3sv1.28.2-k3s1",
"leap-15.5-standard-arm64-generic-v2.4.2-rc2-k3sv1.28.2-k3s1",
"leap-15.5-core-arm64-rpi4-v2.4.2-rc2",
"sha256-14085eff1627290f2c75ce49630e90818014aab93d3067403513731a02035bcf.sig",
"tumbleweed-core-arm64-rpi4-v2.4.2-rc2",
"sha256-58ead00f6cc8a2e799b79c4c82072dffd78a6d3f908104c3beae7d5c1353c29f.sig",
"leap-15.5-core-arm64-rpi4-v2.4.2-rc2-img",
"tumbleweed-core-arm64-rpi4-v2.4.2-rc2-img",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.28.2-k3s1",
"sha256-0a42785f540e5027c9975c0dc5d1a769aef869191866a78dcac43a9191488988.sig",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.28.2-k3s1-img",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.27.6-k3s1",
"sha256-a038ea55f1ac8a5308a83d2ff7fb9ced84e64863a03eb9249801dd0f3798ff24.sig",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.27.6-k3s1-img",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.26.9-k3s1",
"sha256-d3d7169d1798726c7355128c4e766d4b30f3e823f72a99785e68197ae367ffac.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.26.9-k3s1",
"leap-15.5-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.26.9-k3s1-img",
"sha256-359791b032c5814c9a33c37d02297b20f9259fe06df851197eeaa898ea551a51.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.26.9-k3s1-img",
"leap-15.5-standard-amd64-generic-v2.4.2-rc2-k3sv1.28.2-k3s1",
"sha256-8d77c1767667cf5109237c7bf696e0984f2903169a5352210b5fb1aaf658545b.sig",
"leap-15.5-standard-amd64-generic-v2.4.2-rc2-k3sv1.26.9-k3s1",
"sha256-0533b5df4dcf40e9018d805b0d2bab9dc47a41f831760fe3e283a5599c4aa22d.sig",
"leap-15.5-standard-amd64-generic-v2.4.2-rc2-k3sv1.27.6-k3s1",
"sha256-6da280b51ecc4b86afb0569ade05cec52138e96018559eee114256598c3325cd.sig",
"tumbleweed-standard-amd64-generic-v2.4.2-rc2-k3sv1.28.2-k3s1",
"sha256-e7593d2ee82e8334f498eb33746196a1842e863a4be2d872c98c40f6534d2469.sig",
"tumbleweed-standard-amd64-generic-v2.4.2-rc2-k3sv1.27.6-k3s1",
"sha256-a63c6ebea818ad76d566a415e6094b9665870d1f3aedda44d04503ca9bf8e7f6.sig",
"tumbleweed-standard-amd64-generic-v2.4.2-rc2-k3sv1.26.9-k3s1",
"sha256-b1204893b0e271bf58dc3b0dab12524b417fe707b4d3bd22020ff68c3cf0e3e6.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.28.2-k3s1",
"sha256-af07d7cf655f98d279b987557bee199e1dc04dc0c7c24d5f8eb089cd30d9efc3.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.28.2-k3s1-img",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.27.6-k3s1",
"sha256-4b0e2bd304e372ee337f62b9c4e29f351e258955496e52eb6d963f2dee698947.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-rc2-k3sv1.27.6-k3s1-img",
"sha256-0fa7594ee825709b470b01b731e2c6e0c1c0dd9411e2263479b3403209a45bf9.sbom",
"sha256-17ab9dad7bda0edecd43e4963907a61444f853e246fa15b0348cd56b287b4ab7.sig",
"sha256-0fa7594ee825709b470b01b731e2c6e0c1c0dd9411e2263479b3403209a45bf9.att",
"sha256-93979fc4d4c6696f93c3c1d1b8b8ce17426f9be129cb599a0909954172ada251.sbom",
"sha256-0565fda0fd7726f251e47eb6951096e1d4643e159d9488217017c2358982bee1.sig",
"sha256-93979fc4d4c6696f93c3c1d1b8b8ce17426f9be129cb599a0909954172ada251.att",
"sha256-302489f1e969ed1e979ad28adc1bb297e495f9f0cebcb8f37c4154554125f4ac.sbom",
"sha256-30435bc1464317dd93d781207a28a99eb0b7a76a189a2adf49d041ee7932118f.sig",
"sha256-302489f1e969ed1e979ad28adc1bb297e495f9f0cebcb8f37c4154554125f4ac.att",
"sha256-95d4061509ccf90d5d4ca49d4f3889de55eccc12a9727aa6babac981f530a218.sbom",
"sha256-5ea87d9caa710633f64855f4ed2c8853b1813d7519899d767806e2e2d0ae5016.sig",
"sha256-95d4061509ccf90d5d4ca49d4f3889de55eccc12a9727aa6babac981f530a218.att",
"leap-15.5-standard-arm64-generic-v2.4.2-k3sv1.28.2-k3s1",
"leap-15.5-core-arm64-generic-v2.4.2-k3sv1.28.2-k3s1",
"leap-15.5-core-arm64-rpi4-v2.4.2",
"sha256-310e1539b336a166218512ae7a5fe955050f3ab8335782ca8a958110529ef828.sig",
"leap-15.5-core-arm64-rpi4-v2.4.2-img",
"leap-15.5-standard-arm64-rpi4-v2.4.2-k3sv1.27.6-k3s1",
"sha256-9f594ec4f7bc11cf24cd8e8918e9477f9f0b13233901ff83f48f4787a3271ded.sig",
"leap-15.5-standard-arm64-rpi4-v2.4.2-k3sv1.28.2-k3s1",
"sha256-8ed16ff537b43e8e1acdb8f97b7b7c1316a13445cad0b3f822ec7fa26fce0632.sig",
"leap-15.5-standard-arm64-rpi4-v2.4.2-k3sv1.26.9-k3s1",
"sha256-16eee465953bd18acdd5577ad755dc1347f51f4ae0a6578d8914b6d2a27a80f2.sig",
"leap-15.5-standard-arm64-rpi4-v2.4.2-k3sv1.27.6-k3s1-img",
"leap-15.5-standard-arm64-rpi4-v2.4.2-k3sv1.28.2-k3s1-img",
"leap-15.5-standard-arm64-rpi4-v2.4.2-k3sv1.26.9-k3s1-img",
"tumbleweed-core-arm64-rpi4-v2.4.2",
"sha256-a1474461010b7ef9fafd1312f41a7bebb20e160042d69a64225148fa1329b6ce.sig",
"tumbleweed-core-arm64-rpi4-v2.4.2-img",
"leap-15.5-core-amd64-generic-v2.4.2",
"sha256-4338e339cf09302701d8147535163cb91b24a760995f46c636abdf46648c8869.sbom",
"sha256-8c0c00bdc0d1c208672932ce19ac834535f30583dfb2a0b969384a64035faa4e.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-k3sv1.27.6-k3s1",
"sha256-42a194370bf6c0dcb91f597e255b5d15e477606924993cce408f46621e64e226.sig",
"sha256-4338e339cf09302701d8147535163cb91b24a760995f46c636abdf46648c8869.att",
"tumbleweed-standard-arm64-rpi4-v2.4.2-k3sv1.28.2-k3s1",
"sha256-bb4d603d527ab64b726a57f1464fea43a3a3b95acb2f6bbbce0343a5947043bc.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-k3sv1.27.6-k3s1-img",
"tumbleweed-standard-arm64-rpi4-v2.4.2-k3sv1.28.2-k3s1-img",
"tumbleweed-core-amd64-generic-v2.4.2",
"sha256-dd115060300b2b92b4b143d661c2b863f0bcb55075eeb11cc9d385ff09cae171.sbom",
"sha256-bc3d1b366ffdf9be0f59b4ecc34186ac17c6655bce4b42e667391db0e64adcc3.sig",
"sha256-dd115060300b2b92b4b143d661c2b863f0bcb55075eeb11cc9d385ff09cae171.att",
"leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.27.6-k3s1",
"sha256-92d8e1a6193afc0f901abca15b47578d434dd7dc236ca03bc87983d66247aafe.sig",
"leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.26.9-k3s1",
"sha256-92f879a5523a43744c7986a742458d313c70ffaaabad7a743380705a91d984a8.sig",
"tumbleweed-standard-amd64-generic-v2.4.2-k3sv1.28.2-k3s1",
"sha256-6cb2d4d56d444370f548cca032c8c60abc7341f7fcb6893aac3e09a4bf7c1e52.sig",
"tumbleweed-standard-amd64-generic-v2.4.2-k3sv1.27.6-k3s1",
"sha256-9486eec5b57e50cd6828b148fd5707d06f4a8395f55df4d24d5293e1ef26f6e1.sig",
"leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.28.2-k3s1",
"sha256-7de8e9476565a32f37dfebfe3c6504260a8b9967695b8f68a2c0f93973799ee7.sig",
"tumbleweed-standard-amd64-generic-v2.4.2-k3sv1.26.9-k3s1",
"sha256-2299ed45c98a35b69b7ef5c6b8f57383a99e4c07660b4aacb35bfc276bd5446f.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-k3sv1.26.9-k3s1",
"sha256-22fe02a367a5effad5689c408145dd21221e8fbd68e768920531a10477d9845f.sig",
"tumbleweed-standard-arm64-rpi4-v2.4.2-k3sv1.26.9-k3s1-img",
"sha256-b1a375b8b24b5591b36630e19c30c9c4bfe8739e13fad26f2fa39a622dc8b4ab.sbom",
"sha256-45b1fb8edd0ba64896df31e46307c306dd739164fc3776e55051e689a130cecf.sig",
"sha256-b1a375b8b24b5591b36630e19c30c9c4bfe8739e13fad26f2fa39a622dc8b4ab.att",
"sha256-0508b39d26de23436a7a9f518d00af03addd460d63d1b3e9e2116168bf41a61c.sbom",
"sha256-de13874f4d0939d69524190791b1581d5662bd76b0737064754a32e8544ec768.sig",
"sha256-0508b39d26de23436a7a9f518d00af03addd460d63d1b3e9e2116168bf41a61c.att",
"sha256-dbc17c251e45d169958d585a3fdc32465f50469b7f81006f356e150204962730.sbom",
"sha256-c9a532043c0c44051c33441b023b36e0d2a67c923f8961f89ccd2cb028f842a5.sig",
"sha256-dbc17c251e45d169958d585a3fdc32465f50469b7f81006f356e150204962730.att",
"sha256-2b209e0cf99cfa44b96bd72bfc75e08580f4e46597d2bacda57de1f21e88dcbc.sbom",
"sha256-90c5c29b2ecb06e4af4d58641f682092ed28948f7bab7f2f80b8404ab839c8f7.sig",
"sha256-2b209e0cf99cfa44b96bd72bfc75e08580f4e46597d2bacda57de1f21e88dcbc.att",
"sha256-8d74e4a52c1dd0978e81a8c17900b73af87b8050f41503baa9d8fd4f598bc5ff.sbom",
"sha256-df0128f79fa5fbafb81fe25f1825534d1eaeb451bea90ae557aa7d1cfc37b71d.sig",
"sha256-8d74e4a52c1dd0978e81a8c17900b73af87b8050f41503baa9d8fd4f598bc5ff.att",
"sha256-efd04b3f970aff965bf0f0ecbd568233931a422fee4f7b894b0c501b31700246.sbom",
"sha256-23547d9d845efdef5cfb14e85a0b899cc85ce07214f9b8a9d77b7d72b59e7f05.sig",
"sha256-efd04b3f970aff965bf0f0ecbd568233931a422fee4f7b894b0c501b31700246.att",
"sha256-93b4531dc907523d6c1bd0561d5644ff49a4d505182e7f61879c00de7908f86d.sbom",
"sha256-4d19e9a53bb156e93f8979a826900c4e1c0b387dea6d217fc09dd7ca5d7d984c.sig",
"sha256-93b4531dc907523d6c1bd0561d5644ff49a4d505182e7f61879c00de7908f86d.att",
"sha256-a7352425cba55f8e29b280679291cf16c9184beba515677fcbeefebda62bfffb.sbom",
"sha256-697ba3241c1e1ccc75a26397962662c088bed2b33e0bd2594c33e69651eb6521.sig",
"sha256-a7352425cba55f8e29b280679291cf16c9184beba515677fcbeefebda62bfffb.att",
"sha256-27c33f0176e3e336661a922245cf08a423f738858a1b2a1aec477a429b1fb4b1.sbom",
"sha256-6f909322993b4df4e1bf7f7d4fbeb2905a7adc71c32853ad4be156b212dd4130.sig",
"sha256-27c33f0176e3e336661a922245cf08a423f738858a1b2a1aec477a429b1fb4b1.att",
"sha256-7a72e2d88c5a81b75a546ef89a74e5f7adb6d0560f1922317391ae8067bb7ec1.sbom",
"sha256-bf6644261333fe055bce4d3ddd9de975ad7c83e469872aca74bd58ca3c6372b5.sig",
"sha256-7a72e2d88c5a81b75a546ef89a74e5f7adb6d0560f1922317391ae8067bb7ec1.att",
"sha256-9c6abfdef5b6502e61b143e7f4e7f542a355d4d34944759b65dab6ec8920c835.sbom",
"sha256-f872994ef446f66c0ef07757f522e58a286ea711c744424d3b4412f6ae96e064.sig",
"sha256-9c6abfdef5b6502e61b143e7f4e7f542a355d4d34944759b65dab6ec8920c835.att",
"sha256-7d0f4d3fac167c4c2f3f1ac84ea3c21ba06a089441115706df5798853e925b32.sbom",
"sha256-810c654ce1fefa5eda05d7866166fe48b3a6ece0ea50a63f71875bd69b242feb.sig",
"sha256-7d0f4d3fac167c4c2f3f1ac84ea3c21ba06a089441115706df5798853e925b32.att",
"sha256-23c5e9c19d6a06bbd99cad767addc37f3430ec8bfed5950323ce74558e374a7c.sbom",
"sha256-d860e82697ec6923cbab537dc507ad1fe0d834af2ba6a2507cedcef9922ed80f.sig",
"sha256-23c5e9c19d6a06bbd99cad767addc37f3430ec8bfed5950323ce74558e374a7c.att",
"sha256-9cb5eecb57241920a8bc1ac969d1b52c5f96840c109ad145a7e8b12ecfe09af9.sbom",
"sha256-9c65f59b028c96261ae168181232eb111aaddd04c3613f2963a5276b5ed06604.sig",
"sha256-9cb5eecb57241920a8bc1ac969d1b52c5f96840c109ad145a7e8b12ecfe09af9.att",
"sha256-1bcce425b245744fc75ec816f549b53b739ce2ef1b83a7a8f2037c286c3f36d4.sbom",
"sha256-8697040feb79dee147693223d261072f831c82f24aa032abc3a7e4b631e2549d.sig",
"sha256-1bcce425b245744fc75ec816f549b53b739ce2ef1b83a7a8f2037c286c3f36d4.att",
"sha256-d10c753e8dc6bccf4621c9593e984b712944e5252b914cd1287383d4c7980fba.sbom",
"sha256-184fe37c476d726c604962716728bc44cec00697db536427cf9a349e0228caaa.sig",
"sha256-d10c753e8dc6bccf4621c9593e984b712944e5252b914cd1287383d4c7980fba.att",
"latest"
]

View File

@ -0,0 +1,56 @@
package versioneer_test
import (
"github.com/kairos-io/kairos-sdk/versioneer"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("BaseContainerName", func() {
var artifact versioneer.Artifact
var expectedName string
var registryAndOrg string
BeforeEach(func() {
artifact = versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "standard",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2",
SoftwareVersion: "k3sv1.26.9+k3s1",
}
})
When("artifact is valid", func() {
var id, registryAndOrg string
BeforeEach(func() {
id = "master"
registryAndOrg = "quay.io/kairos"
expectedName = "quay.io/kairos/opensuse:leap-15.5-standard-amd64-generic-master"
})
It("returns the name", func() {
name, err := artifact.BaseContainerName(registryAndOrg, id)
Expect(err).ToNot(HaveOccurred())
Expect(name).To(Equal(expectedName))
})
When("no id is passed", func() {
It("returns the name", func() {
name, err := artifact.BaseContainerName(registryAndOrg, "")
Expect(err).To(HaveOccurred(), name)
Expect(err).To(MatchError("no id passed"))
})
})
})
When("artifact is invalid", func() {
BeforeEach(func() {
artifact.Flavor = ""
})
It("returns an error", func() {
_, err := artifact.ContainerName(registryAndOrg)
Expect(err).To(MatchError("Flavor is empty"))
})
})
})

View File

@ -0,0 +1,59 @@
package versioneer_test
import (
"github.com/kairos-io/kairos-sdk/versioneer"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("BootableName", func() {
var artifact versioneer.Artifact
var expectedName string
BeforeEach(func() {
artifact = versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "standard",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2",
SoftwareVersion: "k3sv1.26.9+k3s1",
}
})
When("artifact is valid", func() {
When("SoftwareVersion is empty", func() {
BeforeEach(func() {
artifact.SoftwareVersion = ""
expectedName = "kairos-opensuse-leap-15.5-standard-amd64-generic-v2.4.2"
})
It("returns the name", func() {
name, err := artifact.BootableName()
Expect(err).ToNot(HaveOccurred())
Expect(name).To(Equal(expectedName))
})
})
When("SoftwareVersion is not empty", func() {
BeforeEach(func() {
expectedName = "kairos-opensuse-leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.26.9+k3s1"
})
It("returns the name", func() {
name, err := artifact.BootableName()
Expect(err).ToNot(HaveOccurred())
Expect(name).To(Equal(expectedName))
})
})
})
When("artifact is invalid", func() {
BeforeEach(func() {
artifact.Version = ""
})
It("returns an error", func() {
_, err := artifact.BootableName()
Expect(err).To(MatchError("Version is empty"))
})
})
})

193
versioneer/cli.go Normal file
View File

@ -0,0 +1,193 @@
package versioneer
import (
"fmt"
"github.com/urfave/cli/v2"
)
var (
flavorFlag *cli.StringFlag = &cli.StringFlag{
Name: "flavor",
Value: "",
Usage: "the OS flavor (e.g. opensuse)",
EnvVars: []string{EnvVarFlavor},
}
flavorReleaseFlag *cli.StringFlag = &cli.StringFlag{
Name: "flavor-release",
Value: "",
Usage: "the OS flavor release (e.g. leap-15.5)",
EnvVars: []string{EnvVarFlavorRelease},
}
variantFlag *cli.StringFlag = &cli.StringFlag{
Name: "variant",
Value: "",
Usage: "the Kairos variant (core, standard)",
EnvVars: []string{EnvVarVariant},
}
modelFlag *cli.StringFlag = &cli.StringFlag{
Name: "model",
Value: "",
Usage: "the model for which the OS was built (e.g. rpi4)",
EnvVars: []string{EnvVarModel},
}
archFlag *cli.StringFlag = &cli.StringFlag{
Name: "arch",
Value: "",
Usage: "the architecture of the OS",
EnvVars: []string{EnvVarArch},
}
versionFlag *cli.StringFlag = &cli.StringFlag{
Name: "version",
Value: "",
Usage: "the Kairos version (e.g. v2.4.2)",
EnvVars: []string{EnvVarVersion},
}
softwareVersionFlag *cli.StringFlag = &cli.StringFlag{
Name: "software-version",
Value: "",
Usage: "the software version (e.g. k3sv1.28.2+k3s1)",
EnvVars: []string{EnvVarSoftwareVersion},
}
registryAndOrgFlag *cli.StringFlag = &cli.StringFlag{
Name: "registry-and-org",
Value: "",
Usage: "the container registry and org (e.g. \"quay.io/kairos\")",
EnvVars: []string{EnvVarRegistryAndOrg},
}
idFlag *cli.StringFlag = &cli.StringFlag{
Name: "id",
Value: "",
Usage: "a identifier for the artifact (e.g. \"master\")",
EnvVars: []string{EnvVarID},
}
githubRepoFlag *cli.StringFlag = &cli.StringFlag{
Name: "github-repo",
Value: "",
Usage: "the Github repository where the code is hosted",
EnvVars: []string{EnvVarGithubRepo},
}
bugReportURLFlag *cli.StringFlag = &cli.StringFlag{
Name: "bug-report-url",
Value: "",
Usage: "the url where bugs can be reported",
EnvVars: []string{EnvVarBugReportURL},
}
projectHomeURLFlag *cli.StringFlag = &cli.StringFlag{
Name: "project-home-url",
Value: "",
Usage: "the url where more information about the project can be found",
EnvVars: []string{EnvVarHomeURL},
}
)
func CliCommands() []*cli.Command {
return []*cli.Command{
{
Name: "container-artifact-name",
Usage: "generates an artifact name for Kairos OCI images",
Flags: []cli.Flag{
flavorFlag, flavorReleaseFlag, variantFlag, modelFlag, archFlag,
versionFlag, softwareVersionFlag, registryAndOrgFlag,
},
Action: func(cCtx *cli.Context) error {
a := artifactFromFlags(cCtx)
result, err := a.ContainerName(cCtx.String(registryAndOrgFlag.Name))
if err != nil {
return err
}
fmt.Println(result)
return nil
},
},
{
Name: "bootable-artifact-name",
Usage: "generates a name for bootable artifacts (e.g. iso files)",
Flags: []cli.Flag{
flavorFlag, flavorReleaseFlag, variantFlag, modelFlag, archFlag,
versionFlag, softwareVersionFlag,
},
Action: func(cCtx *cli.Context) error {
a := artifactFromFlags(cCtx)
result, err := a.BootableName()
if err != nil {
return err
}
fmt.Println(result)
return nil
},
},
{
Name: "base-container-artifact-name",
Usage: "generates a name for base (not yet Kairos) images",
Flags: []cli.Flag{
flavorFlag, flavorReleaseFlag, variantFlag, modelFlag, archFlag,
registryAndOrgFlag, idFlag,
},
Action: func(cCtx *cli.Context) error {
a := artifactFromFlags(cCtx)
result, err := a.BaseContainerName(
cCtx.String(registryAndOrgFlag.Name), cCtx.String(idFlag.Name))
if err != nil {
return err
}
fmt.Println(result)
return nil
},
},
{
Name: "os-release-variables",
Usage: "generates a set of variables to be appended in the /etc/os-release file",
Flags: []cli.Flag{
flavorFlag, flavorReleaseFlag, variantFlag, modelFlag, archFlag, versionFlag,
softwareVersionFlag, registryAndOrgFlag, bugReportURLFlag, projectHomeURLFlag,
githubRepoFlag,
},
Action: func(cCtx *cli.Context) error {
a := artifactFromFlags(cCtx)
result, err := a.OSReleaseVariables(
registryAndOrgFlag.Get(cCtx),
githubRepoFlag.Get(cCtx),
bugReportURLFlag.Get(cCtx),
projectHomeURLFlag.Get(cCtx),
)
if err != nil {
return err
}
fmt.Println(result)
return nil
},
},
}
}
func artifactFromFlags(cCtx *cli.Context) Artifact {
return Artifact{
Flavor: flavorFlag.Get(cCtx),
FlavorRelease: flavorReleaseFlag.Get(cCtx),
Variant: variantFlag.Get(cCtx),
Model: modelFlag.Get(cCtx),
Arch: archFlag.Get(cCtx),
Version: versionFlag.Get(cCtx),
SoftwareVersion: softwareVersionFlag.Get(cCtx),
}
}

View File

@ -0,0 +1,63 @@
package versioneer_test
import (
"github.com/kairos-io/kairos-sdk/versioneer"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("ContainerName", func() {
var artifact versioneer.Artifact
var expectedName string
var registryAndOrg string
BeforeEach(func() {
artifact = versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "standard",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2",
SoftwareVersion: "k3sv1.26.9+k3s1",
}
registryAndOrg = "quay.io/kairos"
})
When("artifact is valid", func() {
When("SoftwareVersion is empty", func() {
BeforeEach(func() {
artifact.SoftwareVersion = ""
expectedName = "quay.io/kairos/opensuse:leap-15.5-standard-amd64-generic-v2.4.2"
})
It("returns the name", func() {
name, err := artifact.ContainerName(registryAndOrg)
Expect(err).ToNot(HaveOccurred())
Expect(name).To(Equal(expectedName))
})
})
When("SoftwareVersion is not empty", func() {
BeforeEach(func() {
expectedName = "quay.io/kairos/opensuse:leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.26.9-k3s1"
})
It("returns the name", func() {
name, err := artifact.ContainerName(registryAndOrg)
Expect(err).ToNot(HaveOccurred())
Expect(name).To(Equal(expectedName))
})
})
})
When("artifact is invalid", func() {
BeforeEach(func() {
artifact.Flavor = ""
})
It("returns an error", func() {
_, err := artifact.ContainerName(registryAndOrg)
Expect(err).To(MatchError("Flavor is empty"))
})
})
})

View File

@ -0,0 +1,32 @@
package versioneer_test
import (
"github.com/kairos-io/kairos-sdk/versioneer"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("NewArtifactFromJSON", func() {
It("returns an object from the given json", func() {
jsonStr := `{
"flavor":"opensuse-leap",
"flavorRelease":"15.5",
"variant":"standard",
"model":"generic",
"arch":"amd64",
"version":"v2.4.2",
"softwareVersion":"k3sv1.26.9+k3s1"
}`
artifact, err := versioneer.NewArtifactFromJSON(jsonStr)
Expect(err).ToNot(HaveOccurred())
Expect(artifact.Flavor).To(Equal("opensuse-leap"))
Expect(artifact.FlavorRelease).To(Equal("15.5"))
Expect(artifact.Variant).To(Equal("standard"))
Expect(artifact.Model).To(Equal("generic"))
Expect(artifact.Arch).To(Equal("amd64"))
Expect(artifact.Version).To(Equal("v2.4.2"))
Expect(artifact.SoftwareVersion).To(Equal("k3sv1.26.9+k3s1"))
})
})

View File

@ -0,0 +1,48 @@
package versioneer_test
import (
"os"
"github.com/kairos-io/kairos-sdk/versioneer"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("NewArtifactFromOSRelease", func() {
var tmpOSReleaseFile *os.File
var err error
var osReleaseContent string
BeforeEach(func() {
tmpOSReleaseFile, err = os.CreateTemp("", "os-release")
Expect(err).ToNot(HaveOccurred())
osReleaseContent = "KAIROS_FLAVOR=opensuse\n" +
"KAIROS_FLAVOR_RELEASE=leap-15.5\n" +
"KAIROS_VARIANT=standard\n" +
"KAIROS_ARCH=amd64\n" +
"KAIROS_MODEL=generic\n" +
"KAIROS_RELEASE=v2.4.2\n" +
"KAIROS_SOFTWARE_VERSION=k3sv1.26.9+k3s1\n"
err = os.WriteFile(tmpOSReleaseFile.Name(), []byte(osReleaseContent), 0644)
Expect(err).ToNot(HaveOccurred())
})
AfterEach(func() {
os.Remove(tmpOSReleaseFile.Name())
})
It("builds a correct object", func() {
artifact, err := versioneer.NewArtifactFromOSRelease(tmpOSReleaseFile.Name())
Expect(err).ToNot(HaveOccurred())
Expect(artifact.Flavor).To(Equal("opensuse"))
Expect(artifact.FlavorRelease).To(Equal("leap-15.5"))
Expect(artifact.Variant).To(Equal("standard"))
Expect(artifact.Model).To(Equal("generic"))
Expect(artifact.Arch).To(Equal("amd64"))
Expect(artifact.Version).To(Equal("v2.4.2"))
Expect(artifact.SoftwareVersion).To(Equal("k3sv1.26.9+k3s1"))
})
})

View File

@ -0,0 +1,25 @@
package versioneer
import (
"fmt"
"github.com/google/go-containerregistry/pkg/crane"
)
type RegistryInspector interface {
TagList(registryAndOrg string, artifact *Artifact) (TagList, error)
}
type DefaultRegistryInspector struct{}
func (i *DefaultRegistryInspector) TagList(registryAndOrg string, artifact *Artifact) (TagList, error) {
var err error
tl := TagList{Artifact: artifact}
tl.Tags, err = crane.ListTags(fmt.Sprintf("%s/%s", registryAndOrg, artifact.Flavor))
if err != nil {
return tl, err
}
return tl, nil
}

27
versioneer/suite_test.go Normal file
View File

@ -0,0 +1,27 @@
package versioneer_test
import (
"encoding/json"
"os"
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestConfig(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Versioneer Suite")
}
func getFakeTags() []string {
var fakeTags []string
// To regenerate this file, just remove the inspector from the artifact
// below and let the default inspector query the quay.io repository.
tagsJSON, err := os.ReadFile("assets/test_tags.json")
Expect(err).ToNot(HaveOccurred())
err = json.Unmarshal(tagsJSON, &fakeTags)
Expect(err).ToNot(HaveOccurred())
return fakeTags
}

241
versioneer/tag_list.go Normal file
View File

@ -0,0 +1,241 @@
package versioneer
import (
"fmt"
"regexp"
"sort"
"strings"
"golang.org/x/mod/semver"
)
type TagList struct {
Tags []string
Artifact *Artifact
}
// implements sort.Interface for TagList
func (tl TagList) Len() int { return len(tl.Tags) }
func (tl TagList) Swap(i, j int) { tl.Tags[i], tl.Tags[j] = tl.Tags[j], tl.Tags[i] }
func (tl TagList) Less(i, j int) bool {
return tl.Tags[i] < tl.Tags[j]
}
// Images returns only tags that represent images, skipping tags representing:
// - sbom
// - att
// - sig
// - -img
func (tl TagList) Images() TagList {
pattern := `.*-(core|standard)-(amd64|arm64)-.*-v.*`
regexpObject := regexp.MustCompile(pattern)
result := TagList{Artifact: tl.Artifact}
for _, t := range tl.Tags {
// We have to filter "-img" tags outside the regexp because golang regexp doesn't support negative lookaheads.
if regexpObject.MatchString(t) && !strings.HasSuffix(t, "-img") {
result.Tags = append(result.Tags, t)
}
}
return result
}
// OtherVersions returns tags that match all fields of the given Artifact,
// except the Version. Should be used to return other possible versions for the same
// Kairos image (e.g. that one could upgrade to).
// This method returns all versions, not only newer ones. Use NewerVersions to
// fetch only versions, newer than the one of the Artifact.
func (tl TagList) OtherVersions() TagList {
return tl.fieldOtherOptions(tl.Artifact.Version)
}
// NewerVersions returns OtherVersions filtered to only include tags with
// Version higher than the given artifact's.
func (tl TagList) NewerVersions() TagList {
tags := tl.OtherVersions()
return tags.newerVersions()
}
// OtherSoftwareVersions returns tags that match all fields of the given Artifact,
// except the SoftwareVersion. Should be used to return other possible software versions
// for the same Kairos image (e.g. that one could upgrade to).
// This method returns all versions, not only newer ones. Use NewerSofwareVersions to
// fetch only versions, newer than the one of the Artifact.
func (tl TagList) OtherSoftwareVersions() TagList {
return tl.fieldOtherOptions(tl.Artifact.SoftwareVersion)
}
// NewerSofwareVersions returns OtherSoftwareVersions filtered to only include tags with
// SoftwareVersion higher than the given artifact's.
func (tl TagList) NewerSofwareVersions(softwarePrefix string) TagList {
tags := tl.OtherSoftwareVersions()
return tags.newerSoftwareVersions(softwarePrefix)
}
// OtherAnyVersion returns tags that match all fields of the given Artifact,
// except the SoftwareVersion and/or Version.
// Should be used to return tags with newer versions (Kairos or "software")
// that one could upgrade to.
// This method returns all versions, not only newer ones. Use NewerAnyVersion to
// fetch only versions, newer than the one of the Artifact.
func (tl TagList) OtherAnyVersion() TagList {
if tl.Artifact.SoftwareVersion != "" {
return tl.fieldOtherOptions(
fmt.Sprintf("%s-%s", tl.Artifact.Version, tl.Artifact.SoftwareVersion))
} else {
return tl.fieldOtherOptions(tl.Artifact.Version)
}
}
// NewerAnyVersion returns OtherAnyVersion filtered to only include tags with
// Version and SoftwareVersion equal or higher than the given artifact's.
// At least one of the 2 versions will be higher than the current one.
// Splitting the 2 versions is done using the softwarePrefix (first encountered,
// because our tags have a "k3s1" in the end too)
func (tl TagList) NewerAnyVersion(softwarePrefix string) TagList {
tags := tl.OtherAnyVersion()
if tl.Artifact.SoftwareVersion != "" {
return tags.newerAllVersions(softwarePrefix)
} else {
return tags.newerVersions()
}
}
func (tl TagList) Print() {
for _, t := range tl.Tags {
fmt.Println(t)
}
}
// Sorted returns the TagList sorted alphabetically
// This means lower versions come first.
func (tl TagList) Sorted() TagList {
newTags := make([]string, len(tl.Tags))
copy(newTags, tl.Tags)
sort.Strings(newTags)
return TagList{Artifact: tl.Artifact, Tags: newTags}
}
// RSorted returns the TagList in the reverse order of Sorted
// This means higher versions come first.
func (tl TagList) RSorted() TagList {
newTags := make([]string, len(tl.Tags))
copy(newTags, tl.Tags)
sort.Sort(sort.Reverse(sort.StringSlice(newTags)))
return TagList{Artifact: tl.Artifact, Tags: newTags}
}
func (tl TagList) fieldOtherOptions(field string) TagList {
artifactTag, err := tl.Artifact.Tag()
if err != nil {
panic(fmt.Errorf("invalid artifact passed: %w", err))
}
pattern := regexp.QuoteMeta(artifactTag)
pattern = strings.Replace(pattern, regexp.QuoteMeta(field), ".*", 1)
regexpObject := regexp.MustCompile(pattern)
result := TagList{Artifact: tl.Artifact}
for _, t := range tl.Images().Tags {
if regexpObject.MatchString(t) && t != artifactTag {
result.Tags = append(result.Tags, t)
}
}
return result
}
func (tl TagList) newerVersions() TagList {
artifactTag, err := tl.Artifact.Tag()
if err != nil {
panic(fmt.Errorf("invalid artifact passed: %w", err))
}
pattern := regexp.QuoteMeta(artifactTag)
pattern = strings.Replace(pattern, regexp.QuoteMeta(tl.Artifact.Version), "(.*)", 1)
regexpObject := regexp.MustCompile(pattern)
result := TagList{Artifact: tl.Artifact}
for _, t := range tl.Tags {
version := regexpObject.FindStringSubmatch(t)[1]
if semver.Compare(version, tl.Artifact.Version) == +1 {
result.Tags = append(result.Tags, t)
}
}
return result
}
func (tl TagList) newerSoftwareVersions(softwarePrefix string) TagList {
artifactTag, err := tl.Artifact.Tag()
if err != nil {
panic(fmt.Errorf("invalid artifact passed: %w", err))
}
pattern := regexp.QuoteMeta(artifactTag)
pattern = strings.Replace(pattern, regexp.QuoteMeta(tl.Artifact.SoftwareVersion), "(.*)", 1)
regexpObject := regexp.MustCompile(pattern)
trimmedVersion := strings.TrimPrefix(tl.Artifact.SoftwareVersion, softwarePrefix)
result := TagList{Artifact: tl.Artifact}
for _, t := range tl.Tags {
version := strings.TrimPrefix(regexpObject.FindStringSubmatch(t)[1], softwarePrefix)
if semver.Compare(version, trimmedVersion) == +1 {
result.Tags = append(result.Tags, t)
}
}
return result
}
// softwarePrefix is what separates the Version from SoftwareVersion in the tag.
// It has to be removed for the SoftwareVersion to be valid semver.
// E.g. "k3sv1.26.9-k3s1"
func (tl TagList) newerAllVersions(softwarePrefix string) TagList {
artifactTag, err := tl.Artifact.Tag()
if err != nil {
panic(fmt.Errorf("invalid artifact passed: %w", err))
}
pattern := regexp.QuoteMeta(artifactTag)
// Example result:
// leap-15\.5-standard-amd64-generic-(.*?)-k3sv1.27.6-k3s1
pattern = strings.Replace(pattern, regexp.QuoteMeta(tl.Artifact.Version), "(.*?)", 1)
// Example result:
// leap-15\.5-standard-amd64-generic-(.*?)-k3s(.*)
pattern = strings.Replace(pattern,
regexp.QuoteMeta(strings.TrimPrefix(tl.Artifact.SoftwareVersion, softwarePrefix)),
"(.*)", 1)
regexpObject := regexp.MustCompile(pattern)
trimmedSVersion := strings.TrimPrefix(tl.Artifact.SoftwareVersion, softwarePrefix)
result := TagList{Artifact: tl.Artifact}
for _, t := range tl.Tags {
matches := regexpObject.FindStringSubmatch(t)
version := matches[1]
softwareVersion := matches[2]
versionResult := semver.Compare(version, tl.Artifact.Version)
sVersionResult := semver.Compare(softwareVersion, trimmedSVersion)
// If version is not lower than the current
// and softwareVersion is not lower than the current
// and at least one of the 2 is higher than the current
if versionResult >= 0 && sVersionResult >= 0 && versionResult+sVersionResult > 0 {
result.Tags = append(result.Tags, t)
}
}
return result
}

254
versioneer/tag_list_test.go Normal file
View File

@ -0,0 +1,254 @@
package versioneer_test
import (
"github.com/kairos-io/kairos-sdk/versioneer"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("TagList", func() {
var tagList versioneer.TagList
BeforeEach(func() {
tagList = versioneer.TagList{
Tags: getFakeTags(),
}
})
Describe("Images", func() {
It("returns only tags matching images", func() {
images := tagList.Images()
// Sanity check, that we didn't filter everything out
Expect(len(images.Tags)).To(BeNumerically(">", 4))
expectOnlyImages(images.Tags)
})
})
Describe("Sorted", func() {
It("returns tags sorted alphabetically", func() {
images := tagList.Images()
sortedImages := images.Sorted()
// Sanity checks
Expect(len(images.Tags)).To(BeNumerically(">", 4))
Expect(len(sortedImages.Tags)).To(Equal(len(images.Tags)))
Expect(isSorted(images.Tags)).To(BeFalse())
Expect(isSorted(sortedImages.Tags)).To(BeTrue())
})
})
Describe("RSorted", func() {
It("returns tags in reverse alphabetical order", func() {
images := tagList.Images()
rSortedImages := images.RSorted()
// Sanity checks
Expect(len(images.Tags)).To(BeNumerically(">", 4))
Expect(len(rSortedImages.Tags)).To(Equal(len(images.Tags)))
Expect(isRSorted(images.Tags)).To(BeFalse())
Expect(isRSorted(rSortedImages.Tags)).To(BeTrue())
})
})
Describe("OtherVersions", func() {
BeforeEach(func() {
tagList.Artifact = &versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "standard",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2-rc1",
SoftwareVersion: "k3sv1.27.6-k3s1",
}
})
It("returns only tags with different version", func() {
tags := tagList.OtherVersions().Tags
Expect(tags).To(HaveExactElements(
"leap-15.5-standard-amd64-generic-v2.4.2-rc2-k3sv1.27.6-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.27.6-k3s1"))
})
})
Describe("NewerVersions", func() {
BeforeEach(func() {
tagList.Artifact = &versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "standard",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2-rc2",
SoftwareVersion: "k3sv1.27.6-k3s1",
}
})
It("returns only tags with newer Version field (the rest similar)", func() {
tags := tagList.NewerVersions().Tags
Expect(tags).To(HaveExactElements(
"leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.27.6-k3s1"))
})
})
Describe("OtherSoftwareVersions", func() {
BeforeEach(func() {
tagList.Artifact = &versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "standard",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2-rc1",
SoftwareVersion: "k3sv1.27.6-k3s1",
}
})
It("returns only tags with different SoftwareVersion", func() {
tags := tagList.OtherSoftwareVersions().Tags
Expect(tags).To(HaveExactElements(
"leap-15.5-standard-amd64-generic-v2.4.2-rc1-k3sv1.26.9-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-rc1-k3sv1.28.2-k3s1"))
})
})
Describe("NewerSofwareVersions", func() {
BeforeEach(func() {
tagList.Artifact = &versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "standard",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2-rc1",
SoftwareVersion: "k3sv1.27.6-k3s1",
}
})
It("returns only tags with newer SoftwareVersion", func() {
tags := tagList.NewerSofwareVersions("k3s").Tags
Expect(tags).To(HaveExactElements(
"leap-15.5-standard-amd64-generic-v2.4.2-rc1-k3sv1.28.2-k3s1"))
})
})
Describe("OtherAnyVersion", func() {
BeforeEach(func() {
tagList.Artifact = &versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "standard",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2-rc1",
SoftwareVersion: "k3sv1.27.6-k3s1",
}
})
It("returns only tags with different Version and/or SoftwareVersion", func() {
tags := tagList.OtherAnyVersion().Tags
Expect(tags).To(HaveExactElements(
"leap-15.5-standard-amd64-generic-v2.4.2-rc1-k3sv1.26.9-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-rc1-k3sv1.28.2-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-rc2-k3sv1.28.2-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-rc2-k3sv1.26.9-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-rc2-k3sv1.27.6-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.27.6-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.26.9-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.28.2-k3s1"))
})
})
Describe("NewerAnyVersion", func() {
When("artifact has SoftwareVersion", func() {
BeforeEach(func() {
tagList.Artifact = &versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "standard",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2-rc1",
SoftwareVersion: "k3sv1.27.6-k3s1",
}
})
It("returns only tags with newer Versions and/or SoftwareVersion", func() {
tags := tagList.NewerAnyVersion("k3s").Tags
Expect(tags).To(HaveExactElements(
"leap-15.5-standard-amd64-generic-v2.4.2-rc1-k3sv1.28.2-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-rc2-k3sv1.28.2-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-rc2-k3sv1.27.6-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.27.6-k3s1",
"leap-15.5-standard-amd64-generic-v2.4.2-k3sv1.28.2-k3s1"))
})
})
When("artifact has no SoftwareVersion", func() {
BeforeEach(func() {
tagList.Artifact = &versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "core",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2-rc1",
SoftwareVersion: "",
}
})
It("returns only tags with newer Versions and/or SoftwareVersion", func() {
tags := tagList.NewerAnyVersion("k3s").Tags
Expect(tags).To(HaveExactElements(
"leap-15.5-core-amd64-generic-v2.4.2-rc2",
"leap-15.5-core-amd64-generic-v2.4.2"))
})
})
})
})
func expectOnlyImages(images []string) {
Expect(images).ToNot(ContainElement(ContainSubstring(".att")))
Expect(images).ToNot(ContainElement(ContainSubstring(".sbom")))
Expect(images).ToNot(ContainElement(ContainSubstring(".sig")))
Expect(images).ToNot(ContainElement(ContainSubstring("-img")))
Expect(images).To(HaveEach(MatchRegexp((".*-(core|standard)-(amd64|arm64)-.*-v.*"))))
}
func isSorted(tl []string) bool {
for i, tag := range tl {
if i > 0 {
previousTag := tl[i-1]
if previousTag > tag {
return false
}
}
}
return true
}
func isRSorted(tl []string) bool {
for i, tag := range tl {
if i > 0 {
previousTag := tl[i-1]
if previousTag < tag {
return false
}
}
}
return true
}

View File

@ -0,0 +1,47 @@
package versioneer_test
import (
"github.com/kairos-io/kairos-sdk/versioneer"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Validate", func() {
var artifact versioneer.Artifact
BeforeEach(func() {
artifact = versioneer.Artifact{
Flavor: "opensuse",
FlavorRelease: "leap-15.5",
Variant: "standard",
Model: "generic",
Arch: "amd64",
Version: "v2.4.2",
}
})
When("artifact is valid", func() {
It("returns nil", func() {
Expect(artifact.Validate()).To(BeNil())
})
})
It("returns an error when FlavorRelease is empty", func() {
artifact.FlavorRelease = ""
Expect(artifact.Validate()).To(MatchError("FlavorRelease is empty"))
})
It("returns an error when Variant is empty", func() {
artifact.Variant = ""
Expect(artifact.Validate()).To(MatchError("Variant is empty"))
})
It("returns an error when Model is empty", func() {
artifact.Model = ""
Expect(artifact.Validate()).To(MatchError("Model is empty"))
})
It("returns an error when Arch is empty", func() {
artifact.Arch = ""
Expect(artifact.Validate()).To(MatchError("Arch is empty"))
})
})

260
versioneer/versioneer.go Normal file
View File

@ -0,0 +1,260 @@
package versioneer
import (
"encoding/json"
"errors"
"fmt"
"strings"
"github.com/kairos-io/kairos-sdk/utils"
)
const (
// KAIROS_VERSION was already used in os-release and we avoided breaking it
// for consumers by using a new variable KAIROS_RELEASE instead. But it's the
// "Artifact.Version".
EnvVarVersion = "RELEASE"
EnvVarFlavor = "FLAVOR"
EnvVarFlavorRelease = "FLAVOR_RELEASE"
EnvVarVariant = "VARIANT"
EnvVarModel = "MODEL"
EnvVarArch = "ARCH"
EnvVarSoftwareVersion = "SOFTWARE_VERSION"
EnvVarRegistryAndOrg = "REGISTRY_AND_ORG"
EnvVarID = "ID"
EnvVarGithubRepo = "GITHUB_REPO"
EnvVarBugReportURL = "BUG_REPORT_URL"
EnvVarHomeURL = "HOME_URL"
)
type Artifact struct {
Flavor string
FlavorRelease string
Variant string
Model string
Arch string
Version string // The Kairos version. E.g. "v2.4.2"
SoftwareVersion string // The k3s version. E.g. "k3sv1.26.9+k3s1"
RegistryInspector RegistryInspector
}
func NewArtifactFromJSON(jsonStr string) (*Artifact, error) {
result := &Artifact{}
err := json.Unmarshal([]byte(jsonStr), result)
return result, err
}
// NewArtifactFromOSRelease generates an artifact by inpecting the variables
// in the /etc/os-release file of a Kairos image. The variable should be
// prefixed with "KAIROS_". E.g. KAIROS_VARIANT would be used to set the Variant
// field. The function optionally takes an argument to specify a different file
// path (for testing reasons).
func NewArtifactFromOSRelease(file ...string) (*Artifact, error) {
var err error
result := Artifact{}
if result.Flavor, err = utils.OSRelease(EnvVarFlavor, file...); err != nil {
return nil, err
}
if result.FlavorRelease, err = utils.OSRelease(EnvVarFlavorRelease, file...); err != nil {
return nil, err
}
if result.Variant, err = utils.OSRelease(EnvVarVariant, file...); err != nil {
return nil, err
}
if result.Model, err = utils.OSRelease(EnvVarModel, file...); err != nil {
return nil, err
}
if result.Arch, err = utils.OSRelease(EnvVarArch, file...); err != nil {
return nil, err
}
if result.Version, err = utils.OSRelease(EnvVarVersion, file...); err != nil {
return nil, err
}
if result.SoftwareVersion, err = utils.OSRelease(EnvVarSoftwareVersion, file...); err != nil {
return nil, err
}
return &result, nil
}
func (a *Artifact) Validate() error {
if a.FlavorRelease == "" {
return errors.New("FlavorRelease is empty")
}
if a.Variant == "" {
return errors.New("Variant is empty")
}
if a.Model == "" {
return errors.New("Model is empty")
}
if a.Arch == "" {
return errors.New("Arch is empty")
}
return nil
}
func (a *Artifact) BootableName() (string, error) {
commonName, err := a.commonVersionedName()
if err != nil {
return "", err
}
if a.Flavor == "" {
return "", errors.New("Flavor is empty")
}
return fmt.Sprintf("kairos-%s-%s", a.Flavor, commonName), nil
}
func (a *Artifact) ContainerName(registryAndOrg string) (string, error) {
if a.Flavor == "" {
return "", errors.New("Flavor is empty")
}
tag, err := a.Tag()
if err != nil {
return "", err
}
return fmt.Sprintf("%s/%s:%s", registryAndOrg, a.Flavor, tag), nil
}
func (a *Artifact) BaseContainerName(registryAndOrg, id string) (string, error) {
if a.Flavor == "" {
return "", errors.New("Flavor is empty")
}
if id == "" {
return "", errors.New("no id passed")
}
tag, err := a.BaseTag()
if err != nil {
return "", err
}
return fmt.Sprintf("%s/%s:%s-%s", registryAndOrg, a.Flavor, tag, id), nil
}
func (a *Artifact) BaseTag() (string, error) {
return a.commonName()
}
func (a *Artifact) Tag() (string, error) {
commonName, err := a.commonVersionedName()
if err != nil {
return commonName, err
}
return strings.ReplaceAll(commonName, "+", "-"), nil
}
// OSReleaseVariables returns a set of variables to be appended in /etc/os-release
func (a *Artifact) OSReleaseVariables(registryAndOrg, githubRepo, bugURL, homeURL string) (string, error) {
if registryAndOrg == "" {
return "", errors.New("registry-and-org must be set")
}
commonName, err := a.commonVersionedName()
if err != nil {
return commonName, err
}
kairosName := fmt.Sprintf("kairos-%s-%s-%s", a.Variant, a.Flavor, a.FlavorRelease)
kairosVersion := a.Version
if a.SoftwareVersion != "" {
kairosVersion += "-" + strings.ReplaceAll(a.SoftwareVersion, "+", "-")
}
containerName, err := a.ContainerName(registryAndOrg)
if err != nil {
return "", err
}
tag, err := a.Tag()
if err != nil {
return "", err
}
bootableName, err := a.BootableName()
if err != nil {
return "", err
}
vars := map[string]string{
// Legacy variables (not used by versioneer)
"KAIROS_NAME": kairosName,
"KAIROS_VERSION": kairosVersion,
"KAIROS_ID": "kairos",
"KAIROS_ID_LIKE": kairosName,
"KAIROS_VERSION_ID": kairosVersion,
"KAIROS_PRETTY_NAME": fmt.Sprintf("%s %s", kairosName, kairosVersion),
"KAIROS_IMAGE_REPO": containerName,
"KAIROS_IMAGE_LABEL": tag,
"KAIROS_ARTIFACT": bootableName,
// Actively used variables
"KAIROS_FLAVOR": a.Flavor,
"KAIROS_FLAVOR_RELEASE": a.FlavorRelease,
"KAIROS_VARIANT": a.Variant,
"KAIROS_MODEL": a.Model,
"KAIROS_ARCH": a.Arch,
"KAIROS_RELEASE": a.Version,
}
if bugURL != "" {
vars["KAIROS_BUG_REPORT_URL"] = bugURL
}
if homeURL != "" {
vars["KAIROS_HOME_URL"] = homeURL
}
if githubRepo != "" {
vars["KAIROS_GITHUB_REPO"] = githubRepo
}
if a.SoftwareVersion != "" {
vars["KAIROS_SOFTWARE_VERSION"] = a.SoftwareVersion
}
result := ""
for k, v := range vars {
result += fmt.Sprintf("%s=%s\n", k, v)
}
return result, nil
}
func (a *Artifact) TagList(registryAndOrg string) (TagList, error) {
if a.RegistryInspector == nil {
a.RegistryInspector = &DefaultRegistryInspector{}
}
return a.RegistryInspector.TagList(registryAndOrg, a)
}
func (a *Artifact) commonName() (string, error) {
if err := a.Validate(); err != nil {
return "", err
}
result := fmt.Sprintf("%s-%s-%s-%s",
a.FlavorRelease, a.Variant, a.Arch, a.Model)
return result, nil
}
func (a *Artifact) commonVersionedName() (string, error) {
if a.Version == "" {
return "", errors.New("Version is empty")
}
result, err := a.commonName()
if err != nil {
return result, err
}
result = fmt.Sprintf("%s-%s", result, a.Version)
if a.SoftwareVersion != "" {
result = fmt.Sprintf("%s-%s", result, a.SoftwareVersion)
}
return result, nil
}