[lxc-devel] [distrobuilder/master] distrobuilder: Optimize package handling

monstermunchkin on Github lxc-bot at linuxcontainers.org
Fri Aug 9 14:26:07 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190809/14be2903/attachment.bin>
-------------- next part --------------
From c8c07ef25872e0483c9e5ee9d5022e6f5dfaba6f Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Fri, 9 Aug 2019 16:20:04 +0200
Subject: [PATCH] distrobuilder: Optimize package handling

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 distrobuilder/chroot.go      | 41 ++++++++++++++++++++++++
 distrobuilder/chroot_test.go | 60 ++++++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+)
 create mode 100644 distrobuilder/chroot_test.go

diff --git a/distrobuilder/chroot.go b/distrobuilder/chroot.go
index cd3c45a..aa3e8e6 100644
--- a/distrobuilder/chroot.go
+++ b/distrobuilder/chroot.go
@@ -62,6 +62,8 @@ func managePackages(def shared.DefinitionPackages, actions []shared.DefinitionAc
 		manager.SetInstallFlags("install", "--allow-downgrade")
 	}
 
+	var validSets []shared.DefinitionPackagesSet
+
 	for _, set := range def.Sets {
 		if len(set.Releases) > 0 && !lxd.StringInSlice(release, set.Releases) {
 			continue
@@ -71,6 +73,10 @@ func managePackages(def shared.DefinitionPackages, actions []shared.DefinitionAc
 			continue
 		}
 
+		validSets = append(validSets, set)
+	}
+
+	for _, set := range optimizePackageSets(validSets) {
 		if set.Action == "install" {
 			err = manager.Install(set.Packages)
 		} else if set.Action == "remove" {
@@ -90,3 +96,38 @@ func managePackages(def shared.DefinitionPackages, actions []shared.DefinitionAc
 
 	return nil
 }
+
+// optimizePackageSets groups consecutive package sets with the same action to
+// reduce the amount of calls to manager.{Install,Remove}(). It still honors the
+// order of execution.
+func optimizePackageSets(sets []shared.DefinitionPackagesSet) []shared.DefinitionPackagesSet {
+	if len(sets) < 2 {
+		return sets
+	}
+
+	var newSets []shared.DefinitionPackagesSet
+
+	action := sets[0].Action
+	packages := sets[0].Packages
+
+	for i := 1; i < len(sets); i++ {
+		if sets[i].Action == sets[i-1].Action {
+			packages = append(packages, sets[i].Packages...)
+		} else {
+			newSets = append(newSets, shared.DefinitionPackagesSet{
+				Action:   action,
+				Packages: packages,
+			})
+
+			action = sets[i].Action
+			packages = sets[i].Packages
+		}
+	}
+
+	newSets = append(newSets, shared.DefinitionPackagesSet{
+		Action:   action,
+		Packages: packages,
+	})
+
+	return newSets
+}
diff --git a/distrobuilder/chroot_test.go b/distrobuilder/chroot_test.go
new file mode 100644
index 0000000..ab4a4c4
--- /dev/null
+++ b/distrobuilder/chroot_test.go
@@ -0,0 +1,60 @@
+package main
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+
+	"github.com/lxc/distrobuilder/shared"
+)
+
+func TestManagePackages(t *testing.T) {
+	sets := []shared.DefinitionPackagesSet{
+		{
+			Packages: []string{"foo"},
+			Action:   "install",
+		},
+		{
+			Packages: []string{"bar"},
+			Action:   "install",
+		},
+		{
+			Packages: []string{"baz"},
+			Action:   "remove",
+		},
+		{
+			Packages: []string{"lorem"},
+			Action:   "remove",
+		},
+		{
+			Packages: []string{"ipsum"},
+			Action:   "install",
+		},
+		{
+			Packages: []string{"dolor"},
+			Action:   "remove",
+		},
+	}
+
+	optimizedSets := optimizePackageSets(sets)
+	require.Len(t, optimizedSets, 4)
+	require.Equal(t, optimizedSets[0], shared.DefinitionPackagesSet{Action: "install", Packages: []string{"foo", "bar"}})
+	require.Equal(t, optimizedSets[1], shared.DefinitionPackagesSet{Action: "remove", Packages: []string{"baz", "lorem"}})
+	require.Equal(t, optimizedSets[2], shared.DefinitionPackagesSet{Action: "install", Packages: []string{"ipsum"}})
+	require.Equal(t, optimizedSets[3], shared.DefinitionPackagesSet{Action: "remove", Packages: []string{"dolor"}})
+
+	sets = []shared.DefinitionPackagesSet{
+		{
+			Packages: []string{"foo"},
+			Action:   "install",
+		},
+	}
+
+	optimizedSets = optimizePackageSets(sets)
+	require.Len(t, optimizedSets, 1)
+	require.Equal(t, optimizedSets[0], shared.DefinitionPackagesSet{Action: "install", Packages: []string{"foo"}})
+
+	sets = []shared.DefinitionPackagesSet{}
+	optimizedSets = optimizePackageSets(sets)
+	require.Len(t, optimizedSets, 0)
+}


More information about the lxc-devel mailing list