mirror of
https://github.com/mudler/luet.git
synced 2025-09-17 15:52:15 +00:00
Pass by options to compute functions in install
This commit is contained in:
@@ -198,7 +198,7 @@ func (l *LuetInstaller) Swap(toRemove pkg.Packages, toInstall pkg.Packages, s *S
|
|||||||
return l.swap(syncedRepos, toRemoveFinal, toInstall, s, false)
|
return l.swap(syncedRepos, toRemoveFinal, toInstall, s, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LuetInstaller) computeSwap(syncedRepos Repositories, toRemove pkg.Packages, toInstall pkg.Packages, s *System) (map[string]ArtifactMatch, pkg.Packages, solver.PackagesAssertions, pkg.PackageDatabase, error) {
|
func (l *LuetInstaller) computeSwap(o Option, syncedRepos Repositories, toRemove pkg.Packages, toInstall pkg.Packages, s *System) (map[string]ArtifactMatch, pkg.Packages, solver.PackagesAssertions, pkg.PackageDatabase, error) {
|
||||||
|
|
||||||
allRepos := pkg.NewInMemoryDatabase(false)
|
allRepos := pkg.NewInMemoryDatabase(false)
|
||||||
syncedRepos.SyncDatabase(allRepos)
|
syncedRepos.SyncDatabase(allRepos)
|
||||||
@@ -213,7 +213,7 @@ func (l *LuetInstaller) computeSwap(syncedRepos Repositories, toRemove pkg.Packa
|
|||||||
|
|
||||||
systemAfterChanges := &System{Database: installedtmp}
|
systemAfterChanges := &System{Database: installedtmp}
|
||||||
|
|
||||||
packs, err := l.computeUninstall(systemAfterChanges, toRemove...)
|
packs, err := l.computeUninstall(o, systemAfterChanges, toRemove...)
|
||||||
if err != nil && !l.Options.Force {
|
if err != nil && !l.Options.Force {
|
||||||
Error("Failed computing uninstall for ", packsToList(toRemove))
|
Error("Failed computing uninstall for ", packsToList(toRemove))
|
||||||
return nil, nil, nil, nil, errors.Wrap(err, "computing uninstall "+packsToList(toRemove))
|
return nil, nil, nil, nil, errors.Wrap(err, "computing uninstall "+packsToList(toRemove))
|
||||||
@@ -233,8 +233,8 @@ func (l *LuetInstaller) computeSwap(syncedRepos Repositories, toRemove pkg.Packa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *LuetInstaller) swap(syncedRepos Repositories, toRemove pkg.Packages, toInstall pkg.Packages, s *System, forceNodeps bool) error {
|
func (l *LuetInstaller) swap(syncedRepos Repositories, toRemove pkg.Packages, toInstall pkg.Packages, s *System, forceNodeps bool) error {
|
||||||
forced := l.Options.Force
|
//forced := l.Options.Force
|
||||||
nodeps := l.Options.NoDeps
|
// nodeps := l.Options.NoDeps
|
||||||
|
|
||||||
// We don't want any conflict with the installed to raise during the upgrade.
|
// We don't want any conflict with the installed to raise during the upgrade.
|
||||||
// In this way we both force uninstalls and we avoid to check with conflicts
|
// In this way we both force uninstalls and we avoid to check with conflicts
|
||||||
@@ -244,11 +244,20 @@ func (l *LuetInstaller) swap(syncedRepos Repositories, toRemove pkg.Packages, to
|
|||||||
// now the solver enforces the constraints and explictly denies two packages
|
// now the solver enforces the constraints and explictly denies two packages
|
||||||
// of the same version installed.
|
// of the same version installed.
|
||||||
l.Options.Force = true
|
l.Options.Force = true
|
||||||
|
nodeps := l.Options.NoDeps
|
||||||
if forceNodeps {
|
if forceNodeps {
|
||||||
l.Options.NoDeps = true
|
nodeps = true
|
||||||
}
|
}
|
||||||
|
|
||||||
match, packages, assertions, allRepos, err := l.computeSwap(syncedRepos, toRemove, toInstall, s)
|
o := Option{
|
||||||
|
FullUninstall: l.Options.FullUninstall,
|
||||||
|
Force: true,
|
||||||
|
CheckConflicts: l.Options.CheckConflicts,
|
||||||
|
FullCleanUninstall: l.Options.FullCleanUninstall,
|
||||||
|
NoDeps: nodeps,
|
||||||
|
}
|
||||||
|
|
||||||
|
match, packages, assertions, allRepos, err := l.computeSwap(o, syncedRepos, toRemove, toInstall, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed computing package replacement")
|
return errors.Wrap(err, "failed computing package replacement")
|
||||||
}
|
}
|
||||||
@@ -278,15 +287,123 @@ func (l *LuetInstaller) swap(syncedRepos Repositories, toRemove pkg.Packages, to
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err = l.Uninstall(s, toRemove...)
|
toUninstall, uninstall, err := l.generateUninstallFn(o, s, toRemove...)
|
||||||
if err != nil && !l.Options.Force {
|
if err != nil && !o.Force {
|
||||||
Error("Failed uninstall for ", packsToList(toRemove))
|
return errors.Wrap(err, "while computing uninstall")
|
||||||
return errors.Wrap(err, "uninstalling "+packsToList(toRemove))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Options.Force = forced
|
err = uninstall()
|
||||||
l.Options.NoDeps = nodeps
|
if err != nil && !o.Force {
|
||||||
return l.install(syncedRepos, match, packages, assertions, allRepos, s)
|
Error("Failed uninstall for ", packsToList(toUninstall))
|
||||||
|
return errors.Wrap(err, "uninstalling "+packsToList(toUninstall))
|
||||||
|
}
|
||||||
|
|
||||||
|
o = Option{
|
||||||
|
Force: l.Options.Force,
|
||||||
|
NoDeps: l.Options.NoDeps,
|
||||||
|
}
|
||||||
|
|
||||||
|
return l.install(o, syncedRepos, match, packages, assertions, allRepos, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Option struct {
|
||||||
|
Force bool
|
||||||
|
NoDeps bool
|
||||||
|
CheckConflicts bool
|
||||||
|
FullUninstall bool
|
||||||
|
FullCleanUninstall bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type operation struct {
|
||||||
|
Option Option
|
||||||
|
Package pkg.Package
|
||||||
|
}
|
||||||
|
|
||||||
|
// installerOp is the operation that is sent to the
|
||||||
|
// upgradeWorker's channel (todo)
|
||||||
|
type installerOp struct {
|
||||||
|
Uninstall operation
|
||||||
|
Install operation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *LuetInstaller) runOps(syncedRepos Repositories, ops []installerOp, p pkg.Packages, solution solver.PackagesAssertions, allRepos pkg.PackageDatabase, s *System) error {
|
||||||
|
all := make(chan installerOp)
|
||||||
|
|
||||||
|
wg := new(sync.WaitGroup)
|
||||||
|
|
||||||
|
// Do the real install
|
||||||
|
for i := 0; i < l.Options.Concurrency; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go l.installerOpWorker(i, wg, all, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range ops {
|
||||||
|
all <- c
|
||||||
|
}
|
||||||
|
close(all)
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *LuetInstaller) installerOpWorker(i int, wg *sync.WaitGroup, c <-chan installerOp, s *System) error {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
for p := range c {
|
||||||
|
|
||||||
|
if p.Uninstall.Package != nil {
|
||||||
|
|
||||||
|
toUninstall, uninstall, err := l.generateUninstallFn(p.Uninstall.Option, s, p.Uninstall.Package)
|
||||||
|
if err != nil && !l.Options.Force {
|
||||||
|
return errors.Wrap(err, "while computing uninstall")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = uninstall()
|
||||||
|
if err != nil && !p.Uninstall.Option.Force {
|
||||||
|
Error("Failed uninstall for ", packsToList(toUninstall))
|
||||||
|
return errors.Wrap(err, "uninstalling "+packsToList(toUninstall))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// return l.install(p.Install.Option, match, packages, assertions, allRepos, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks wheter we can uninstall and install in place and compose installer worker ops
|
||||||
|
func (l *LuetInstaller) getOpsWithOptions(toUninstall pkg.Packages, installMatch map[string]ArtifactMatch, installOpt, uninstallOpt Option) []installerOp {
|
||||||
|
resOps := []installerOp{}
|
||||||
|
for _, match := range installMatch {
|
||||||
|
if pack, err := toUninstall.Find(match.Package.GetPackageName()); err == nil {
|
||||||
|
resOps = append(resOps, installerOp{
|
||||||
|
Uninstall: operation{Package: pack, Option: uninstallOpt},
|
||||||
|
Install: operation{Package: match.Package, Option: installOpt},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
resOps = append(resOps, installerOp{
|
||||||
|
Install: operation{Package: match.Package, Option: installOpt},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range toUninstall {
|
||||||
|
found := false
|
||||||
|
|
||||||
|
for _, match := range installMatch {
|
||||||
|
if match.Package.GetPackageName() == p.GetPackageName() {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
resOps = append(resOps, installerOp{
|
||||||
|
Uninstall: operation{Package: p, Option: uninstallOpt},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resOps
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LuetInstaller) checkAndUpgrade(r Repositories, s *System) error {
|
func (l *LuetInstaller) checkAndUpgrade(r Repositories, s *System) error {
|
||||||
@@ -370,17 +487,20 @@ func (l *LuetInstaller) Install(cp pkg.Packages, s *System) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Info("Packages that are going to be installed in the system: \n ", Green(matchesToList(match)).BgBlack().String())
|
Info("Packages that are going to be installed in the system: \n ", Green(matchesToList(match)).BgBlack().String())
|
||||||
|
o := Option{
|
||||||
|
NoDeps: l.Options.NoDeps,
|
||||||
|
Force: l.Options.Force,
|
||||||
|
}
|
||||||
if l.Options.Ask {
|
if l.Options.Ask {
|
||||||
Info("By going forward, you are also accepting the licenses of the packages that you are going to install in your system.")
|
Info("By going forward, you are also accepting the licenses of the packages that you are going to install in your system.")
|
||||||
if Ask() {
|
if Ask() {
|
||||||
l.Options.Ask = false // Don't prompt anymore
|
l.Options.Ask = false // Don't prompt anymore
|
||||||
return l.install(syncedRepos, match, packages, assertions, allRepos, s)
|
return l.install(o, syncedRepos, match, packages, assertions, allRepos, s)
|
||||||
} else {
|
} else {
|
||||||
return errors.New("Aborted by user")
|
return errors.New("Aborted by user")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return l.install(syncedRepos, match, packages, assertions, allRepos, s)
|
return l.install(o, syncedRepos, match, packages, assertions, allRepos, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LuetInstaller) download(syncedRepos Repositories, toDownload map[string]ArtifactMatch) error {
|
func (l *LuetInstaller) download(syncedRepos Repositories, toDownload map[string]ArtifactMatch) error {
|
||||||
@@ -540,7 +660,7 @@ func (l *LuetInstaller) computeInstall(syncedRepos Repositories, cp pkg.Packages
|
|||||||
return toInstall, p, solution, allRepos, nil
|
return toInstall, p, solution, allRepos, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LuetInstaller) install(syncedRepos Repositories, toInstall map[string]ArtifactMatch, p pkg.Packages, solution solver.PackagesAssertions, allRepos pkg.PackageDatabase, s *System) error {
|
func (l *LuetInstaller) install(o Option, syncedRepos Repositories, toInstall map[string]ArtifactMatch, p pkg.Packages, solution solver.PackagesAssertions, allRepos pkg.PackageDatabase, s *System) error {
|
||||||
// Install packages into rootfs in parallel.
|
// Install packages into rootfs in parallel.
|
||||||
if err := l.download(syncedRepos, toInstall); err != nil {
|
if err := l.download(syncedRepos, toInstall); err != nil {
|
||||||
return errors.Wrap(err, "Downloading packages")
|
return errors.Wrap(err, "Downloading packages")
|
||||||
@@ -569,13 +689,13 @@ func (l *LuetInstaller) install(syncedRepos Repositories, toInstall map[string]A
|
|||||||
for _, c := range toInstall {
|
for _, c := range toInstall {
|
||||||
// Annotate to the system that the package was installed
|
// Annotate to the system that the package was installed
|
||||||
_, err := s.Database.CreatePackage(c.Package)
|
_, err := s.Database.CreatePackage(c.Package)
|
||||||
if err != nil && !l.Options.Force {
|
if err != nil && !o.Force {
|
||||||
return errors.Wrap(err, "Failed creating package")
|
return errors.Wrap(err, "Failed creating package")
|
||||||
}
|
}
|
||||||
bus.Manager.Publish(bus.EventPackageInstall, c)
|
bus.Manager.Publish(bus.EventPackageInstall, c)
|
||||||
}
|
}
|
||||||
var toFinalize []pkg.Package
|
var toFinalize []pkg.Package
|
||||||
if !l.Options.NoDeps {
|
if !o.NoDeps {
|
||||||
// TODO: Lower those errors as warning
|
// TODO: Lower those errors as warning
|
||||||
for _, w := range p {
|
for _, w := range p {
|
||||||
// Finalizers needs to run in order and in sequence.
|
// Finalizers needs to run in order and in sequence.
|
||||||
@@ -779,14 +899,14 @@ func (l *LuetInstaller) uninstall(p pkg.Package, s *System) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LuetInstaller) computeUninstall(s *System, packs ...pkg.Package) (pkg.Packages, error) {
|
func (l *LuetInstaller) computeUninstall(o Option, s *System, packs ...pkg.Package) (pkg.Packages, error) {
|
||||||
|
|
||||||
var toUninstall pkg.Packages
|
var toUninstall pkg.Packages
|
||||||
// compute uninstall from all world - remove packages in parallel - run uninstall finalizer (in order) TODO - mark the uninstallation in db
|
// compute uninstall from all world - remove packages in parallel - run uninstall finalizer (in order) TODO - mark the uninstallation in db
|
||||||
// Get installed definition
|
// Get installed definition
|
||||||
checkConflicts := l.Options.CheckConflicts
|
checkConflicts := o.CheckConflicts
|
||||||
full := l.Options.FullUninstall
|
full := o.FullUninstall
|
||||||
if l.Options.Force == true { // IF forced, we want to remove the package and all its requires
|
if o.Force == true { // IF forced, we want to remove the package and all its requires
|
||||||
checkConflicts = false
|
checkConflicts = false
|
||||||
full = false
|
full = false
|
||||||
}
|
}
|
||||||
@@ -803,7 +923,7 @@ func (l *LuetInstaller) computeUninstall(s *System, packs ...pkg.Package) (pkg.P
|
|||||||
solv := solver.NewResolver(solver.Options{Type: l.Options.SolverOptions.Implementation, Concurrency: l.Options.Concurrency}, installedtmp, installedtmp, pkg.NewInMemoryDatabase(false), l.Options.SolverOptions.Resolver())
|
solv := solver.NewResolver(solver.Options{Type: l.Options.SolverOptions.Implementation, Concurrency: l.Options.Concurrency}, installedtmp, installedtmp, pkg.NewInMemoryDatabase(false), l.Options.SolverOptions.Resolver())
|
||||||
var solution pkg.Packages
|
var solution pkg.Packages
|
||||||
var err error
|
var err error
|
||||||
if l.Options.FullCleanUninstall {
|
if o.FullCleanUninstall {
|
||||||
solution, err = solv.UninstallUniverse(packs)
|
solution, err = solv.UninstallUniverse(packs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return toUninstall, errors.Wrap(err, "Could not solve the uninstall constraints. Tip: try with --solver-type qlearning or with --force, or by removing packages excluding their dependencies with --nodeps")
|
return toUninstall, errors.Wrap(err, "Could not solve the uninstall constraints. Tip: try with --solver-type qlearning or with --force, or by removing packages excluding their dependencies with --nodeps")
|
||||||
@@ -824,32 +944,47 @@ func (l *LuetInstaller) computeUninstall(s *System, packs ...pkg.Package) (pkg.P
|
|||||||
|
|
||||||
return toUninstall, nil
|
return toUninstall, nil
|
||||||
}
|
}
|
||||||
func (l *LuetInstaller) Uninstall(s *System, packs ...pkg.Package) error {
|
|
||||||
|
|
||||||
|
func (l *LuetInstaller) generateUninstallFn(o Option, s *System, packs ...pkg.Package) (pkg.Packages, func() error, error) {
|
||||||
for _, p := range packs {
|
for _, p := range packs {
|
||||||
if packs, _ := s.Database.FindPackages(p); len(packs) == 0 {
|
if packs, _ := s.Database.FindPackages(p); len(packs) == 0 {
|
||||||
return errors.New("Package not found in the system")
|
return nil, nil, errors.New("Package not found in the system")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Spinner(32)
|
toUninstall, err := l.computeUninstall(o, s, packs...)
|
||||||
toUninstall, err := l.computeUninstall(s, packs...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "while computing uninstall")
|
return nil, nil, errors.Wrap(err, "while computing uninstall")
|
||||||
}
|
}
|
||||||
SpinnerStop()
|
|
||||||
|
|
||||||
uninstall := func() error {
|
uninstall := func() error {
|
||||||
for _, p := range toUninstall {
|
for _, p := range toUninstall {
|
||||||
err := l.uninstall(p, s)
|
err := l.uninstall(p, s)
|
||||||
if err != nil && !l.Options.Force {
|
if err != nil && !o.Force {
|
||||||
return errors.Wrap(err, "Uninstall failed")
|
return errors.Wrap(err, "Uninstall failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return toUninstall, uninstall, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *LuetInstaller) Uninstall(s *System, packs ...pkg.Package) error {
|
||||||
|
|
||||||
|
Spinner(32)
|
||||||
|
o := Option{
|
||||||
|
FullUninstall: l.Options.FullUninstall,
|
||||||
|
Force: l.Options.Force,
|
||||||
|
CheckConflicts: l.Options.CheckConflicts,
|
||||||
|
FullCleanUninstall: l.Options.FullCleanUninstall,
|
||||||
|
}
|
||||||
|
toUninstall, uninstall, err := l.generateUninstallFn(o, s, packs...)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "while computing uninstall")
|
||||||
|
}
|
||||||
|
SpinnerStop()
|
||||||
|
|
||||||
if len(toUninstall) == 0 {
|
if len(toUninstall) == 0 {
|
||||||
Info("Nothing to do")
|
Info("Nothing to do")
|
||||||
return nil
|
return nil
|
||||||
|
@@ -645,6 +645,16 @@ func (set Packages) Best(v version.Versioner) Package {
|
|||||||
return versionsMap[sorted[len(sorted)-1]]
|
return versionsMap[sorted[len(sorted)-1]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (set Packages) Find(packageName string) (Package, error) {
|
||||||
|
for _, p := range set {
|
||||||
|
if p.GetPackageName() == packageName {
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DefaultPackage{}, errors.New("package not found")
|
||||||
|
}
|
||||||
|
|
||||||
func (set Packages) Unique() Packages {
|
func (set Packages) Unique() Packages {
|
||||||
var result Packages
|
var result Packages
|
||||||
uniq := make(map[string]Package)
|
uniq := make(map[string]Package)
|
||||||
|
Reference in New Issue
Block a user