Compare commits

...

12 Commits
0.8.0 ... 0.8.2

Author SHA1 Message Date
Ettore Di Giacinto
3af9109b99 Tag 0.8.2 2020-07-12 15:57:46 +02:00
Ettore Di Giacinto
6e3650d3af Add upgrade_old_repo_revision fixture 2020-07-12 15:38:02 +02:00
Ettore Di Giacinto
5dcf77c987 Add package buildtimestamp and luet upgrade --sync
Annotate the package build time when compiling, and use that from the
client to force upgrade of packages that changed the artifact, but
didn't changed any version.

The client can trigger this behavior with `luet upgrade --sync`
2020-07-12 15:29:38 +02:00
Daniele Rondina
ee0e70ed3d tree/pkglist: Now --deps orders for build/installation order 2020-07-05 10:44:47 +02:00
Daniele Rondina
364b5648b4 repository loader now support .yaml extension 2020-07-04 20:07:32 +02:00
Daniele Rondina
e28a4753f8 tree/validate: Use --deps instead of --rdeps (we support also build deps) 2020-06-27 19:42:03 +02:00
Daniele Rondina
d1d7f5aa74 tree/pkglist: Add --rdeps option for runtime deps 2020-06-27 19:27:45 +02:00
Daniele Rondina
e2260b6956 Add --no-spinner option 2020-06-27 16:45:49 +02:00
Ettore Di Giacinto
764a09ce0c Tag 0.8.1 2020-06-27 13:02:00 +02:00
Ettore Di Giacinto
910f1ad3fe Merge branch 'master' into develop 2020-06-27 13:01:14 +02:00
Ettore Di Giacinto
16e9d7b20c Use packageImage as builder image fingerprint
This allows to have an unique identifier for the builder image id against
different depgraphs combinations. The package fingerprint is not enough,
as an atom could have a difference deptree depending on the requires
constraints.

