mirror of
https://github.com/mudler/luet.git
synced 2025-09-03 08:14:46 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
719ef16161 | ||
|
1a9073a97a | ||
|
7e825400e2 | ||
|
39e62f3321 | ||
|
9dcaeb0870 | ||
|
c4affb0f0e | ||
|
4c1b9b92af |
@@ -86,7 +86,6 @@ Build packages specifying multiple definition trees:
|
||||
viper.BindPFlag("wait", cmd.Flags().Lookup("wait"))
|
||||
viper.BindPFlag("keep-images", cmd.Flags().Lookup("keep-images"))
|
||||
|
||||
viper.BindPFlag("general.show_build_output", cmd.Flags().Lookup("live-output"))
|
||||
viper.BindPFlag("backend-args", cmd.Flags().Lookup("backend-args"))
|
||||
|
||||
},
|
||||
@@ -334,7 +333,6 @@ func init() {
|
||||
buildCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")
|
||||
buildCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
|
||||
buildCmd.Flags().Bool("solver-concurrent", false, "Use concurrent solver (experimental)")
|
||||
buildCmd.Flags().Bool("live-output", true, "Enable live output of the build phase.")
|
||||
buildCmd.Flags().Bool("from-repositories", false, "Consume the user-defined repositories to pull specfiles from")
|
||||
buildCmd.Flags().Bool("rebuild", false, "To combine with --pull. Allows to rebuild the target package even if an image is available, against a local values file")
|
||||
buildCmd.Flags().Bool("pretend", false, "Just print what packages will be compiled")
|
||||
|
@@ -30,7 +30,7 @@ var cfgFile string
|
||||
var Verbose bool
|
||||
|
||||
const (
|
||||
LuetCLIVersion = "0.22.0"
|
||||
LuetCLIVersion = "0.22.2"
|
||||
LuetEnvPrefix = "LUET"
|
||||
)
|
||||
|
||||
|
@@ -35,6 +35,7 @@ type PackageResult struct {
|
||||
Target string `json:"target"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Files []string `json:"files"`
|
||||
Installed bool `json:"installed"`
|
||||
}
|
||||
|
||||
type Results struct {
|
||||
@@ -45,13 +46,13 @@ func (r PackageResult) String() string {
|
||||
return fmt.Sprintf("%s/%s-%s required for %s", r.Category, r.Name, r.Version, r.Target)
|
||||
}
|
||||
|
||||
var rows []string = []string{"Package", "Category", "Name", "Version", "Repository", "License"}
|
||||
var rows []string = []string{"Package", "Category", "Name", "Version", "Repository", "License", "Installed"}
|
||||
|
||||
func packageToRow(repo string, p pkg.Package) []string {
|
||||
return []string{p.HumanReadableString(), p.GetCategory(), p.GetName(), p.GetVersion(), repo, p.GetLicense()}
|
||||
func packageToRow(repo string, p pkg.Package, installed bool) []string {
|
||||
return []string{p.HumanReadableString(), p.GetCategory(), p.GetName(), p.GetVersion(), repo, p.GetLicense(), fmt.Sprintf("%t", installed)}
|
||||
}
|
||||
|
||||
func packageToList(l *util.ListWriter, repo string, p pkg.Package) {
|
||||
func packageToList(l *util.ListWriter, repo string, p pkg.Package, installed bool) {
|
||||
l.AppendItem(pterm.BulletListItem{
|
||||
Level: 0, Text: p.HumanReadableString(),
|
||||
TextStyle: pterm.NewStyle(pterm.FgCyan), Bullet: ">", BulletStyle: pterm.NewStyle(pterm.FgYellow),
|
||||
@@ -80,12 +81,32 @@ func packageToList(l *util.ListWriter, repo string, p pkg.Package) {
|
||||
Level: 1, Text: fmt.Sprintf("Uri: %s ", strings.Join(p.GetURI(), " ")),
|
||||
Bullet: "->", BulletStyle: pterm.NewStyle(pterm.FgDarkGray),
|
||||
})
|
||||
l.AppendItem(pterm.BulletListItem{
|
||||
Level: 1, Text: fmt.Sprintf("Installed: %t ", installed),
|
||||
Bullet: "->", BulletStyle: pterm.NewStyle(pterm.FgDarkGray),
|
||||
})
|
||||
}
|
||||
|
||||
var s *installer.System
|
||||
|
||||
func sys() *installer.System {
|
||||
if s != nil {
|
||||
return s
|
||||
}
|
||||
s = &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.System.Rootfs}
|
||||
return s
|
||||
}
|
||||
|
||||
func installed(p pkg.Package) bool {
|
||||
s := sys()
|
||||
_, err := s.Database.FindPackage(p)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label, labelMatch, revdeps, hidden bool) Results {
|
||||
var results Results
|
||||
|
||||
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.System.Rootfs}
|
||||
system := sys()
|
||||
|
||||
var err error
|
||||
iMatches := pkg.Packages{}
|
||||
@@ -104,9 +125,8 @@ func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label,
|
||||
for _, pack := range iMatches {
|
||||
if !revdeps {
|
||||
if !pack.IsHidden() || pack.IsHidden() && hidden {
|
||||
|
||||
t.AppendRow(packageToRow("system", pack))
|
||||
packageToList(l, "system", pack)
|
||||
t.AppendRow(packageToRow("system", pack, true))
|
||||
packageToList(l, "system", pack, true)
|
||||
f, _ := system.Database.GetPackageFiles(pack)
|
||||
results.Packages = append(results.Packages,
|
||||
PackageResult{
|
||||
@@ -116,6 +136,7 @@ func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label,
|
||||
Repository: "system",
|
||||
Hidden: pack.IsHidden(),
|
||||
Files: f,
|
||||
Installed: true,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@@ -123,8 +144,9 @@ func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label,
|
||||
packs, _ := system.Database.GetRevdeps(pack)
|
||||
for _, revdep := range packs {
|
||||
if !revdep.IsHidden() || revdep.IsHidden() && hidden {
|
||||
t.AppendRow(packageToRow("system", pack))
|
||||
packageToList(l, "system", pack)
|
||||
i := installed(pack)
|
||||
t.AppendRow(packageToRow("system", pack, i))
|
||||
packageToList(l, "system", pack, i)
|
||||
f, _ := system.Database.GetPackageFiles(revdep)
|
||||
results.Packages = append(results.Packages,
|
||||
PackageResult{
|
||||
@@ -134,6 +156,7 @@ func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label,
|
||||
Repository: "system",
|
||||
Hidden: revdep.IsHidden(),
|
||||
Files: f,
|
||||
Installed: i,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -172,14 +195,16 @@ func searchOnline(term string, l *util.ListWriter, t *util.TableWriter, label, l
|
||||
for _, m := range matches {
|
||||
if !revdeps {
|
||||
if !m.Package.IsHidden() || m.Package.IsHidden() && hidden {
|
||||
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package))
|
||||
packageToList(l, m.Repo.GetName(), m.Package)
|
||||
i := installed(m.Package)
|
||||
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package, i))
|
||||
packageToList(l, m.Repo.GetName(), m.Package, i)
|
||||
r := &PackageResult{
|
||||
Name: m.Package.GetName(),
|
||||
Version: m.Package.GetVersion(),
|
||||
Category: m.Package.GetCategory(),
|
||||
Repository: m.Repo.GetName(),
|
||||
Hidden: m.Package.IsHidden(),
|
||||
Installed: i,
|
||||
}
|
||||
if m.Artifact != nil {
|
||||
r.Files = m.Artifact.Files
|
||||
@@ -190,10 +215,12 @@ func searchOnline(term string, l *util.ListWriter, t *util.TableWriter, label, l
|
||||
packs, _ := m.Repo.GetTree().GetDatabase().GetRevdeps(m.Package)
|
||||
for _, revdep := range packs {
|
||||
if !revdep.IsHidden() || revdep.IsHidden() && hidden {
|
||||
t.AppendRow(packageToRow(m.Repo.GetName(), revdep))
|
||||
packageToList(l, m.Repo.GetName(), revdep)
|
||||
i := installed(revdep)
|
||||
t.AppendRow(packageToRow(m.Repo.GetName(), revdep, i))
|
||||
packageToList(l, m.Repo.GetName(), revdep, i)
|
||||
r := &PackageResult{
|
||||
Name: revdep.GetName(),
|
||||
Installed: i,
|
||||
Version: revdep.GetVersion(),
|
||||
Category: revdep.GetCategory(),
|
||||
Repository: m.Repo.GetName(),
|
||||
@@ -215,8 +242,9 @@ func searchLocalFiles(term string, l *util.ListWriter, t *util.TableWriter) Resu
|
||||
|
||||
matches, _ := util.DefaultContext.Config.GetSystemDB().FindPackageByFile(term)
|
||||
for _, pack := range matches {
|
||||
t.AppendRow(packageToRow("system", pack))
|
||||
packageToList(l, "system", pack)
|
||||
i := installed(pack)
|
||||
t.AppendRow(packageToRow("system", pack, i))
|
||||
packageToList(l, "system", pack, i)
|
||||
f, _ := util.DefaultContext.Config.GetSystemDB().GetPackageFiles(pack)
|
||||
results.Packages = append(results.Packages,
|
||||
PackageResult{
|
||||
@@ -226,6 +254,7 @@ func searchLocalFiles(term string, l *util.ListWriter, t *util.TableWriter) Resu
|
||||
Repository: "system",
|
||||
Hidden: pack.IsHidden(),
|
||||
Files: f,
|
||||
Installed: i,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -255,8 +284,9 @@ func searchFiles(term string, l *util.ListWriter, t *util.TableWriter) Results {
|
||||
matches = synced.SearchPackages(term, installer.FileSearch)
|
||||
|
||||
for _, m := range matches {
|
||||
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package))
|
||||
packageToList(l, m.Repo.GetName(), m.Package)
|
||||
i := installed(m.Package)
|
||||
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package, i))
|
||||
packageToList(l, m.Repo.GetName(), m.Package, i)
|
||||
results.Packages = append(results.Packages,
|
||||
PackageResult{
|
||||
Name: m.Package.GetName(),
|
||||
@@ -265,6 +295,7 @@ func searchFiles(term string, l *util.ListWriter, t *util.TableWriter) Results {
|
||||
Repository: m.Repo.GetName(),
|
||||
Hidden: m.Package.IsHidden(),
|
||||
Files: m.Artifact.Files,
|
||||
Installed: i,
|
||||
})
|
||||
}
|
||||
return results
|
||||
|
26
cmd/util.go
26
cmd/util.go
@@ -89,7 +89,7 @@ func NewUnpackCommand() *cobra.Command {
|
||||
Use: "unpack image path",
|
||||
Short: "Unpack a docker image natively",
|
||||
Long: `unpack doesn't need the docker daemon to run, and unpacks a docker image in the specified directory:
|
||||
|
||||
|
||||
luet util unpack golang:alpine /alpine
|
||||
`,
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
@@ -107,7 +107,7 @@ func NewUnpackCommand() *cobra.Command {
|
||||
util.DefaultContext.Error("Invalid path %s", destination)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
local, _ := cmd.Flags().GetBool("local")
|
||||
verify, _ := cmd.Flags().GetBool("verify")
|
||||
user, _ := cmd.Flags().GetString("auth-username")
|
||||
pass, _ := cmd.Flags().GetString("auth-password")
|
||||
@@ -126,13 +126,22 @@ func NewUnpackCommand() *cobra.Command {
|
||||
RegistryToken: registryToken,
|
||||
}
|
||||
|
||||
info, err := docker.DownloadAndExtractDockerImage(util.DefaultContext, image, destination, auth, verify)
|
||||
if err != nil {
|
||||
util.DefaultContext.Error(err.Error())
|
||||
os.Exit(1)
|
||||
if !local {
|
||||
info, err := docker.DownloadAndExtractDockerImage(util.DefaultContext, image, destination, auth, verify)
|
||||
if err != nil {
|
||||
util.DefaultContext.Error(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
util.DefaultContext.Info(fmt.Sprintf("Pulled: %s %s", info.Target.Digest, info.Name))
|
||||
util.DefaultContext.Info(fmt.Sprintf("Size: %s", units.BytesSize(float64(info.Target.Size))))
|
||||
} else {
|
||||
info, err := docker.ExtractDockerImage(util.DefaultContext, image, destination)
|
||||
if err != nil {
|
||||
util.DefaultContext.Error(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
util.DefaultContext.Info(fmt.Sprintf("Size: %s", units.BytesSize(float64(info.Target.Size))))
|
||||
}
|
||||
util.DefaultContext.Info(fmt.Sprintf("Pulled: %s %s", info.Target.Digest, info.Name))
|
||||
util.DefaultContext.Info(fmt.Sprintf("Size: %s", units.BytesSize(float64(info.Target.Size))))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -143,6 +152,7 @@ func NewUnpackCommand() *cobra.Command {
|
||||
c.Flags().String("auth-identity-token", "", "Authentication identity token")
|
||||
c.Flags().String("auth-registry-token", "", "Authentication registry token")
|
||||
c.Flags().Bool("verify", false, "Verify signed images to notary before to pull")
|
||||
c.Flags().Bool("local", false, "Unpack local image")
|
||||
return c
|
||||
}
|
||||
|
||||
|
@@ -220,7 +220,7 @@ func setDefaults(viper *viper.Viper) {
|
||||
viper.SetDefault("general.concurrency", runtime.NumCPU())
|
||||
viper.SetDefault("general.debug", false)
|
||||
viper.SetDefault("general.quiet", false)
|
||||
viper.SetDefault("general.show_build_output", false)
|
||||
viper.SetDefault("general.show_build_output", true)
|
||||
viper.SetDefault("general.fatal_warnings", false)
|
||||
viper.SetDefault("general.http_timeout", 360)
|
||||
|
||||
@@ -278,6 +278,7 @@ func InitViper(RootCmd *cobra.Command) {
|
||||
pflags.Float32("solver-rate", 0.7, "Solver learning rate")
|
||||
pflags.Float32("solver-discount", 1.0, "Solver discount rate")
|
||||
pflags.Int("solver-attempts", 9000, "Solver maximum attempts")
|
||||
pflags.Bool("live-output", true, "Show live output during build")
|
||||
|
||||
pflags.Bool("same-owner", true, "Maintain same owner on uncompress.")
|
||||
pflags.Int("concurrency", runtime.NumCPU(), "Concurrency")
|
||||
@@ -303,6 +304,7 @@ func InitViper(RootCmd *cobra.Command) {
|
||||
viper.BindPFlag("general.same_owner", pflags.Lookup("same-owner"))
|
||||
viper.BindPFlag("plugin", pflags.Lookup("plugin"))
|
||||
viper.BindPFlag("general.http_timeout", pflags.Lookup("http-timeout"))
|
||||
viper.BindPFlag("general.show_build_output", pflags.Lookup("live-output"))
|
||||
|
||||
// Currently I maintain this only from cli.
|
||||
viper.BindPFlag("no_spinner", pflags.Lookup("no-spinner"))
|
||||
|
@@ -36,7 +36,7 @@ func TreePackages(treedir string) (searchResult SearchResult, err error) {
|
||||
}
|
||||
|
||||
func imageAvailable(image string) bool {
|
||||
_, err := crane.Digest(image)
|
||||
_, err := crane.Digest(image, crane.Insecure)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
|
@@ -29,7 +29,9 @@ const (
|
||||
)
|
||||
|
||||
func imageAvailable(image string) bool {
|
||||
_, err := crane.Digest(image)
|
||||
// We use crane.insecure as we just check if the image is available
|
||||
// It's the daemon duty to use it or not based on the host settings
|
||||
_, err := crane.Digest(image, crane.Insecure)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
"github.com/google/go-containerregistry/pkg/v1/daemon"
|
||||
"github.com/mudler/luet/pkg/api/core/bus"
|
||||
"github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
@@ -192,3 +193,60 @@ func DownloadAndExtractDockerImage(ctx luettypes.Context, image, dest string, au
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ExtractDockerImage(ctx luettypes.Context, local, dest string)(*images.Image, error) {
|
||||
if !fileHelper.Exists(dest) {
|
||||
if err := os.MkdirAll(dest, os.ModePerm); err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot create destination directory")
|
||||
}
|
||||
}
|
||||
|
||||
ref, err := name.ParseReference(local)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
img, err := daemon.Image(ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m, err := img.Manifest()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mt, err := img.MediaType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d, err := img.Digest()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var c int64
|
||||
c, _, err = luetimages.ExtractTo(
|
||||
ctx,
|
||||
img,
|
||||
dest,
|
||||
nil,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bus.Manager.Publish(bus.EventImagePostUnPack, UnpackEventData{Image: local, Dest: dest})
|
||||
|
||||
return &images.Image{
|
||||
Name: local,
|
||||
Labels: m.Annotations,
|
||||
Target: specs.Descriptor{
|
||||
MediaType: string(mt),
|
||||
Digest: digest.Digest(d.String()),
|
||||
Size: c,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
@@ -866,6 +866,8 @@ func (r *LuetSystemRepository) Sync(ctx types.Context, force bool) (*LuetSystemR
|
||||
toTimeSync = true
|
||||
ctx.Debug(r.Name, "is old, refresh is suggested")
|
||||
}
|
||||
} else {
|
||||
toTimeSync = true
|
||||
}
|
||||
|
||||
ctx.Debug("Sync of the repository", r.Name, "in progress...")
|
||||
@@ -893,6 +895,10 @@ func (r *LuetSystemRepository) Sync(ctx types.Context, force bool) (*LuetSystemR
|
||||
return nil, err
|
||||
}
|
||||
defer os.RemoveAll(file)
|
||||
defer func() {
|
||||
now := time.Now().Format(time.RFC3339)
|
||||
ioutil.WriteFile(filepath.Join(repobasedir, "SYNCTIME"), []byte(now), os.ModePerm)
|
||||
}()
|
||||
} else {
|
||||
downloadedRepoMeta, err = r.ReadSpecFile(repoFile)
|
||||
if err != nil {
|
||||
@@ -990,8 +996,6 @@ func (r *LuetSystemRepository) Sync(ctx types.Context, force bool) (*LuetSystemR
|
||||
downloadedRepoMeta.GetRevision(),
|
||||
time.Unix(tsec, 0).String()))
|
||||
|
||||
now := time.Now().Format(time.RFC3339)
|
||||
ioutil.WriteFile(filepath.Join(repobasedir, "SYNCTIME"), []byte(now), os.ModePerm)
|
||||
}
|
||||
|
||||
meta, err := NewLuetSystemRepositoryMetadata(
|
||||
|
Reference in New Issue
Block a user