gofmt
This commit is contained in:
parent
f2e3de4b5d
commit
40fd4646ce
9 changed files with 187 additions and 189 deletions
|
@ -2,13 +2,13 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"git.deuxfleurs.fr/deuxfleurs/albatros/cmd"
|
"git.deuxfleurs.fr/deuxfleurs/albatros/cmd"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := cmd.RootCmd.Execute(); err != nil {
|
if err := cmd.RootCmd.Execute(); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.deuxfleurs.fr/deuxfleurs/albatros/pkg"
|
"git.deuxfleurs.fr/deuxfleurs/albatros/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
182
cmd/container.go
182
cmd/container.go
|
@ -1,10 +1,10 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
|
||||||
"errors"
|
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -13,26 +13,27 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/image/v5/transports/alltransports"
|
|
||||||
"github.com/containers/image/v5/signature"
|
|
||||||
"github.com/containers/image/v5/copy"
|
"github.com/containers/image/v5/copy"
|
||||||
|
"github.com/containers/image/v5/signature"
|
||||||
|
"github.com/containers/image/v5/transports/alltransports"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"gocloud.dev/blob"
|
"gocloud.dev/blob"
|
||||||
_ "gocloud.dev/blob/s3blob"
|
_ "gocloud.dev/blob/s3blob"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pctx *signature.PolicyContext
|
var pctx *signature.PolicyContext
|
||||||
const distributionPrefix = "v2"
|
|
||||||
|
|
||||||
|
const distributionPrefix = "v2"
|
||||||
|
|
||||||
//---
|
//---
|
||||||
//--- Image converter
|
//--- Image converter
|
||||||
type OCIImageManifest struct {
|
type OCIImageManifest struct {
|
||||||
SchemaVersion int `json:"schemaVersion"`
|
SchemaVersion int `json:"schemaVersion"`
|
||||||
MediaType string `json:"mediaType"`
|
MediaType string `json:"mediaType"`
|
||||||
Config OCIRef `json:"config"`
|
Config OCIRef `json:"config"`
|
||||||
Layers []OCIRef `json:layers"`
|
Layers []OCIRef `json:layers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadOCIImageManifest(path string) (*OCIImageManifest, error) {
|
func LoadOCIImageManifest(path string) (*OCIImageManifest, error) {
|
||||||
fd, err := os.Open(path)
|
fd, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -56,26 +57,27 @@ func LoadOCIImageManifest(path string) (*OCIImageManifest, error) {
|
||||||
|
|
||||||
type OCIPlatform struct {
|
type OCIPlatform struct {
|
||||||
Architecture string `json:"architecture"`
|
Architecture string `json:"architecture"`
|
||||||
OS string `json:"os"`
|
OS string `json:"os"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OCIRef struct {
|
type OCIRef struct {
|
||||||
MediaType string `json:"mediaType"`
|
MediaType string `json:"mediaType"`
|
||||||
Digest string `json:"digest"`
|
Digest string `json:"digest"`
|
||||||
Size int `json:"size"`
|
Size int `json:"size"`
|
||||||
Platform *OCIPlatform `json:"platform,omitempty"`
|
Platform *OCIPlatform `json:"platform,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OCIImageIndex struct {
|
type OCIImageIndex struct {
|
||||||
SchemaVersion int `json:"schemaVersion"`
|
SchemaVersion int `json:"schemaVersion"`
|
||||||
MediaType string `json:"mediaType"`
|
MediaType string `json:"mediaType"`
|
||||||
Manifests []OCIRef `json:"manifests"`
|
Manifests []OCIRef `json:"manifests"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOCIImageIndex(o *OCIMultiArch) (OCIImageIndex, error) {
|
func NewOCIImageIndex(o *OCIMultiArch) (OCIImageIndex, error) {
|
||||||
idx := OCIImageIndex {
|
idx := OCIImageIndex{
|
||||||
SchemaVersion: 2,
|
SchemaVersion: 2,
|
||||||
MediaType: "application/vnd.oci.image.index.v1+json",
|
MediaType: "application/vnd.oci.image.index.v1+json",
|
||||||
Manifests: []OCIRef{},
|
Manifests: []OCIRef{},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, syst := range o.images {
|
for _, syst := range o.images {
|
||||||
|
@ -130,6 +132,7 @@ func (i OCIImageIndex) WriteTo(root string) error {
|
||||||
type OCILayout struct {
|
type OCILayout struct {
|
||||||
ImageLayoutVersion string `json:"imageLayoutVersion"`
|
ImageLayoutVersion string `json:"imageLayoutVersion"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOCILayout() OCILayout {
|
func NewOCILayout() OCILayout {
|
||||||
return OCILayout{"1.0.0"}
|
return OCILayout{"1.0.0"}
|
||||||
}
|
}
|
||||||
|
@ -146,16 +149,17 @@ func (o OCILayout) WriteTo(root string) error {
|
||||||
|
|
||||||
//---- Alba logic
|
//---- Alba logic
|
||||||
type OCISystemImage struct {
|
type OCISystemImage struct {
|
||||||
path string
|
path string
|
||||||
os string
|
os string
|
||||||
arch string
|
arch string
|
||||||
index *OCIImageIndex
|
index *OCIImageIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOCISystemImage(path, os, arch string) (OCISystemImage, error) {
|
func NewOCISystemImage(path, os, arch string) (OCISystemImage, error) {
|
||||||
si := OCISystemImage {
|
si := OCISystemImage{
|
||||||
path: path,
|
path: path,
|
||||||
os: os,
|
os: os,
|
||||||
arch: arch,
|
arch: arch,
|
||||||
index: nil,
|
index: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,9 +175,9 @@ func NewOCISystemImage(path, os, arch string) (OCISystemImage, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enrich manifest
|
// Enrich manifest
|
||||||
si.index.Manifests[0].Platform = &OCIPlatform {
|
si.index.Manifests[0].Platform = &OCIPlatform{
|
||||||
Architecture: arch,
|
Architecture: arch,
|
||||||
OS: os,
|
OS: os,
|
||||||
}
|
}
|
||||||
return si, nil
|
return si, nil
|
||||||
}
|
}
|
||||||
|
@ -183,15 +187,15 @@ func (o OCISystemImage) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type OCIMultiArch struct {
|
type OCIMultiArch struct {
|
||||||
Name string
|
Name string
|
||||||
Tag string
|
Tag string
|
||||||
path string
|
path string
|
||||||
multi *OCIImageIndex
|
multi *OCIImageIndex
|
||||||
images []OCISystemImage
|
images []OCISystemImage
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOCIMultiArch(nametag string) (*OCIMultiArch, error) {
|
func NewOCIMultiArch(nametag string) (*OCIMultiArch, error) {
|
||||||
ntspl := strings.Split(nametag, ":")
|
ntspl := strings.Split(nametag, ":")
|
||||||
if len(ntspl) != 2 {
|
if len(ntspl) != 2 {
|
||||||
return nil, errors.New("nametag must be of the form 'name:tag'")
|
return nil, errors.New("nametag must be of the form 'name:tag'")
|
||||||
}
|
}
|
||||||
|
@ -201,10 +205,10 @@ func NewOCIMultiArch(nametag string) (*OCIMultiArch, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &OCIMultiArch {
|
return &OCIMultiArch{
|
||||||
Name: ntspl[0],
|
Name: ntspl[0],
|
||||||
Tag: ntspl[1],
|
Tag: ntspl[1],
|
||||||
path: tmp,
|
path: tmp,
|
||||||
images: []OCISystemImage{},
|
images: []OCISystemImage{},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -252,7 +256,6 @@ func (o *OCIMultiArch) LoadFromDockerArchives(path string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Convert the docker archive to an oci image
|
// Convert the docker archive to an oci image
|
||||||
_, err = copy.Image(context.Background(), pctx, dstRef, srcRef, ©.Options{})
|
_, err = copy.Image(context.Background(), pctx, dstRef, srcRef, ©.Options{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -288,7 +291,6 @@ func (o *OCIMultiArch) MergeSystemImages() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create the oci-layout file
|
// Create the oci-layout file
|
||||||
err = NewOCILayout().WriteTo(multiArchRoot)
|
err = NewOCILayout().WriteTo(multiArchRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -308,7 +310,6 @@ func (o *OCIMultiArch) MergeSystemImages() error {
|
||||||
o.multi = &idx
|
o.multi = &idx
|
||||||
fmt.Printf("-> index.json\n")
|
fmt.Printf("-> index.json\n")
|
||||||
|
|
||||||
|
|
||||||
// Copy blobs
|
// Copy blobs
|
||||||
for _, img := range o.images {
|
for _, img := range o.images {
|
||||||
blobCounter := 0
|
blobCounter := 0
|
||||||
|
@ -462,7 +463,6 @@ func (o *OCIMultiArch) UploadImageS3(buck *blob.Bucket) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type StaticRegistryManager struct {
|
type StaticRegistryManager struct {
|
||||||
name string
|
name string
|
||||||
buck *blob.Bucket
|
buck *blob.Bucket
|
||||||
|
@ -476,7 +476,7 @@ func NewStaticRegistryManager(buck *blob.Bucket, name string) *StaticRegistryMan
|
||||||
}
|
}
|
||||||
|
|
||||||
type TagList struct {
|
type TagList struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,7 +489,7 @@ func (l *StaticRegistryManager) ComputeTagList() (TagList, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
iter := l.buck.List(&blob.ListOptions{
|
iter := l.buck.List(&blob.ListOptions{
|
||||||
Prefix: fmt.Sprintf("v2/%s/manifests/", l.name),
|
Prefix: fmt.Sprintf("v2/%s/manifests/", l.name),
|
||||||
Delimiter: "/",
|
Delimiter: "/",
|
||||||
})
|
})
|
||||||
for {
|
for {
|
||||||
|
@ -543,66 +543,66 @@ func (l *StaticRegistryManager) UpdateTagList() error {
|
||||||
//--- Command logic
|
//--- Command logic
|
||||||
|
|
||||||
var containerCmd = &cobra.Command{
|
var containerCmd = &cobra.Command{
|
||||||
Use: "container",
|
Use: "container",
|
||||||
Short: "Manage container images",
|
Short: "Manage container images",
|
||||||
Long: "Publish software on an S3 target following the OCI specification",
|
Long: "Publish software on an S3 target following the OCI specification",
|
||||||
}
|
}
|
||||||
|
|
||||||
var containerTag string
|
var containerTag string
|
||||||
var containerPublishCmd = &cobra.Command{
|
var containerPublishCmd = &cobra.Command{
|
||||||
Use: "push [folder] [remote]", // https://gocloud.dev/howto/blob/#s3-compatible
|
Use: "push [folder] [remote]", // https://gocloud.dev/howto/blob/#s3-compatible
|
||||||
Short: "Publish a container image",
|
Short: "Publish a container image",
|
||||||
Long: "Copy .tar.gz files in the specified folder on the S3 target so that they match the OCI distribution specification",
|
Long: "Copy .tar.gz files in the specified folder on the S3 target so that they match the OCI distribution specification",
|
||||||
Args: cobra.ExactArgs(2),
|
Args: cobra.ExactArgs(2),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
localPath := args[0]
|
localPath := args[0]
|
||||||
remotePath := args[1]
|
remotePath := args[1]
|
||||||
|
|
||||||
oi, err := NewOCIMultiArch(containerTag)
|
oi, err := NewOCIMultiArch(containerTag)
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer oi.Close()
|
|
||||||
|
|
||||||
if err = oi.LoadFromDockerArchives(localPath); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = oi.MergeSystemImages(); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasPrefix(remotePath, "s3:") {
|
|
||||||
// open bucket
|
|
||||||
bucket, err := blob.OpenBucket(context.Background(), remotePath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer bucket.Close()
|
defer oi.Close()
|
||||||
|
|
||||||
// upload image
|
if err = oi.LoadFromDockerArchives(localPath); err != nil {
|
||||||
if err = oi.UploadImageS3(bucket); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// update tag
|
|
||||||
if err = NewStaticRegistryManager(bucket, oi.Name).UpdateTagList(); err != nil {
|
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fmt.Printf("Protocol not supported for remote path %s. Supported transports are s3:// and docker://\n", remotePath)
|
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
}
|
if err = oi.MergeSystemImages(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("✅ push succeeded\n")
|
if strings.HasPrefix(remotePath, "s3:") {
|
||||||
},
|
// open bucket
|
||||||
|
bucket, err := blob.OpenBucket(context.Background(), remotePath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer bucket.Close()
|
||||||
|
|
||||||
|
// upload image
|
||||||
|
if err = oi.UploadImageS3(bucket); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update tag
|
||||||
|
if err = NewStaticRegistryManager(bucket, oi.Name).UpdateTagList(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Protocol not supported for remote path %s. Supported transports are s3:// and docker://\n", remotePath)
|
||||||
|
os.Exit(1)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("✅ push succeeded\n")
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -614,8 +614,8 @@ func init() {
|
||||||
policy := &signature.Policy{Default: []signature.PolicyRequirement{signature.NewPRInsecureAcceptAnything()}}
|
policy := &signature.Policy{Default: []signature.PolicyRequirement{signature.NewPRInsecureAcceptAnything()}}
|
||||||
pctx, err = signature.NewPolicyContext(policy)
|
pctx, err = signature.NewPolicyContext(policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
containerPublishCmd.Flags().StringVarP(&containerTag, "tag", "t", "", "Tag of the project, eg. albatros:0.9")
|
containerPublishCmd.Flags().StringVarP(&containerTag, "tag", "t", "", "Tag of the project, eg. albatros:0.9")
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var RootCmd = &cobra.Command{
|
var RootCmd = &cobra.Command{
|
||||||
Use: "alba",
|
Use: "alba",
|
||||||
Short: "alba is a companion cli for albatros",
|
Short: "alba is a companion cli for albatros",
|
||||||
Long: `A companion CLI for your CI that handle its configuration and artifacts publishing`,
|
Long: `A companion CLI for your CI that handle its configuration and artifacts publishing`,
|
||||||
}
|
}
|
||||||
|
|
105
cmd/static.go
105
cmd/static.go
|
@ -26,7 +26,7 @@ type Tag struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Flavor struct {
|
type Flavor struct {
|
||||||
Resources []Resource `json:"resources"`
|
Resources []Resource `json:"resources"`
|
||||||
Platform RegistryPlatform `json:"platform"`
|
Platform RegistryPlatform `json:"platform"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,21 +36,20 @@ type Resource struct {
|
||||||
|
|
||||||
type RegistryPlatform struct {
|
type RegistryPlatform struct {
|
||||||
Architecture string `json:"architecture"`
|
Architecture string `json:"architecture"`
|
||||||
OS string `json:"os"`
|
OS string `json:"os"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Manifest struct {
|
type Manifest struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
//--- Collect data on the filesystem
|
//--- Collect data on the filesystem
|
||||||
type Platform struct {
|
type Platform struct {
|
||||||
OS string
|
OS string
|
||||||
Arch string
|
Arch string
|
||||||
Root string
|
Root string
|
||||||
Files []string
|
Files []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,11 +82,10 @@ func CollectPlatforms(path string) ([]Platform, error) {
|
||||||
filenames = append(filenames, f.Name())
|
filenames = append(filenames, f.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plat := Platform{
|
||||||
plat := Platform {
|
OS: osDir.Name(),
|
||||||
OS: osDir.Name(),
|
Arch: archDir.Name(),
|
||||||
Arch: archDir.Name(),
|
Root: root,
|
||||||
Root: root,
|
|
||||||
Files: filenames,
|
Files: filenames,
|
||||||
}
|
}
|
||||||
p = append(p, plat)
|
p = append(p, plat)
|
||||||
|
@ -98,9 +96,9 @@ func CollectPlatforms(path string) ([]Platform, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Platform) BuildRegistryPlatform() RegistryPlatform {
|
func (p *Platform) BuildRegistryPlatform() RegistryPlatform {
|
||||||
return RegistryPlatform {
|
return RegistryPlatform{
|
||||||
Architecture: p.Arch,
|
Architecture: p.Arch,
|
||||||
OS: p.OS,
|
OS: p.OS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,8 +112,8 @@ func (p *Platform) BuildResources() []Resource {
|
||||||
|
|
||||||
//---
|
//---
|
||||||
type Artifact struct {
|
type Artifact struct {
|
||||||
Name string
|
Name string
|
||||||
Tag string
|
Tag string
|
||||||
Platforms []Platform
|
Platforms []Platform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +125,7 @@ func NewArtifact(nametag, path string) (Artifact, error) {
|
||||||
|
|
||||||
ar := Artifact{
|
ar := Artifact{
|
||||||
Name: ntspl[0],
|
Name: ntspl[0],
|
||||||
Tag: ntspl[1],
|
Tag: ntspl[1],
|
||||||
}
|
}
|
||||||
|
|
||||||
plat, err := CollectPlatforms(path)
|
plat, err := CollectPlatforms(path)
|
||||||
|
@ -140,7 +138,7 @@ func NewArtifact(nametag, path string) (Artifact, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Artifact) UpdateManifest() Manifest {
|
func (a *Artifact) UpdateManifest() Manifest {
|
||||||
return Manifest {
|
return Manifest{
|
||||||
Name: a.Name,
|
Name: a.Name,
|
||||||
Tags: []string{a.Tag}, //@FIXME we must fetch the other tags of the repo
|
Tags: []string{a.Tag}, //@FIXME we must fetch the other tags of the repo
|
||||||
}
|
}
|
||||||
|
@ -149,9 +147,9 @@ func (a *Artifact) UpdateManifest() Manifest {
|
||||||
func (a *Artifact) BuildTag() Tag {
|
func (a *Artifact) BuildTag() Tag {
|
||||||
t := Tag{Flavors: []Flavor{}}
|
t := Tag{Flavors: []Flavor{}}
|
||||||
for _, p := range a.Platforms {
|
for _, p := range a.Platforms {
|
||||||
f := Flavor {
|
f := Flavor{
|
||||||
Resources: p.BuildResources(),
|
Resources: p.BuildResources(),
|
||||||
Platform: p.BuildRegistryPlatform(),
|
Platform: p.BuildRegistryPlatform(),
|
||||||
}
|
}
|
||||||
t.Flavors = append(t.Flavors, f)
|
t.Flavors = append(t.Flavors, f)
|
||||||
}
|
}
|
||||||
|
@ -208,10 +206,11 @@ func (a *Artifact) Upload(buck *blob.Bucket) error {
|
||||||
//---
|
//---
|
||||||
//--- Bucket Wrapper
|
//--- Bucket Wrapper
|
||||||
type BucketUploader struct {
|
type BucketUploader struct {
|
||||||
bucket *blob.Bucket
|
bucket *blob.Bucket
|
||||||
reader io.ReadCloser
|
reader io.ReadCloser
|
||||||
options *blob.WriterOptions
|
options *blob.WriterOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUploadFromFS(buck *blob.Bucket, path string) (*BucketUploader, error) {
|
func NewUploadFromFS(buck *blob.Bucket, path string) (*BucketUploader, error) {
|
||||||
fd, err := os.Open(path)
|
fd, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -277,45 +276,45 @@ func (bu *BucketUploader) UploadTo(key string) error {
|
||||||
//--- Command logic
|
//--- Command logic
|
||||||
|
|
||||||
var staticCmd = &cobra.Command{
|
var staticCmd = &cobra.Command{
|
||||||
Use: "static",
|
Use: "static",
|
||||||
Short: "Manage static artifacts",
|
Short: "Manage static artifacts",
|
||||||
Long: "There are many ways to ship software, one is simply to publish a bunch of files on a mirror.",
|
Long: "There are many ways to ship software, one is simply to publish a bunch of files on a mirror.",
|
||||||
}
|
}
|
||||||
|
|
||||||
var tag string
|
var tag string
|
||||||
var publishCmd = &cobra.Command{
|
var publishCmd = &cobra.Command{
|
||||||
Use: "push [folder] [remote]", // https://gocloud.dev/howto/blob/#s3-compatible
|
Use: "push [folder] [remote]", // https://gocloud.dev/howto/blob/#s3-compatible
|
||||||
Short: "Publish a static artifact",
|
Short: "Publish a static artifact",
|
||||||
Long: "Sending logic for a static artifact",
|
Long: "Sending logic for a static artifact",
|
||||||
Args: cobra.ExactArgs(2),
|
Args: cobra.ExactArgs(2),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
localFolder := args[0]
|
localFolder := args[0]
|
||||||
remoteUrl := args[1]
|
remoteUrl := args[1]
|
||||||
|
|
||||||
// build artifact in memory
|
// build artifact in memory
|
||||||
art, err := NewArtifact(tag, localFolder)
|
art, err := NewArtifact(tag, localFolder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// open bucket
|
// open bucket
|
||||||
bucket, err := blob.OpenBucket(context.Background(), remoteUrl)
|
bucket, err := blob.OpenBucket(context.Background(), remoteUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer bucket.Close()
|
defer bucket.Close()
|
||||||
|
|
||||||
// send artifacts
|
// send artifacts
|
||||||
err = art.Upload(bucket)
|
err = art.Upload(bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("✅ push succeeded\n")
|
fmt.Printf("✅ push succeeded\n")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
consul "github.com/hashicorp/consul/api"
|
consul "github.com/hashicorp/consul/api"
|
||||||
nomad "github.com/hashicorp/nomad/api"
|
nomad "github.com/hashicorp/nomad/api"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type Cluster struct {
|
type Cluster struct {
|
||||||
Nomad *nomad.Client
|
Nomad *nomad.Client
|
||||||
Consul *consul.Client
|
Consul *consul.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCluster(conf* Config) Cluster {
|
func NewCluster(conf *Config) Cluster {
|
||||||
cluster := Cluster{}
|
cluster := Cluster{}
|
||||||
|
|
||||||
// Init Nomad
|
// Init Nomad
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"fmt"
|
||||||
"fmt"
|
"github.com/caarlos0/env/v7"
|
||||||
"github.com/caarlos0/env/v7"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
|
|
@ -4,23 +4,23 @@ import (
|
||||||
b64 "encoding/base64"
|
b64 "encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
nomad "github.com/hashicorp/nomad/api"
|
nomad "github.com/hashicorp/nomad/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HookHandler struct {
|
type HookHandler struct {
|
||||||
Config *Config
|
Config *Config
|
||||||
Cluster *Cluster
|
Cluster *Cluster
|
||||||
}
|
}
|
||||||
|
|
||||||
type BuildHandler struct {
|
type BuildHandler struct {
|
||||||
Config *Config
|
Config *Config
|
||||||
Cluster *Cluster
|
Cluster *Cluster
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h HookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h HookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -101,13 +101,13 @@ func (h HookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("Created job %s for %s\n", dres.DispatchedJobID, notifInfo)
|
log.Printf("Created job %s for %s\n", dres.DispatchedJobID, notifInfo)
|
||||||
|
|
||||||
// Start a lifecycle observer to update gitea status
|
// Start a lifecycle observer to update gitea status
|
||||||
j := Job {
|
j := Job{
|
||||||
Cluster: h.Cluster,
|
Cluster: h.Cluster,
|
||||||
Config: h.Config,
|
Config: h.Config,
|
||||||
Notification: ¬ification,
|
Notification: ¬ification,
|
||||||
Dispatch: dres,
|
Dispatch: dres,
|
||||||
Creds: &repoDesc.Gitea,
|
Creds: &repoDesc.Gitea,
|
||||||
Flavor: flavor,
|
Flavor: flavor,
|
||||||
}
|
}
|
||||||
go j.follow()
|
go j.follow()
|
||||||
|
|
||||||
|
|
12
pkg/job.go
12
pkg/job.go
|
@ -1,18 +1,18 @@
|
||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
nomad "github.com/hashicorp/nomad/api"
|
nomad "github.com/hashicorp/nomad/api"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Job struct {
|
type Job struct {
|
||||||
Cluster *Cluster
|
Cluster *Cluster
|
||||||
Config *Config
|
Config *Config
|
||||||
Notification *GiteaNotification
|
Notification *GiteaNotification
|
||||||
Dispatch *nomad.JobDispatchResponse
|
Dispatch *nomad.JobDispatchResponse
|
||||||
Creds *SecretGitea
|
Creds *SecretGitea
|
||||||
Flavor string
|
Flavor string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Job) follow() {
|
func (j *Job) follow() {
|
||||||
|
|
Loading…
Reference in a new issue