refactor: internal actions package #8
15 changed files with 306 additions and 393 deletions
|
@ -1,4 +1,4 @@
|
||||||
package deploy
|
package actions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flow/services/internal"
|
"flow/services/internal"
|
||||||
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/magefile/mage/sh"
|
"github.com/magefile/mage/sh"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Deploy(dockerHost, environment, name string, daemon bool) error {
|
func Deploy(dockerHost, environment, service string, daemon bool) error {
|
||||||
os.Setenv("DOCKER_HOST", dockerHost)
|
os.Setenv("DOCKER_HOST", dockerHost)
|
||||||
|
|
||||||
command := []string{
|
command := []string{
|
||||||
|
@ -24,8 +24,8 @@ func Deploy(dockerHost, environment, name string, daemon bool) error {
|
||||||
command = append(command, "-d")
|
command = append(command, "-d")
|
||||||
}
|
}
|
||||||
|
|
||||||
if name != "all" {
|
if service != "all" {
|
||||||
command = append(command, name)
|
command = append(command, service)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sh.RunV(command[0], command[1:]...)
|
return sh.RunV(command[0], command[1:]...)
|
|
@ -1,6 +1,7 @@
|
||||||
package download
|
package actions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flow/services/internal/bundle"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -10,48 +11,25 @@ import (
|
||||||
"github.com/magefile/mage/sh"
|
"github.com/magefile/mage/sh"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Bundle struct {
|
|
||||||
DestinationDir string
|
|
||||||
Packages []Pack
|
|
||||||
Checksum Checksum
|
|
||||||
ValidateGPGSignature bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type Pack struct {
|
|
||||||
File Object
|
|
||||||
GPGSignature Object
|
|
||||||
}
|
|
||||||
|
|
||||||
type Checksum struct {
|
|
||||||
File Object
|
|
||||||
Validate bool
|
|
||||||
ValidateFunc func() error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Object struct {
|
|
||||||
Source string
|
|
||||||
Destination string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Download downloads all the files in the download pack,
|
// Download downloads all the files in the download pack,
|
||||||
// verifies all the GPG signatures (if enabled) and
|
// verifies all the GPG signatures (if enabled) and
|
||||||
// verifies the checksums (if enabled).
|
// verifies the checksums (if enabled).
|
||||||
func Download(bundle Bundle) error {
|
func Download(b bundle.Bundle) error {
|
||||||
if err := os.MkdirAll(bundle.DestinationDir, 0o750); err != nil {
|
if err := os.MkdirAll(b.DestinationDir, 0o750); err != nil {
|
||||||
return fmt.Errorf("unable to make '%s'; %w", bundle.DestinationDir, err)
|
return fmt.Errorf("unable to make '%s'; %w", b.DestinationDir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var objects []Object
|
var objects []bundle.Object
|
||||||
|
|
||||||
for i := range bundle.Packages {
|
for i := range b.Packages {
|
||||||
objects = append(objects, bundle.Packages[i].File)
|
objects = append(objects, b.Packages[i].File)
|
||||||
if bundle.ValidateGPGSignature {
|
if b.ValidateGPGSignature {
|
||||||
objects = append(objects, bundle.Packages[i].GPGSignature)
|
objects = append(objects, b.Packages[i].GPGSignature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if bundle.Checksum.Validate {
|
if b.Checksum.Validate {
|
||||||
objects = append(objects, bundle.Checksum.File)
|
objects = append(objects, b.Checksum.File)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, object := range objects {
|
for _, object := range objects {
|
||||||
|
@ -94,20 +72,20 @@ func Download(bundle Bundle) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if bundle.ValidateGPGSignature {
|
if b.ValidateGPGSignature {
|
||||||
for i := range bundle.Packages {
|
for i := range b.Packages {
|
||||||
if err := sh.RunV("gpg", "--verify", bundle.Packages[i].GPGSignature.Destination, bundle.Packages[i].File.Destination); err != nil {
|
if err := sh.RunV("gpg", "--verify", b.Packages[i].GPGSignature.Destination, b.Packages[i].File.Destination); err != nil {
|
||||||
return fmt.Errorf("GPG verification failed for '%s'; %w", bundle.Packages[i].File.Destination, err)
|
return fmt.Errorf("GPG verification failed for '%s'; %w", b.Packages[i].File.Destination, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if bundle.Checksum.Validate {
|
if b.Checksum.Validate {
|
||||||
var err error
|
var err error
|
||||||
if bundle.Checksum.ValidateFunc != nil {
|
if b.Checksum.ValidateFunc != nil {
|
||||||
err = bundle.Checksum.ValidateFunc()
|
err = b.Checksum.ValidateFunc()
|
||||||
} else {
|
} else {
|
||||||
err = validateChecksum(bundle.DestinationDir, bundle.Checksum.File.Destination)
|
err = validateChecksum(b.DestinationDir, b.Checksum.File.Destination)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
|
@ -1,4 +1,4 @@
|
||||||
package prepare
|
package actions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -10,6 +10,7 @@ import (
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"flow/services/internal"
|
"flow/services/internal"
|
||||||
|
"flow/services/internal/bundle"
|
||||||
"flow/services/internal/config"
|
"flow/services/internal/config"
|
||||||
"flow/services/internal/services"
|
"flow/services/internal/services"
|
||||||
"flow/services/internal/services/forgejo"
|
"flow/services/internal/services/forgejo"
|
||||||
|
@ -81,7 +82,7 @@ func prepareService(cfg config.Config, environment, service string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := downloadServiceFiles(cfg, environment, service); err != nil {
|
if err := downloadBundle(cfg, environment, service); err != nil {
|
||||||
return fmt.Errorf("error downloading service files for %q; %w", service, err)
|
return fmt.Errorf("error downloading service files for %q; %w", service, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,25 +97,23 @@ func prepareService(cfg config.Config, environment, service string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadServiceFiles(cfg config.Config, environment, service string) error {
|
func downloadBundle(cfg config.Config, environment, service string) error {
|
||||||
|
var b bundle.Bundle
|
||||||
|
|
||||||
switch service {
|
switch service {
|
||||||
case services.Forgejo:
|
case services.Forgejo:
|
||||||
obj := forgejo.NewForgejo(environment, cfg.Forgejo.Version)
|
b = forgejo.Bundle(environment, cfg.Forgejo.Version)
|
||||||
if err := obj.Download(); err != nil {
|
|
||||||
return fmt.Errorf("error downloading the files for %q; %w", services.Forgejo, err)
|
|
||||||
}
|
|
||||||
case services.Gotosocial:
|
case services.Gotosocial:
|
||||||
obj := gotosocial.NewGotosocial(environment, cfg.GoToSocial.Version)
|
b = gotosocial.Bundle(environment, cfg.GoToSocial.Version)
|
||||||
if err := obj.Download(); err != nil {
|
|
||||||
return fmt.Errorf("error downloading the files for %q; %w", services.Gotosocial, err)
|
|
||||||
}
|
|
||||||
case services.Woodpecker:
|
case services.Woodpecker:
|
||||||
obj := woodpecker.NewWoodpecker(environment, cfg.Woodpecker.Version)
|
b = woodpecker.Bundle(environment, cfg.Woodpecker.Version)
|
||||||
if err := obj.Download(); err != nil {
|
|
||||||
return fmt.Errorf("error downloading the files for %q; %w", services.Woodpecker, err)
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
fmt.Printf("There's no files to download for %q.\n", service)
|
fmt.Printf("There's no files to download for %q.\n", service)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := Download(b); err != nil {
|
||||||
|
return fmt.Errorf("error downloading the files for %q; %w", service, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
24
internal/actions/stop.go
Normal file
24
internal/actions/stop.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package actions
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flow/services/internal"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/magefile/mage/sh"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Stop(dockerHost, environment, service string) error {
|
||||||
|
os.Setenv("DOCKER_HOST", dockerHost)
|
||||||
|
|
||||||
|
command := []string{
|
||||||
|
"docker",
|
||||||
|
"compose",
|
||||||
|
"--project-directory",
|
||||||
|
fmt.Sprintf("%s/%s/compose", internal.RootBuildDir, environment),
|
||||||
|
"stop",
|
||||||
|
service,
|
||||||
|
}
|
||||||
|
|
||||||
|
return sh.RunV(command[0], command[1:]...)
|
||||||
|
}
|
24
internal/bundle/bundle.go
Normal file
24
internal/bundle/bundle.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package bundle
|
||||||
|
|
||||||
|
type Bundle struct {
|
||||||
|
DestinationDir string
|
||||||
|
Packages []Pack
|
||||||
|
Checksum Checksum
|
||||||
|
ValidateGPGSignature bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pack struct {
|
||||||
|
File Object
|
||||||
|
GPGSignature Object
|
||||||
|
}
|
||||||
|
|
||||||
|
type Checksum struct {
|
||||||
|
File Object
|
||||||
|
Validate bool
|
||||||
|
ValidateFunc func() error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Object struct {
|
||||||
|
Source string
|
||||||
|
Destination string
|
||||||
|
}
|
58
internal/services/forgejo/bundle.go
Normal file
58
internal/services/forgejo/bundle.go
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package forgejo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"flow/services/internal"
|
||||||
|
"flow/services/internal/bundle"
|
||||||
|
"flow/services/internal/services"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
binaryURLFormat = "https://codeberg.org/forgejo/forgejo/releases/download/v%s/forgejo-%s-linux-amd64"
|
||||||
|
signatureURLFormat = "https://codeberg.org/forgejo/forgejo/releases/download/v%s/forgejo-%s-linux-amd64.asc"
|
||||||
|
checksumURLFormat = "https://codeberg.org/forgejo/forgejo/releases/download/v%s/forgejo-%s-linux-amd64.sha256"
|
||||||
|
forgejoBinaryFileFormat = "forgejo-%s-linux-amd64"
|
||||||
|
forgejoDigestExtension = ".sha256"
|
||||||
|
forgejoSignatureExtension = ".asc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Bundle(environment, version string) bundle.Bundle {
|
||||||
|
var (
|
||||||
|
destinationDir = filepath.Join(internal.RootBuildDir, environment, services.Forgejo)
|
||||||
|
binaryURL = fmt.Sprintf(binaryURLFormat, version, version)
|
||||||
|
binaryPath = filepath.Join(destinationDir, fmt.Sprintf(forgejoBinaryFileFormat, version))
|
||||||
|
signatureURL = fmt.Sprintf(signatureURLFormat, version, version)
|
||||||
|
signaturePath = binaryPath + forgejoSignatureExtension
|
||||||
|
checksumURL = fmt.Sprintf(checksumURLFormat, version, version)
|
||||||
|
checksumPath = binaryPath + forgejoDigestExtension
|
||||||
|
)
|
||||||
|
|
||||||
|
bundle := bundle.Bundle{
|
||||||
|
DestinationDir: destinationDir,
|
||||||
|
Packages: []bundle.Pack{
|
||||||
|
{
|
||||||
|
File: bundle.Object{
|
||||||
|
Source: binaryURL,
|
||||||
|
Destination: binaryPath,
|
||||||
|
},
|
||||||
|
GPGSignature: bundle.Object{
|
||||||
|
Source: signatureURL,
|
||||||
|
Destination: signaturePath,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ValidateGPGSignature: true,
|
||||||
|
Checksum: bundle.Checksum{
|
||||||
|
File: bundle.Object{
|
||||||
|
Source: checksumURL,
|
||||||
|
Destination: checksumPath,
|
||||||
|
},
|
||||||
|
Validate: true,
|
||||||
|
ValidateFunc: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return bundle
|
||||||
|
}
|
|
@ -1,40 +0,0 @@
|
||||||
package forgejo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"flow/services/internal/download"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (f Forgejo) Download() error {
|
|
||||||
bundle := download.Bundle{
|
|
||||||
DestinationDir: f.destinationDir,
|
|
||||||
Packages: []download.Pack{
|
|
||||||
{
|
|
||||||
File: download.Object{
|
|
||||||
Source: f.binaryURL,
|
|
||||||
Destination: f.binaryPath,
|
|
||||||
},
|
|
||||||
GPGSignature: download.Object{
|
|
||||||
Source: f.signatureURL,
|
|
||||||
Destination: f.signaturePath,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ValidateGPGSignature: true,
|
|
||||||
Checksum: download.Checksum{
|
|
||||||
File: download.Object{
|
|
||||||
Source: f.checksumURL,
|
|
||||||
Destination: f.checksumPath,
|
|
||||||
},
|
|
||||||
Validate: true,
|
|
||||||
ValidateFunc: nil,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := download.Download(bundle); err != nil {
|
|
||||||
return fmt.Errorf("error downloading files for Forgejo; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package forgejo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"flow/services/internal"
|
|
||||||
"flow/services/internal/services"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Forgejo struct {
|
|
||||||
binaryURL string
|
|
||||||
binaryPath string
|
|
||||||
signatureURL string
|
|
||||||
signaturePath string
|
|
||||||
checksumURL string
|
|
||||||
checksumPath string
|
|
||||||
destinationDir string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewForgejo(environment, version string) Forgejo {
|
|
||||||
forgejoBinaryFileFormat := "forgejo-%s-linux-amd64"
|
|
||||||
forgejoDigestExtension := ".sha256"
|
|
||||||
forgejoSignatureExtension := ".asc"
|
|
||||||
destinationDir := filepath.Join(internal.RootBuildDir, environment, services.Forgejo)
|
|
||||||
binaryPath := filepath.Join(destinationDir, fmt.Sprintf(forgejoBinaryFileFormat, version))
|
|
||||||
|
|
||||||
forgejo := Forgejo{
|
|
||||||
destinationDir: destinationDir,
|
|
||||||
binaryURL: fmt.Sprintf(
|
|
||||||
"https://codeberg.org/forgejo/forgejo/releases/download/v%s/forgejo-%s-linux-amd64",
|
|
||||||
version,
|
|
||||||
version,
|
|
||||||
),
|
|
||||||
|
|
||||||
binaryPath: filepath.Join(
|
|
||||||
destinationDir,
|
|
||||||
fmt.Sprintf(forgejoBinaryFileFormat, version),
|
|
||||||
),
|
|
||||||
|
|
||||||
signatureURL: fmt.Sprintf(
|
|
||||||
"https://codeberg.org/forgejo/forgejo/releases/download/v%s/forgejo-%s-linux-amd64.asc",
|
|
||||||
version,
|
|
||||||
version,
|
|
||||||
),
|
|
||||||
|
|
||||||
signaturePath: binaryPath + forgejoSignatureExtension,
|
|
||||||
|
|
||||||
checksumURL: fmt.Sprintf(
|
|
||||||
"https://codeberg.org/forgejo/forgejo/releases/download/v%s/forgejo-%s-linux-amd64.sha256",
|
|
||||||
version,
|
|
||||||
version,
|
|
||||||
),
|
|
||||||
|
|
||||||
checksumPath: binaryPath + forgejoDigestExtension,
|
|
||||||
}
|
|
||||||
|
|
||||||
return forgejo
|
|
||||||
}
|
|
57
internal/services/gotosocial/bundle.go
Normal file
57
internal/services/gotosocial/bundle.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package gotosocial
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"flow/services/internal"
|
||||||
|
"flow/services/internal/bundle"
|
||||||
|
"flow/services/internal/services"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
binaryTarURLFormat = "https://github.com/superseriousbusiness/gotosocial/releases/download/v%s/gotosocial_%s_linux_amd64.tar.gz"
|
||||||
|
webAssetsTarURLFormat = "https://github.com/superseriousbusiness/gotosocial/releases/download/v%s/gotosocial_%s_web-assets.tar.gz"
|
||||||
|
checksumURLFormat = "https://github.com/superseriousbusiness/gotosocial/releases/download/v%s/checksums.txt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Bundle(environment, version string) bundle.Bundle {
|
||||||
|
var (
|
||||||
|
destinationDir = filepath.Join(internal.RootBuildDir, environment, services.Gotosocial)
|
||||||
|
binaryTarURL = fmt.Sprintf(binaryTarURLFormat, version, version)
|
||||||
|
binaryTarFilepath = filepath.Join(destinationDir, fmt.Sprintf("gotosocial_%s_linux_amd64.tar.gz", version))
|
||||||
|
webAssetsTarURL = fmt.Sprintf(webAssetsTarURLFormat, version, version)
|
||||||
|
webAssetsFilepath = filepath.Join(destinationDir, fmt.Sprintf("gotosocial_%s_web-assets.tar.gz", version))
|
||||||
|
checksumURL = fmt.Sprintf(checksumURLFormat, version)
|
||||||
|
checksumPath = filepath.Join(destinationDir, fmt.Sprintf("gotosocial_%s_checksums.txt", version))
|
||||||
|
)
|
||||||
|
|
||||||
|
bundle := bundle.Bundle{
|
||||||
|
DestinationDir: destinationDir,
|
||||||
|
Packages: []bundle.Pack{
|
||||||
|
{
|
||||||
|
File: bundle.Object{
|
||||||
|
Source: binaryTarURL,
|
||||||
|
Destination: binaryTarFilepath,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
File: bundle.Object{
|
||||||
|
Source: webAssetsTarURL,
|
||||||
|
Destination: webAssetsFilepath,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ValidateGPGSignature: false,
|
||||||
|
Checksum: bundle.Checksum{
|
||||||
|
File: bundle.Object{
|
||||||
|
Source: checksumURL,
|
||||||
|
Destination: checksumPath,
|
||||||
|
},
|
||||||
|
Validate: true,
|
||||||
|
ValidateFunc: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return bundle
|
||||||
|
}
|
|
@ -1,43 +0,0 @@
|
||||||
package gotosocial
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"flow/services/internal/download"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Download downloads and validates the files for GoToSocial.
|
|
||||||
func (g Gotosocial) Download() error {
|
|
||||||
bundle := download.Bundle{
|
|
||||||
DestinationDir: g.destinationDir,
|
|
||||||
Packages: []download.Pack{
|
|
||||||
{
|
|
||||||
File: download.Object{
|
|
||||||
Source: g.binaryTarURL,
|
|
||||||
Destination: g.binaryTarFilepath,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
File: download.Object{
|
|
||||||
Source: g.webAssetsTarURL,
|
|
||||||
Destination: g.webAssetsFilepath,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ValidateGPGSignature: false,
|
|
||||||
Checksum: download.Checksum{
|
|
||||||
File: download.Object{
|
|
||||||
Source: g.checksumURL,
|
|
||||||
Destination: g.checksumPath,
|
|
||||||
},
|
|
||||||
Validate: true,
|
|
||||||
ValidateFunc: nil,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := download.Download(bundle); err != nil {
|
|
||||||
return fmt.Errorf("error downloading the files for Gotosocial; %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package gotosocial
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"flow/services/internal"
|
|
||||||
"flow/services/internal/services"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Gotosocial struct {
|
|
||||||
binaryTarURL string
|
|
||||||
binaryTarFilepath string
|
|
||||||
checksumURL string
|
|
||||||
checksumPath string
|
|
||||||
webAssetsTarURL string
|
|
||||||
webAssetsFilepath string
|
|
||||||
destinationDir string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGotosocial(environment, version string) Gotosocial {
|
|
||||||
destinationDir := filepath.Join(internal.RootBuildDir, environment, services.Gotosocial)
|
|
||||||
|
|
||||||
gotosocial := Gotosocial{
|
|
||||||
destinationDir: destinationDir,
|
|
||||||
binaryTarURL: fmt.Sprintf(
|
|
||||||
"https://github.com/superseriousbusiness/gotosocial/releases/download/v%s/gotosocial_%s_linux_amd64.tar.gz",
|
|
||||||
version,
|
|
||||||
version,
|
|
||||||
),
|
|
||||||
binaryTarFilepath: filepath.Join(destinationDir, fmt.Sprintf("gotosocial_%s_linux_amd64.tar.gz", version)),
|
|
||||||
|
|
||||||
webAssetsTarURL: fmt.Sprintf(
|
|
||||||
"https://github.com/superseriousbusiness/gotosocial/releases/download/v%s/gotosocial_%s_web-assets.tar.gz",
|
|
||||||
version,
|
|
||||||
version,
|
|
||||||
),
|
|
||||||
webAssetsFilepath: filepath.Join(destinationDir, fmt.Sprintf("gotosocial_%s_web-assets.tar.gz", version)),
|
|
||||||
|
|
||||||
checksumURL: fmt.Sprintf(
|
|
||||||
"https://github.com/superseriousbusiness/gotosocial/releases/download/v%s/checksums.txt",
|
|
||||||
version,
|
|
||||||
),
|
|
||||||
checksumPath: filepath.Join(destinationDir, fmt.Sprintf("gotosocial_%s_checksums.txt", version)),
|
|
||||||
}
|
|
||||||
|
|
||||||
return gotosocial
|
|
||||||
}
|
|
99
internal/services/woodpecker/bundle.go
Normal file
99
internal/services/woodpecker/bundle.go
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
package woodpecker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"flow/services/internal"
|
||||||
|
"flow/services/internal/bundle"
|
||||||
|
"flow/services/internal/services"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
binaryTarURLFormat = "https://github.com/woodpecker-ci/woodpecker/releases/download/v%s/woodpecker-server_linux_amd64.tar.gz"
|
||||||
|
checksumURLFormat = "https://github.com/woodpecker-ci/woodpecker/releases/download/v%s/checksums.txt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Bundle(environment, version string) bundle.Bundle {
|
||||||
|
var (
|
||||||
|
destinationDir = filepath.Join(internal.RootBuildDir, environment, services.Woodpecker)
|
||||||
|
binaryTarURL = fmt.Sprintf(binaryTarURLFormat, version)
|
||||||
|
binaryTarPath = filepath.Join(destinationDir, fmt.Sprintf("woodpecker-server-%s_linux_amd64.tar.gz", version))
|
||||||
|
checksumURL = fmt.Sprintf(checksumURLFormat, version)
|
||||||
|
checksumPath = filepath.Join(destinationDir, fmt.Sprintf("woodpecker_%s_checksums.txt", version))
|
||||||
|
)
|
||||||
|
|
||||||
|
bundle := bundle.Bundle{
|
||||||
|
DestinationDir: destinationDir,
|
||||||
|
Packages: []bundle.Pack{
|
||||||
|
{
|
||||||
|
File: bundle.Object{
|
||||||
|
Source: binaryTarURL,
|
||||||
|
Destination: binaryTarPath,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ValidateGPGSignature: false,
|
||||||
|
Checksum: bundle.Checksum{
|
||||||
|
File: bundle.Object{
|
||||||
|
Source: checksumURL,
|
||||||
|
Destination: checksumPath,
|
||||||
|
},
|
||||||
|
Validate: true,
|
||||||
|
ValidateFunc: checksumValidationFunc(binaryTarPath, checksumPath),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return bundle
|
||||||
|
}
|
||||||
|
|
||||||
|
func checksumValidationFunc(binaryTarPath, checksumPath string) func() error {
|
||||||
|
return func() error {
|
||||||
|
var wantChecksum, gotChecksum string
|
||||||
|
|
||||||
|
// get the tar file's checksum
|
||||||
|
tarFile, err := os.Open(binaryTarPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to open %s; %w", binaryTarPath, err)
|
||||||
|
}
|
||||||
|
defer tarFile.Close()
|
||||||
|
|
||||||
|
h := sha256.New()
|
||||||
|
|
||||||
|
if _, err = io.Copy(h, tarFile); err != nil {
|
||||||
|
return fmt.Errorf("unable to get the shasum for %s; %w", binaryTarPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gotChecksum = fmt.Sprintf("%x", h.Sum(nil))
|
||||||
|
|
||||||
|
// get the expected checksum from the checksum file
|
||||||
|
checksumFile, err := os.Open(checksumPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to open %s; %w", checksumPath, err)
|
||||||
|
}
|
||||||
|
defer checksumFile.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(checksumFile)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if strings.Contains(line, "woodpecker-server_linux_amd64.tar.gz") {
|
||||||
|
wantChecksum = strings.Split(line, " ")[0]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare the two checksum strings
|
||||||
|
if gotChecksum != wantChecksum {
|
||||||
|
return fmt.Errorf("checksum validation failed: want %s, got %s", wantChecksum, gotChecksum)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Checksum validation successful: %s\n", gotChecksum)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,85 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"crypto/sha256"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"flow/services/internal/download"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (w Woodpecker) Download() error {
|
|
||||||
bundle := download.Bundle{
|
|
||||||
DestinationDir: w.destinationDir,
|
|
||||||
Packages: []download.Pack{
|
|
||||||
{
|
|
||||||
File: download.Object{
|
|
||||||
Source: w.binaryTarURL,
|
|
||||||
Destination: w.binaryTarPath,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ValidateGPGSignature: false,
|
|
||||||
Checksum: download.Checksum{
|
|
||||||
File: download.Object{
|
|
||||||
Source: w.checksumURL,
|
|
||||||
Destination: w.checksumPath,
|
|
||||||
},
|
|
||||||
Validate: true,
|
|
||||||
ValidateFunc: w.checksumValidation,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := download.Download(bundle); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w Woodpecker) checksumValidation() error {
|
|
||||||
var wantChecksum, gotChecksum string
|
|
||||||
|
|
||||||
// get the tar file's checksum
|
|
||||||
tarFile, err := os.Open(w.binaryTarPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to open %s; %w", w.binaryTarPath, err)
|
|
||||||
}
|
|
||||||
defer tarFile.Close()
|
|
||||||
|
|
||||||
h := sha256.New()
|
|
||||||
|
|
||||||
if _, err = io.Copy(h, tarFile); err != nil {
|
|
||||||
return fmt.Errorf("unable to get the shasum for %s; %w", w.binaryTarPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
gotChecksum = fmt.Sprintf("%x", h.Sum(nil))
|
|
||||||
|
|
||||||
// get the expected checksum from the checksum file
|
|
||||||
checksumFile, err := os.Open(w.checksumPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to open %s; %w", w.checksumPath, err)
|
|
||||||
}
|
|
||||||
defer checksumFile.Close()
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(checksumFile)
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Text()
|
|
||||||
if strings.Contains(line, "woodpecker-server_linux_amd64.tar.gz") {
|
|
||||||
wantChecksum = strings.Split(line, " ")[0]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// compare the two checksum strings
|
|
||||||
if gotChecksum != wantChecksum {
|
|
||||||
return fmt.Errorf("checksum validation failed: want %s, got %s", wantChecksum, gotChecksum)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("Checksum validation successful: %s\n", gotChecksum)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"flow/services/internal"
|
|
||||||
"flow/services/internal/services"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Woodpecker struct {
|
|
||||||
binaryTarURL string
|
|
||||||
binaryTarPath string
|
|
||||||
checksumURL string
|
|
||||||
checksumPath string
|
|
||||||
destinationDir string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWoodpecker(environment, version string) Woodpecker {
|
|
||||||
destinationDir := filepath.Join(internal.RootBuildDir, environment, services.Woodpecker)
|
|
||||||
|
|
||||||
woodpecker := Woodpecker{
|
|
||||||
destinationDir: destinationDir,
|
|
||||||
binaryTarURL: fmt.Sprintf(
|
|
||||||
"https://github.com/woodpecker-ci/woodpecker/releases/download/v%s/woodpecker-server_linux_amd64.tar.gz",
|
|
||||||
version,
|
|
||||||
),
|
|
||||||
binaryTarPath: filepath.Join(
|
|
||||||
destinationDir,
|
|
||||||
fmt.Sprintf("woodpecker-server-%s_linux_amd64.tar.gz", version),
|
|
||||||
),
|
|
||||||
checksumURL: fmt.Sprintf(
|
|
||||||
"https://github.com/woodpecker-ci/woodpecker/releases/download/v%s/checksums.txt",
|
|
||||||
version,
|
|
||||||
),
|
|
||||||
checksumPath: filepath.Join(
|
|
||||||
destinationDir,
|
|
||||||
fmt.Sprintf("woodpecker_%s_checksums.txt", version),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
return woodpecker
|
|
||||||
}
|
|
|
@ -4,9 +4,8 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flow/services/internal"
|
"flow/services/internal"
|
||||||
|
"flow/services/internal/actions"
|
||||||
"flow/services/internal/config"
|
"flow/services/internal/config"
|
||||||
"flow/services/internal/deploy"
|
|
||||||
"flow/services/internal/prepare"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -48,7 +47,7 @@ func Deploy(environment, service string) error {
|
||||||
return fmt.Errorf("unable to load the configuration; %w", err)
|
return fmt.Errorf("unable to load the configuration; %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := deploy.Deploy(cfg.Docker.Host, environment, service, true); err != nil {
|
if err := actions.Deploy(cfg.Docker.Host, environment, service, true); err != nil {
|
||||||
return fmt.Errorf("error deploying %q; %w", service, err)
|
return fmt.Errorf("error deploying %q; %w", service, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +56,7 @@ func Deploy(environment, service string) error {
|
||||||
|
|
||||||
// Prepare prepares the service's build directory.
|
// Prepare prepares the service's build directory.
|
||||||
func Prepare(environment, service string) error {
|
func Prepare(environment, service string) error {
|
||||||
if err := prepare.Prepare(environment, service); err != nil {
|
if err := actions.Prepare(environment, service); err != nil {
|
||||||
return fmt.Errorf("error running preparations; %w", err)
|
return fmt.Errorf("error running preparations; %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,16 +90,9 @@ func Stop(environment, service string) error {
|
||||||
return fmt.Errorf("unable to load the configuration; %w", err)
|
return fmt.Errorf("unable to load the configuration; %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Setenv("DOCKER_HOST", cfg.Docker.Host)
|
if err := actions.Stop(cfg.Docker.Host, environment, service); err != nil {
|
||||||
|
return fmt.Errorf("error stopping %q; %w", service, err)
|
||||||
command := []string{
|
|
||||||
"docker",
|
|
||||||
"compose",
|
|
||||||
"--project-directory",
|
|
||||||
fmt.Sprintf("%s/%s/compose", internal.RootBuildDir, environment),
|
|
||||||
"stop",
|
|
||||||
service,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sh.RunV(command[0], command[1:]...)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue