mirror of
https://github.com/kairos-io/kairos-sdk.git
synced 2025-05-13 02:26:30 +00:00
so that they can force an older or newer release of one specific package Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
143 lines
3.8 KiB
Go
143 lines
3.8 KiB
Go
package profile
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/kairos-io/kairos-sdk/utils"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type profileDataStruct struct {
|
|
Packages []string `yaml:"packages"`
|
|
}
|
|
|
|
type profileFileStruct struct {
|
|
Common []string `yaml:"common"`
|
|
Images []string `yaml:"images"`
|
|
Flavors map[string][]string `yaml:"flavors"`
|
|
}
|
|
|
|
func BuildFlavor(flavor string, profileFile string, directory string) error {
|
|
dat, err := os.ReadFile(profileFile)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("error while reading profile: %w", err)
|
|
}
|
|
prof := &profileFileStruct{}
|
|
if err := yaml.Unmarshal(dat, &prof); err != nil {
|
|
return fmt.Errorf("error while unmarshalling profile: %w", err)
|
|
}
|
|
|
|
profiles, ok := prof.Flavors[flavor]
|
|
if !ok {
|
|
return fmt.Errorf("No profile found")
|
|
}
|
|
|
|
allPackages := []string{}
|
|
for _, p := range profiles {
|
|
packages, err := readProfilePackages(p, profileFile)
|
|
if err != nil {
|
|
return fmt.Errorf("error while reading profile: %w", err)
|
|
}
|
|
|
|
allPackages = append(allPackages, packages...)
|
|
}
|
|
|
|
if err := populateProfile(profileFile, directory, append(allPackages, prof.Common...)); err != nil {
|
|
return fmt.Errorf("error while populating profile: %w", err)
|
|
}
|
|
|
|
return applyImages(directory, prof.Images)
|
|
}
|
|
|
|
func readProfilePackages(profile string, profileFile string) ([]string, error) {
|
|
res := []string{}
|
|
dat, err := os.ReadFile(profileFile)
|
|
if err != nil {
|
|
return res, fmt.Errorf("error while reading profile: %w", err)
|
|
}
|
|
|
|
data := map[string]interface{}{}
|
|
prof := &profileFileStruct{}
|
|
if err := yaml.Unmarshal(dat, &data); err != nil {
|
|
return res, fmt.Errorf("error while unmarshalling profile: %w", err)
|
|
}
|
|
if err := yaml.Unmarshal(dat, &prof); err != nil {
|
|
return res, fmt.Errorf("error while unmarshalling profile: %w", err)
|
|
}
|
|
p := &profileDataStruct{}
|
|
if profileData, ok := data[profile]; ok {
|
|
profileBlob, err := yaml.Marshal(profileData)
|
|
if err != nil {
|
|
return res, fmt.Errorf("error while marshalling profile: %w", err)
|
|
}
|
|
|
|
if err := yaml.Unmarshal(profileBlob, p); err != nil {
|
|
return res, fmt.Errorf("error while unmarshalling profile: %w", err)
|
|
}
|
|
return p.Packages, nil
|
|
}
|
|
|
|
return res, fmt.Errorf("profile '%s' not found", profile)
|
|
}
|
|
|
|
func readProfile(profileFile string) (*profileFileStruct, error) {
|
|
dat, err := os.ReadFile(profileFile)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error while reading profile: %w", err)
|
|
}
|
|
|
|
prof := &profileFileStruct{}
|
|
|
|
if err := yaml.Unmarshal(dat, &prof); err != nil {
|
|
return nil, fmt.Errorf("error while unmarshalling profile: %w", err)
|
|
}
|
|
|
|
return prof, nil
|
|
}
|
|
|
|
func populateProfile(config string, directory string, packages []string) error {
|
|
cmd := fmt.Sprintf("LUET_NOLOCK=true luet install -y --config %s --system-target %s %s", config, directory, strings.Join(packages, " "))
|
|
fmt.Println("running:", cmd)
|
|
out, err := utils.SH(cmd)
|
|
if err != nil {
|
|
return fmt.Errorf("error while running luet: %w (%s)", err, out)
|
|
}
|
|
|
|
fmt.Println(out)
|
|
return nil
|
|
}
|
|
|
|
func applyImages(directory string, images []string) error {
|
|
for _, img := range images {
|
|
cmd := fmt.Sprintf("luet util unpack %s %s", img, directory)
|
|
fmt.Println("running:", cmd)
|
|
out, err := utils.SH(cmd)
|
|
if err != nil {
|
|
return fmt.Errorf("error while running luet: %w (%s)", err, out)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func Build(profile string, profileFile string, directory string) error {
|
|
packages, err := readProfilePackages(profile, profileFile)
|
|
if err != nil {
|
|
return fmt.Errorf("error while reading profile: %w", err)
|
|
}
|
|
|
|
prof, err := readProfile(profileFile)
|
|
if err != nil {
|
|
return fmt.Errorf("error while reading profile: %w", err)
|
|
}
|
|
|
|
if err := populateProfile(profileFile, directory, append(packages, prof.Common...)); err != nil {
|
|
return fmt.Errorf("error while populating profile: %w", err)
|
|
}
|
|
|
|
return applyImages(directory, prof.Images)
|
|
}
|