TODO: Don't use the full image name, but only the hash as a salt
(currently the salt contains ALSO a reference of the image-repository,
as such it doesn't allow to port a tree in a different docker registry)
2020-06-23 18:59:18 +02:00
Ettore Di Giacinto
6088664887 Drop gox-build make target 2020-06-13 18:40:55 +02:00
21 changed files with 382 additions and 55 deletions

View File

@@ -74,10 +74,6 @@ build-small:
image:
docker build --rm -t luet/base .
.PHONY: gox-build
gox-build:
CGO_ENABLED=0 gox $(BUILD_PLATFORMS) -ldflags '$(LDFLAGS)' -output="release/$(NAME)-$(VERSION)-{{.OS}}-{{.Arch}}"
.PHONY: lint
lint:
golint ./... | grep -v "be unexported"
@@ -94,4 +90,4 @@ test-docker:
.PHONY: multiarch-build
multiarch-build:
gox $(BUILD_PLATFORMS) -ldflags '$(LDFLAGS)' -output="release/$(NAME)-$(VERSION)-{{.OS}}-{{.Arch}}"
CGO_ENABLED=0 gox $(BUILD_PLATFORMS) -ldflags '$(LDFLAGS)' -output="release/$(NAME)-$(VERSION)-{{.OS}}-{{.Arch}}"

View File

@@ -38,7 +38,7 @@ var Verbose bool
var LockedCommands = []string{"install", "uninstall", "upgrade"}
const (
LuetCLIVersion = "0.8.0"
LuetCLIVersion = "0.8.2"
LuetEnvPrefix = "LUET"
)
@@ -88,8 +88,12 @@ func LoadConfig(c *config.LuetConfig) error {
return err
}
noSpinner := c.Viper.GetBool("no_spinner")
InitAurora()
if !noSpinner {
NewSpinner()
}
Debug("Using config file:", c.Viper.ConfigFileUsed())
@@ -145,6 +149,7 @@ func init() {
pflags.BoolP("debug", "d", false, "verbose output")
pflags.Bool("fatal", false, "Enables Warnings to exit")
pflags.Bool("enable-logfile", false, "Enable log to file")
pflags.Bool("no-spinner", false, "Disable spinner.")
pflags.Bool("color", config.LuetCfg.GetLogging().Color, "Enable/Disable color.")
pflags.Bool("emoji", config.LuetCfg.GetLogging().EnableEmoji, "Enable/Disable emoji.")
pflags.StringP("logfile", "l", config.LuetCfg.GetLogging().Path,
@@ -168,6 +173,8 @@ func init() {
config.LuetCfg.Viper.BindPFlag("general.debug", pflags.Lookup("debug"))
config.LuetCfg.Viper.BindPFlag("general.fatal_warnings", pflags.Lookup("fatal"))
config.LuetCfg.Viper.BindPFlag("general.same_owner", pflags.Lookup("same-owner"))
// Currently I maintain this only from cli.
config.LuetCfg.Viper.BindPFlag("no_spinner", pflags.Lookup("no-spinner"))
// Extensions must be binary with the "luet-" prefix to be able to be shown in the help.
// we also accept extensions in the relative path where luet is being started, "extensions/"

View File

@@ -26,6 +26,7 @@ import (
. "github.com/mudler/luet/pkg/config"
. "github.com/mudler/luet/pkg/logger"
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/solver"
tree "github.com/mudler/luet/pkg/tree"
"github.com/spf13/cobra"
@@ -74,15 +75,24 @@ func NewTreePkglistCommand() *cobra.Command {
if len(t) == 0 {
Fatal("Mandatory tree param missing.")
}
revdeps, _ := cmd.Flags().GetBool("revdeps")
deps, _ := cmd.Flags().GetBool("deps")
if revdeps && deps {
Fatal("Both revdeps and deps option used. Choice only one.")
}
},
Run: func(cmd *cobra.Command, args []string) {
var results TreeResults
var depSolver solver.PackageSolver
treePath, _ := cmd.Flags().GetStringArray("tree")
verbose, _ := cmd.Flags().GetBool("verbose")
buildtime, _ := cmd.Flags().GetBool("buildtime")
full, _ := cmd.Flags().GetBool("full")
revdeps, _ := cmd.Flags().GetBool("revdeps")
deps, _ := cmd.Flags().GetBool("deps")
out, _ := cmd.Flags().GetString("output")
if out != "terminal" {
@@ -95,6 +105,7 @@ func NewTreePkglistCommand() *cobra.Command {
} else {
reciper = tree.NewInstallerRecipe(pkg.NewInMemoryDatabase(false))
}
for _, t := range treePath {
err := reciper.Load(t)
if err != nil {
@@ -102,6 +113,15 @@ func NewTreePkglistCommand() *cobra.Command {
}
}
if deps {
emptyInstallationDb := pkg.NewInMemoryDatabase(false)
depSolver = solver.NewSolver(pkg.NewInMemoryDatabase(false),
reciper.GetDatabase(),
emptyInstallationDb)
}
regExcludes, err := helpers.CreateRegexArray(excludes)
if err != nil {
Fatal(err.Error())
@@ -146,15 +166,8 @@ func NewTreePkglistCommand() *cobra.Command {
}
if addPkg {
if !revdeps {
plist = append(plist, pkgstr)
results.Packages = append(results.Packages, TreePackageResult{
Name: p.GetName(),
Version: p.GetVersion(),
Category: p.GetCategory(),
Path: p.GetPath(),
})
} else {
if revdeps {
visited := make(map[string]interface{})
for _, revdep := range p.ExpandedRevdeps(reciper.GetDatabase(), visited) {
if full {
@@ -172,7 +185,58 @@ func NewTreePkglistCommand() *cobra.Command {
Path: revdep.GetPath(),
})
}
} else if deps {
Spinner(32)
solution, err := depSolver.Install(pkg.Packages{p})
if err != nil {
Fatal(err.Error())
}
ass := solution.SearchByName(p.GetPackageName())
solution, err = solution.Order(reciper.GetDatabase(), ass.Package.GetFingerPrint())
if err != nil {
Fatal(err.Error())
}
SpinnerStop()
for _, pa := range solution {
if pa.Value {
// Exclude itself
if pa.Package.GetName() == p.GetName() && pa.Package.GetCategory() == p.GetCategory() {
continue
}
if full {
pkgstr = pkgDetail(pa.Package)
} else if verbose {
pkgstr = pa.Package.HumanReadableString()
} else {
pkgstr = fmt.Sprintf("%s/%s", pa.Package.GetCategory(), pa.Package.GetName())
}
plist = append(plist, pkgstr)
results.Packages = append(results.Packages, TreePackageResult{
Name: pa.Package.GetName(),
Version: pa.Package.GetVersion(),
Category: pa.Package.GetCategory(),
Path: pa.Package.GetPath(),
})
}
}
} else {
plist = append(plist, pkgstr)
results.Packages = append(results.Packages, TreePackageResult{
Name: p.GetName(),
Version: p.GetVersion(),
Category: p.GetCategory(),
Path: p.GetPath(),
})
}
}
}
@@ -192,7 +256,9 @@ func NewTreePkglistCommand() *cobra.Command {
}
fmt.Println(string(j2))
default:
if !deps {
sort.Strings(plist)
}
for _, p := range plist {
fmt.Println(p)
}
@@ -204,6 +270,7 @@ func NewTreePkglistCommand() *cobra.Command {
ans.Flags().BoolP("buildtime", "b", false, "Build time match")
ans.Flags().StringP("output", "o", "terminal", "Output format ( Defaults: terminal, available: json,yaml )")
ans.Flags().Bool("revdeps", false, "Search package reverse dependencies")
ans.Flags().Bool("deps", false, "Search package dependencies")
ans.Flags().BoolP("verbose", "v", false, "Add package version")
ans.Flags().BoolP("full", "f", false, "Show package detail")

View File

@@ -184,7 +184,7 @@ func validateWorker(i int,
))
// Check if the solver is already been done for the deep
_, err := cacheDeps.Get(r.HashFingerprint())
_, err := cacheDeps.Get(r.HashFingerprint(""))
if err == nil {
Debug(" :direct_hit: Cache Hit for dep",
fmt.Sprintf("%s/%s-%s", r.GetCategory(), r.GetName(), r.GetVersion()))
@@ -218,7 +218,7 @@ func validateWorker(i int,
}
// Register the key
cacheDeps.Set(r.HashFingerprint(), "1")
cacheDeps.Set(r.HashFingerprint(""), "1")
}
}

View File

@@ -62,6 +62,7 @@ var upgradeCmd = &cobra.Command{
full, _ := cmd.Flags().GetBool("full")
universe, _ := cmd.Flags().GetBool("universe")
clean, _ := cmd.Flags().GetBool("clean")
sync, _ := cmd.Flags().GetBool("sync")
LuetCfg.GetSolverOptions().Type = stype
LuetCfg.GetSolverOptions().LearnRate = float32(rate)
@@ -78,6 +79,7 @@ var upgradeCmd = &cobra.Command{
NoDeps: nodeps,
SolverUpgrade: universe,
RemoveUnavailableOnUpgrade: clean,
UpgradeNewRevisions: sync,
})
inst.Repositories(repos)
_, err := inst.SyncRepositories(false)
@@ -115,6 +117,7 @@ func init() {
upgradeCmd.Flags().Bool("full", true, "Attempts to remove as much packages as possible which aren't required (slow)")
upgradeCmd.Flags().Bool("universe", false, "Use ONLY the SAT solver to compute upgrades (experimental)")
upgradeCmd.Flags().Bool("clean", false, "Try to drop removed packages (experimental, only when --universe is enabled)")
upgradeCmd.Flags().Bool("sync", false, "Upgrade packages with new revisions (experimental)")
RootCmd.AddCommand(upgradeCmd)
}

View File

@@ -23,6 +23,7 @@ import (
"regexp"
"strings"
"sync"
"time"
"github.com/mudler/luet/pkg/helpers"
. "github.com/mudler/luet/pkg/logger"
@@ -229,13 +230,30 @@ func (cs *LuetCompiler) stripIncludesFromRootfs(includes []string, rootfs string
}
func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage string, concurrency int, keepPermissions, keepImg bool, p CompilationSpec) (Artifact, error) {
fp := p.GetPackage().HashFingerprint()
pkgTag := ":package: " + p.GetPackage().GetName()
// Use packageImage as salt into the fp being used
// so the hash is unique also in cases where
// some package deps does have completely different
// depgraphs
// TODO: As the salt contains the packageImage ( in registry/organization/imagename:tag format)
// the images hashes are broken with registry mirrors.
// We should use the image tag, or pass by the package assertion hash which is unique
// and identifies the deptree of the package.
fp := p.GetPackage().HashFingerprint(packageImage)
if buildertaggedImage == "" {
buildertaggedImage = cs.ImageRepository + "-" + fp + "-builder"
Debug(pkgTag, "Creating intermediary image", buildertaggedImage, "from", image)
}
// TODO: Cleanup, not actually hit
if packageImage == "" {
packageImage = cs.ImageRepository + "-" + fp
}
if !cs.Clean {
exists := cs.Backend.ImageExists(buildertaggedImage) && cs.Backend.ImageExists(packageImage)
if art, err := LoadArtifactFromYaml(p); err == nil && exists {
@@ -243,7 +261,6 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage
return art, err
}
}
pkgTag := ":package: " + p.GetPackage().GetName()
p.SetSeedImage(image) // In this case, we ignore the build deps as we suppose that the image has them - otherwise we recompose the tree with a solver,
// and we build all the images first.
@@ -439,6 +456,8 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage
artifact.SetFiles(filelist)
artifact.GetCompileSpec().GetPackage().SetBuildTimestamp(time.Now().String())
err = artifact.WriteYaml(p.GetOutputPath())
if err != nil {
return artifact, errors.Wrap(err, "Failed while writing metadata file")
@@ -513,7 +532,6 @@ func (cs *LuetCompiler) ComputeDepTree(p CompilationSpec) (solver.PackagesAssert
for _, assertion := range dependencies { //highly dependent on the order
if assertion.Value {
nthsolution := dependencies.Cut(assertion.Package)
assertion.Hash = solver.PackageHash{
BuildHash: nthsolution.HashFrom(assertion.Package),
PackageHash: nthsolution.AssertionHash(),

View File

@@ -44,7 +44,7 @@ type LuetInstallerOptions struct {
PreserveSystemEssentialData bool
FullUninstall, FullCleanUninstall bool
CheckConflicts bool
SolverUpgrade, RemoveUnavailableOnUpgrade bool
SolverUpgrade, RemoveUnavailableOnUpgrade, UpgradeNewRevisions bool
}
type LuetInstaller struct {
@@ -90,12 +90,18 @@ func (l *LuetInstaller) Upgrade(s *System) error {
}
}
Info("Marked for uninstall")
if len(uninstall) > 0 {
Info("Packages marked for uninstall:")
}
for _, p := range uninstall {
Info(fmt.Sprintf("- %s", p.HumanReadableString()))
}
Info("Marked for upgrade")
if len(solution) > 0 {
Info("Packages marked for upgrade:")
}
toInstall := pkg.Packages{}
for _, assertion := range solution {
// Be sure to filter from solutions packages already installed in the system
@@ -105,6 +111,37 @@ func (l *LuetInstaller) Upgrade(s *System) error {
}
}
if l.Options.UpgradeNewRevisions {
Info("Checking packages with new revisions available")
for _, p := range s.Database.World() {
matches := syncedRepos.PackageMatches(pkg.Packages{p})
if len(matches) == 0 {
// Package missing. the user should run luet upgrade --universe
Info("Installed packages seems to be missing from remote repositories.")
Info("It is suggested to run 'luet upgrade --universe'")
continue
}
for _, artefact := range matches[0].Repo.GetIndex() {
if artefact.GetCompileSpec().GetPackage() == nil {
return errors.New("Package in compilespec empty")
}
if artefact.GetCompileSpec().GetPackage().Matches(p) && artefact.GetCompileSpec().GetPackage().GetBuildTimestamp() != p.GetBuildTimestamp() {
toInstall = append(toInstall, matches[0].Package).Unique()
uninstall = append(uninstall, p).Unique()
Info(
fmt.Sprintf("- %s ( %s vs %s ) repo: %s (date: %s)",
p.HumanReadableString(),
artefact.GetCompileSpec().GetPackage().GetBuildTimestamp(),
p.GetBuildTimestamp(),
matches[0].Repo.GetName(),
matches[0].Repo.GetLastUpdate(),
))
}
}
}
}
return l.swap(syncedRepos, uninstall, toInstall, s)
}
@@ -349,6 +386,7 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp pkg.Packages, s *Sy
}
if matches[0].Package.Matches(artefact.GetCompileSpec().GetPackage()) {
currentPack.SetBuildTimestamp(artefact.GetCompileSpec().GetPackage().GetBuildTimestamp())
// Filter out already installed
if _, err := s.Database.FindPackage(currentPack); err != nil {
toInstall[currentPack.GetFingerPrint()] = ArtifactMatch{Package: currentPack, Artifact: artefact, Repository: matches[0].Repo}

View File

@@ -78,13 +78,14 @@ func Spinner(i int) {
i = 43
}
if !s.Active() {
if s != nil && !s.Active() {
// s.UpdateCharSet(spinner.CharSets[i])
s.Start() // Start the spinner
}
}
func SpinnerText(suffix, prefix string) {
if s != nil {
s.Lock()
defer s.Unlock()
if LuetCfg.GetGeneral().Debug {
@@ -97,6 +98,7 @@ func SpinnerText(suffix, prefix string) {
s.Prefix = Bold(Cyan(prefix)).String()
}
}
}
func SpinnerStop() {
var confLevel int
@@ -108,8 +110,10 @@ func SpinnerStop() {
if 2 > confLevel {
return
}
if s != nil {
s.Stop()
}
}
func level2Number(level string) int {
switch level {

View File

@@ -105,7 +105,10 @@ type Package interface {
String() string
HumanReadableString() string
HashFingerprint() string
HashFingerprint(string) string
SetBuildTimestamp(s string)
GetBuildTimestamp() string
Clone() Package
}
@@ -173,6 +176,7 @@ type DefaultPackage struct {
Description string `json:"description,omitempty"`
Uri []string `json:"uri,omitempty"`
License string `json:"license,omitempty"`
BuildTimestamp string `json:"buildtimestamp,omitempty"`
Labels map[string]string `json:"labels,omitempty"` // Affects YAML field names too.
}
@@ -205,9 +209,9 @@ func (p *DefaultPackage) GetFingerPrint() string {
return fmt.Sprintf("%s-%s-%s", p.Name, p.Category, p.Version)
}
func (p *DefaultPackage) HashFingerprint() string {
func (p *DefaultPackage) HashFingerprint(salt string) string {
h := md5.New()
io.WriteString(h, p.GetFingerPrint())
io.WriteString(h, fmt.Sprintf("%s-%s", p.GetFingerPrint(), salt))
return fmt.Sprintf("%x", h.Sum(nil))
}
@@ -229,6 +233,16 @@ func (p *DefaultPackage) GetPackageName() string {
return fmt.Sprintf("%s-%s", p.Name, p.Category)
}
// GetBuildTimestamp returns the package build timestamp
func (p *DefaultPackage) GetBuildTimestamp() string {
return p.BuildTimestamp
}
// SetBuildTimestamp sets the package Build timestamp
func (p *DefaultPackage) SetBuildTimestamp(s string) {
p.BuildTimestamp = s
}
// GetPath returns the path where the definition file was found
func (p *DefaultPackage) GetPath() string {
return p.Path

View File

@@ -36,8 +36,8 @@ var _ = Describe("Package", func() {
})
It("Generates packages fingerprint's hashes", func() {
Expect(a.HashFingerprint()).ToNot(Equal(a1.HashFingerprint()))
Expect(a.HashFingerprint()).To(Equal("c64caa391b79adb598ad98e261aa79a0"))
Expect(a.HashFingerprint("")).ToNot(Equal(a1.HashFingerprint("")))
Expect(a.HashFingerprint("")).To(Equal("76972ef6991ec6102f33b401105c1351"))
})
})

View File

@@ -28,7 +28,7 @@ import (
)
func LoadRepositories(c *LuetConfig) error {
var regexRepo = regexp.MustCompile(`.yml$`)
var regexRepo = regexp.MustCompile(`.yml$|.yaml$`)
for _, rdir := range c.RepositoriesConfDir {
Debug("Parsing Repository Directory", rdir, "...")

View File

@@ -35,12 +35,22 @@ var _ = Describe("Repository", func() {
It("Chec Load Repository 1", func() {
Expect(err).Should(BeNil())
Expect(len(cfg.SystemRepositories)).Should(Equal(1))
Expect(len(cfg.SystemRepositories)).Should(Equal(2))
Expect(cfg.SystemRepositories[0].Name).Should(Equal("test1"))
Expect(cfg.SystemRepositories[0].Priority).Should(Equal(999))
Expect(cfg.SystemRepositories[0].Type).Should(Equal("disk"))
Expect(len(cfg.SystemRepositories[0].Urls)).Should(Equal(1))
Expect(cfg.SystemRepositories[0].Urls[0]).Should(Equal("tests/repos/test1"))
})
It("Chec Load Repository 2", func() {
Expect(err).Should(BeNil())
Expect(len(cfg.SystemRepositories)).Should(Equal(2))
Expect(cfg.SystemRepositories[1].Name).Should(Equal("test2"))
Expect(cfg.SystemRepositories[1].Priority).Should(Equal(1000))
Expect(cfg.SystemRepositories[1].Type).Should(Equal("disk"))
Expect(len(cfg.SystemRepositories[1].Urls)).Should(Equal(1))
Expect(cfg.SystemRepositories[1].Urls[0]).Should(Equal("tests/repos/test2"))
})
})
})

View File

@@ -0,0 +1,9 @@
name: "test2"
description: "Test2 Repository"
type: "disk"
urls:
- "tests/repos/test2"
priority: 1000
enable: true
# auth:
# token: "xxxxx"

View File

@@ -0,0 +1,10 @@
prelude:
- echo foo > /test
- echo bar > /test2
steps:
- echo c > /c
- echo c > /cd
requires:
- category: "test"
name: "a"
version: ">=1.0"

View File

@@ -0,0 +1,3 @@
category: "test"
name: "c"
version: "1.0"

View File

@@ -0,0 +1,11 @@
image: "alpine"
prelude:
- echo foo > /test
- echo bar > /test2
steps:
- echo artifact3 > /test3
- echo artifact4 > /test4
requires:
- category: "test"
name: "b"
version: "1.0"

View File

@@ -0,0 +1,8 @@
category: "test"
name: "a"
version: "1.1"
requires:
- category: "test2"
name: "b"
version: "1.0"

View File

@@ -0,0 +1,9 @@
image: "alpine"
prelude:
- echo foo > /test
- echo bar > /test2
- chmod +x generate.sh
steps:
- echo artifact5 > /newc
- echo artifact6 > /newnewc
- ./generate.sh

View File

@@ -0,0 +1,3 @@
category: "test"
name: "b"
version: "1.0"

View File

@@ -0,0 +1 @@
echo generated > /sonewc

View File

@@ -0,0 +1,116 @@
#!/bin/bash
export LUET_NOLOCK=true
oneTimeSetUp() {
export tmpdir="$(mktemp -d)"
}
oneTimeTearDown() {
rm -rf "$tmpdir"
}
testBuild() {
mkdir $tmpdir/testbuild
luet build --tree "$ROOT_DIR/tests/fixtures/upgrade_old_repo" --destination $tmpdir/testbuild --compression gzip --full --clean=true
buildst=$?
assertTrue 'create package B 1.0' "[ -e '$tmpdir/testbuild/b-test-1.0.package.tar.gz' ]"
assertEquals 'builds successfully' "$buildst" "0"
mkdir $tmpdir/testbuild_revision
luet build --tree "$ROOT_DIR/tests/fixtures/upgrade_old_repo_revision" --destination $tmpdir/testbuild_revision --compression gzip --full --clean=true
buildst=$?
assertTrue 'create package B 1.0' "[ -e '$tmpdir/testbuild_revision/b-test-1.0.package.tar.gz' ]"
assertEquals 'builds successfully' "$buildst" "0"
}
testRepo() {
assertTrue 'no repository' "[ ! -e '$tmpdir/testbuild/repository.yaml' ]"
luet create-repo --tree "$ROOT_DIR/tests/fixtures/upgrade_old_repo" \
--output $tmpdir/testbuild \
--packages $tmpdir/testbuild \
--name "test" \
--descr "Test Repo" \
--urls $tmpdir/testrootfs \
--type http
createst=$?
assertEquals 'create repo successfully' "$createst" "0"
assertTrue 'create repository' "[ -e '$tmpdir/testbuild/repository.yaml' ]"
assertTrue 'no repository' "[ ! -e '$tmpdir/testbuild_revision/repository.yaml' ]"
luet create-repo --tree "$ROOT_DIR/tests/fixtures/upgrade_old_repo_revision" \
--output $tmpdir/testbuild_revision \
--packages $tmpdir/testbuild_revision \
--name "test" \
--descr "Test Repo" \
--urls $tmpdir/testrootfs \
--type http
createst=$?
assertEquals 'create repo successfully' "$createst" "0"
assertTrue 'create repository' "[ -e '$tmpdir/testbuild_revision/repository.yaml' ]"
}
testConfig() {
mkdir $tmpdir/testrootfs
cat <<EOF > $tmpdir/luet.yaml
general:
debug: true
system:
rootfs: $tmpdir/testrootfs
database_path: "/"
database_engine: "boltdb"
repositories:
- name: "main"
type: "disk"
enable: true
urls:
- "$tmpdir/testbuild"
EOF
luet config --config $tmpdir/luet.yaml
res=$?
assertEquals 'config test successfully' "$res" "0"
}
testUpgrade() {
luet install --config $tmpdir/luet.yaml test/b-1.0
installst=$?
assertEquals 'install test successfully' "$installst" "0"
assertTrue 'package installed B' "[ -e '$tmpdir/testrootfs/test5' ]"
cat <<EOF > $tmpdir/luet.yaml
general:
debug: true
system:
rootfs: $tmpdir/testrootfs
database_path: "/"
database_engine: "boltdb"
repositories:
- name: "main"
type: "disk"
enable: true
urls:
- "$tmpdir/testbuild_revision"
EOF
luet cleanup --config $tmpdir/luet.yaml
luet config --config $tmpdir/luet.yaml
res=$?
assertEquals 'config test successfully' "$res" "0"
luet upgrade --sync --config $tmpdir/luet.yaml
installst=$?
assertEquals 'upgrade test successfully' "$installst" "0"
assertTrue 'package uninstalled B' "[ ! -e '$tmpdir/testrootfs/test5' ]"
assertTrue 'package installed B' "[ -e '$tmpdir/testrootfs/newc' ]"
content=$(luet upgrade --sync --config $tmpdir/luet.yaml)
installst=$?
assertNotContains 'didn not upgrade' "$content" "Uninstalling"
}
# Load shUnit2.
. "$ROOT_DIR/tests/integration/shunit2"/shunit2