Add bpm-package functionality
This commit is contained in:
parent
2dec7c28e6
commit
4235252172
1
config/bpm-utils.conf
Normal file
1
config/bpm-utils.conf
Normal file
@ -0,0 +1 @@
|
|||||||
|
privilege_escalator_cmd: "sudo"
|
@ -1,3 +1,8 @@
|
|||||||
module git.enumerated.dev/bubble-package-manager/bpm-utils/src/bpm-package
|
module git.enumerated.dev/bubble-package-manager/bpm-utils/src/bpm-package
|
||||||
|
|
||||||
go 1.23
|
go 1.23
|
||||||
|
|
||||||
|
require gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
require bpm-utils-shared v1.0.0
|
||||||
|
|
||||||
|
replace bpm-utils-shared => ../bpm-utils-shared
|
3
src/bpm-package/go.sum
Normal file
3
src/bpm-package/go.sum
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
@ -1,7 +1,213 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
bpm_utils_shared "bpm-utils-shared"
|
||||||
|
"bufio"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var compile = flag.Bool("c", false, "Compile BPM source package")
|
||||||
|
var skipCheck = flag.Bool("s", false, "Skip 'check' function while compiling")
|
||||||
|
var installDepends = flag.Bool("d", false, "Install package dependencies for compilation")
|
||||||
|
var installPackage = flag.Bool("i", false, "Install compiled BPM package after compilation finishes")
|
||||||
|
var yesAll = flag.Bool("y", false, "Accept all confirmation prompts")
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("bpm-package")
|
// Setup flags
|
||||||
|
setupFlags()
|
||||||
|
|
||||||
|
// Run checks
|
||||||
|
runChecks()
|
||||||
|
|
||||||
|
// Create BPM archive
|
||||||
|
outputFile := createArchive()
|
||||||
|
|
||||||
|
if *compile {
|
||||||
|
compilePackage(outputFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupFlags() {
|
||||||
|
flag.Usage = help
|
||||||
|
flag.Parse()
|
||||||
|
}
|
||||||
|
|
||||||
|
func help() {
|
||||||
|
fmt.Println("Usage: bpm-package <options>")
|
||||||
|
fmt.Println("Description: Generates source BPM package from current directory")
|
||||||
|
fmt.Println("Options:")
|
||||||
|
flag.PrintDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
|
func runChecks() {
|
||||||
|
// Check if pkg.info file exists
|
||||||
|
if stat, err := os.Stat("pkg.info"); err != nil || !stat.Mode().IsRegular() {
|
||||||
|
log.Fatalf("Error: pkg.info does not exist or is not a regular file")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if source.sh file exists
|
||||||
|
if stat, err := os.Stat("source.sh"); err != nil || !stat.Mode().IsRegular() {
|
||||||
|
log.Fatalf("Error: pkg.info does not exist or is not a regular file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createArchive() string {
|
||||||
|
filesToInclude := make([]string, 0)
|
||||||
|
|
||||||
|
// Include base files
|
||||||
|
filesToInclude = append(filesToInclude, "pkg.info", "source.sh")
|
||||||
|
|
||||||
|
// Check if non-empty source-files directory exists and include it
|
||||||
|
if stat, err := os.Stat("source-files"); err == nil && stat.IsDir() {
|
||||||
|
dir, err := os.ReadDir("source-files")
|
||||||
|
if err == nil && len(dir) != 0 {
|
||||||
|
fmt.Println("Non-empty 'source-files' directory found")
|
||||||
|
filesToInclude = append(filesToInclude, "source-files")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for package scripts and include them
|
||||||
|
for _, script := range []string{"pre_install.sh", "post_install.sh", "pre_update.sh", "post_update.sh", "pre_remove.sh", "post_remove.sh"} {
|
||||||
|
if stat, err := os.Stat(script); err == nil && stat.Mode().IsRegular() {
|
||||||
|
fmt.Printf("Package script '%s' found", script)
|
||||||
|
filesToInclude = append(filesToInclude, script)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read pkg.info file into basic struct
|
||||||
|
pkgInfo := struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Version string `yaml:"version"`
|
||||||
|
Revision int `yaml:"revision"`
|
||||||
|
Arch string `yaml:"architecture"`
|
||||||
|
}{
|
||||||
|
Revision: 1,
|
||||||
|
}
|
||||||
|
data, err := os.ReadFile("pkg.info")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: could not read pkg.info file")
|
||||||
|
}
|
||||||
|
err = yaml.Unmarshal(data, &pkgInfo)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: could not unmarshal pkg.info file")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create filename
|
||||||
|
filename := fmt.Sprintf("%s-%s-%d-%s-src.bpm", pkgInfo.Name, pkgInfo.Version, pkgInfo.Revision, pkgInfo.Arch)
|
||||||
|
|
||||||
|
// Create archive using tar
|
||||||
|
args := make([]string, 0)
|
||||||
|
args = append(args, "-c", "--owner=0", "--group=0", "--no-same-owner", "-f", filename)
|
||||||
|
args = append(args, filesToInclude...)
|
||||||
|
cmd := exec.Command("tar", args...)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
err = cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: failed to create BPM source archive: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get absolute path to filename
|
||||||
|
absFilepath, err := filepath.Abs(filename)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: failed to get absolute path of BPM source archive: %s", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("BPM source archive created at: %s\n", absFilepath)
|
||||||
|
|
||||||
|
return absFilepath
|
||||||
|
}
|
||||||
|
|
||||||
|
func compilePackage(archive string) {
|
||||||
|
// Setup compile command
|
||||||
|
args := make([]string, 0)
|
||||||
|
args = append(args, "compile")
|
||||||
|
if *skipCheck {
|
||||||
|
args = append(args, "-s")
|
||||||
|
}
|
||||||
|
if *installDepends {
|
||||||
|
args = append(args, "-d")
|
||||||
|
}
|
||||||
|
if *yesAll {
|
||||||
|
args = append(args, "-y")
|
||||||
|
}
|
||||||
|
args = append(args, archive)
|
||||||
|
cmd := exec.Command("bpm", args...)
|
||||||
|
cmd.Stdin = os.Stdin
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
pipe, err := cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: could not setup stdout pipe: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run command
|
||||||
|
err = cmd.Start()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: failed to compile BPM source package: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print command output and store it in variable
|
||||||
|
pipeOutput := ""
|
||||||
|
buf := bufio.NewReader(pipe)
|
||||||
|
for {
|
||||||
|
b, err := buf.ReadByte()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
} else if err != nil {
|
||||||
|
log.Fatalf("Error: failed to read byte from command: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeOutput += string(b)
|
||||||
|
fmt.Print(string(b))
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Put output file into slice
|
||||||
|
outputFiles := make([]string, 0)
|
||||||
|
for _, line := range strings.Split(pipeOutput, "\n") {
|
||||||
|
if strings.Contains(line, "Binary package generated at: ") {
|
||||||
|
path := strings.TrimSpace(strings.SplitN(line, ":", 2)[1])
|
||||||
|
outputFiles = append(outputFiles, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for process to complete
|
||||||
|
err = cmd.Wait()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: failed to compile BPM source package: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install compiled packages
|
||||||
|
if *installPackage && len(outputFiles) != 0 {
|
||||||
|
// Read BPM utils config
|
||||||
|
config, err := bpm_utils_shared.ReadBPMUtilsConfig()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: failed to read config: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup install command
|
||||||
|
args = make([]string, 0)
|
||||||
|
args = append(args, "bpm", "install", "--reinstall")
|
||||||
|
if *yesAll {
|
||||||
|
args = append(args, "-y")
|
||||||
|
}
|
||||||
|
args = append(args, outputFiles...)
|
||||||
|
cmd = exec.Command(config.PrivilegeEscalatorCmd, args...)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
cmd.Stdin = os.Stdin
|
||||||
|
|
||||||
|
// Run command
|
||||||
|
err = cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: failed to install compiled BPM packages: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
5
src/bpm-utils-shared/go.mod
Normal file
5
src/bpm-utils-shared/go.mod
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module bpm-utils-shared
|
||||||
|
|
||||||
|
go 1.23
|
||||||
|
|
||||||
|
require gopkg.in/yaml.v3 v3.0.1 // indirect
|
3
src/bpm-utils-shared/go.sum
Normal file
3
src/bpm-utils-shared/go.sum
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
25
src/bpm-utils-shared/main.go
Normal file
25
src/bpm-utils-shared/main.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package bpm_utils_shared
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BPMUtilsConfig struct {
|
||||||
|
PrivilegeEscalatorCmd string `yaml:"privilege_escalator_cmd"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadBPMUtilsConfig() (*BPMUtilsConfig, error) {
|
||||||
|
data, err := os.ReadFile("/etc/bpm-utils/bpm-utils.conf")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
config := &BPMUtilsConfig{}
|
||||||
|
err = yaml.Unmarshal(data, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return config, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user