[lxc-devel] [lxd/master] Instance: Updates templateApplyNow to close files at end of each iteration

tomponline on Github lxc-bot at linuxcontainers.org
Thu Oct 15 08:39:19 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 498 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20201015/641a79f0/attachment.bin>
-------------- next part --------------
From 6ffef1d5a7cd31671e1595fa4670fe58570acb1b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 15 Oct 2020 09:37:57 +0100
Subject: [PATCH] lxd/instance/drivers: Updates templateApplyNow to close files
 at end of each iteration

By using an anonymous function so that defer runs at end of each iteration.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/instance/drivers/driver_lxc.go  | 124 +++++++++++++++-------------
 lxd/instance/drivers/driver_qemu.go |  99 +++++++++++-----------
 2 files changed, 119 insertions(+), 104 deletions(-)

diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index ac307d6d1e..7e716b9d7d 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -5119,81 +5119,89 @@ func (c *lxc) templateApplyNow(trigger string) error {
 
 	// Go through the templates
 	for tplPath, tpl := range metadata.Templates {
-		var w *os.File
+		err = func(tplPath string, tpl *api.ImageMetadataTemplate) error {
+			var w *os.File
+
+			// Check if the template should be applied now
+			found := false
+			for _, tplTrigger := range tpl.When {
+				if tplTrigger == trigger {
+					found = true
+					break
+				}
+			}
 
-		// Check if the template should be applied now
-		found := false
-		for _, tplTrigger := range tpl.When {
-			if tplTrigger == trigger {
-				found = true
-				break
+			if !found {
+				return nil
 			}
-		}
 
-		if !found {
-			continue
-		}
+			// Open the file to template, create if needed
+			fullpath := filepath.Join(c.RootfsPath(), strings.TrimLeft(tplPath, "/"))
+			if shared.PathExists(fullpath) {
+				if tpl.CreateOnly {
+					return nil
+				}
 
-		// Open the file to template, create if needed
-		fullpath := filepath.Join(c.RootfsPath(), strings.TrimLeft(tplPath, "/"))
-		if shared.PathExists(fullpath) {
-			if tpl.CreateOnly {
-				continue
+				// Open the existing file
+				w, err = os.Create(fullpath)
+				if err != nil {
+					return errors.Wrap(err, "Failed to create template file")
+				}
+			} else {
+				// Create the directories leading to the file
+				shared.MkdirAllOwner(path.Dir(fullpath), 0755, int(rootUID), int(rootGID))
+
+				// Create the file itself
+				w, err = os.Create(fullpath)
+				if err != nil {
+					return err
+				}
+
+				// Fix ownership and mode
+				w.Chown(int(rootUID), int(rootGID))
+				w.Chmod(0644)
 			}
+			defer w.Close()
 
-			// Open the existing file
-			w, err = os.Create(fullpath)
+			// Read the template
+			tplString, err := ioutil.ReadFile(filepath.Join(c.TemplatesPath(), tpl.Template))
 			if err != nil {
-				return errors.Wrap(err, "Failed to create template file")
+				return errors.Wrap(err, "Failed to read template file")
 			}
-		} else {
-			// Create the directories leading to the file
-			shared.MkdirAllOwner(path.Dir(fullpath), 0755, int(rootUID), int(rootGID))
 
-			// Create the file itself
-			w, err = os.Create(fullpath)
+			// Restrict filesystem access to within the container's rootfs
+			tplSet := pongo2.NewSet(fmt.Sprintf("%s-%s", c.name, tpl.Template), template.ChrootLoader{Path: c.RootfsPath()})
+
+			tplRender, err := tplSet.FromString("{% autoescape off %}" + string(tplString) + "{% endautoescape %}")
 			if err != nil {
-				return err
+				return errors.Wrap(err, "Failed to render template")
 			}
 
-			// Fix ownership and mode
-			w.Chown(int(rootUID), int(rootGID))
-			w.Chmod(0644)
-		}
-		defer w.Close()
-
-		// Read the template
-		tplString, err := ioutil.ReadFile(filepath.Join(c.TemplatesPath(), tpl.Template))
-		if err != nil {
-			return errors.Wrap(err, "Failed to read template file")
-		}
+			configGet := func(confKey, confDefault *pongo2.Value) *pongo2.Value {
+				val, ok := c.expandedConfig[confKey.String()]
+				if !ok {
+					return confDefault
+				}
 
-		// Restrict filesystem access to within the container's rootfs
-		tplSet := pongo2.NewSet(fmt.Sprintf("%s-%s", c.name, tpl.Template), template.ChrootLoader{Path: c.RootfsPath()})
+				return pongo2.AsValue(strings.TrimRight(val, "\r\n"))
+			}
 
-		tplRender, err := tplSet.FromString("{% autoescape off %}" + string(tplString) + "{% endautoescape %}")
-		if err != nil {
-			return errors.Wrap(err, "Failed to render template")
-		}
+			// Render the template
+			tplRender.ExecuteWriter(pongo2.Context{"trigger": trigger,
+				"path":       tplPath,
+				"container":  containerMeta,
+				"instance":   containerMeta,
+				"config":     c.expandedConfig,
+				"devices":    c.expandedDevices,
+				"properties": tpl.Properties,
+				"config_get": configGet}, w)
 
-		configGet := func(confKey, confDefault *pongo2.Value) *pongo2.Value {
-			val, ok := c.expandedConfig[confKey.String()]
-			if !ok {
-				return confDefault
-			}
+			return nil
 
-			return pongo2.AsValue(strings.TrimRight(val, "\r\n"))
+		}(tplPath, tpl)
+		if err != nil {
+			return err
 		}
-
-		// Render the template
-		tplRender.ExecuteWriter(pongo2.Context{"trigger": trigger,
-			"path":       tplPath,
-			"container":  containerMeta,
-			"instance":   containerMeta,
-			"config":     c.expandedConfig,
-			"devices":    c.expandedDevices,
-			"properties": tpl.Properties,
-			"config_get": configGet}, w)
 	}
 
 	return nil
diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index 4fb7f8a37f..1abaddbbb2 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -1534,62 +1534,69 @@ func (vm *qemu) templateApplyNow(trigger string, path string) error {
 
 	// Go through the templates.
 	for tplPath, tpl := range metadata.Templates {
-		var w *os.File
-
-		// Check if the template should be applied now.
-		found := false
-		for _, tplTrigger := range tpl.When {
-			if tplTrigger == trigger {
-				found = true
-				break
+		err = func(tplPath string, tpl *api.ImageMetadataTemplate) error {
+			var w *os.File
+
+			// Check if the template should be applied now.
+			found := false
+			for _, tplTrigger := range tpl.When {
+				if tplTrigger == trigger {
+					found = true
+					break
+				}
 			}
-		}
 
-		if !found {
-			continue
-		}
+			if !found {
+				return nil
+			}
 
-		// Create the file itself.
-		w, err = os.Create(filepath.Join(path, fmt.Sprintf("%s.out", tpl.Template)))
-		if err != nil {
-			return err
-		}
+			// Create the file itself.
+			w, err = os.Create(filepath.Join(path, fmt.Sprintf("%s.out", tpl.Template)))
+			if err != nil {
+				return err
+			}
 
-		// Fix ownership and mode.
-		w.Chmod(0644)
-		defer w.Close()
+			// Fix ownership and mode.
+			w.Chmod(0644)
+			defer w.Close()
 
-		// Read the template.
-		tplString, err := ioutil.ReadFile(filepath.Join(vm.TemplatesPath(), tpl.Template))
-		if err != nil {
-			return errors.Wrap(err, "Failed to read template file")
-		}
+			// Read the template.
+			tplString, err := ioutil.ReadFile(filepath.Join(vm.TemplatesPath(), tpl.Template))
+			if err != nil {
+				return errors.Wrap(err, "Failed to read template file")
+			}
 
-		// Restrict filesystem access to within the container's rootfs.
-		tplSet := pongo2.NewSet(fmt.Sprintf("%s-%s", vm.name, tpl.Template), pongoTemplate.ChrootLoader{Path: vm.TemplatesPath()})
-		tplRender, err := tplSet.FromString("{% autoescape off %}" + string(tplString) + "{% endautoescape %}")
-		if err != nil {
-			return errors.Wrap(err, "Failed to render template")
-		}
+			// Restrict filesystem access to within the container's rootfs.
+			tplSet := pongo2.NewSet(fmt.Sprintf("%s-%s", vm.name, tpl.Template), pongoTemplate.ChrootLoader{Path: vm.TemplatesPath()})
+			tplRender, err := tplSet.FromString("{% autoescape off %}" + string(tplString) + "{% endautoescape %}")
+			if err != nil {
+				return errors.Wrap(err, "Failed to render template")
+			}
+
+			configGet := func(confKey, confDefault *pongo2.Value) *pongo2.Value {
+				val, ok := vm.expandedConfig[confKey.String()]
+				if !ok {
+					return confDefault
+				}
 
-		configGet := func(confKey, confDefault *pongo2.Value) *pongo2.Value {
-			val, ok := vm.expandedConfig[confKey.String()]
-			if !ok {
-				return confDefault
+				return pongo2.AsValue(strings.TrimRight(val, "\r\n"))
 			}
 
-			return pongo2.AsValue(strings.TrimRight(val, "\r\n"))
-		}
+			// Render the template.
+			tplRender.ExecuteWriter(pongo2.Context{"trigger": trigger,
+				"path":       tplPath,
+				"instance":   instanceMeta,
+				"container":  instanceMeta, // FIXME: remove once most images have moved away.
+				"config":     vm.expandedConfig,
+				"devices":    vm.expandedDevices,
+				"properties": tpl.Properties,
+				"config_get": configGet}, w)
 
-		// Render the template.
-		tplRender.ExecuteWriter(pongo2.Context{"trigger": trigger,
-			"path":       tplPath,
-			"instance":   instanceMeta,
-			"container":  instanceMeta, // FIXME: remove once most images have moved away.
-			"config":     vm.expandedConfig,
-			"devices":    vm.expandedDevices,
-			"properties": tpl.Properties,
-			"config_get": configGet}, w)
+			return nil
+		}(tplPath, tpl)
+		if err != nil {
+			return err
+		}
 	}
 
 	return nil


More information about the lxc-devel mailing list