The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8035

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
By using an anonymous function so that defer runs at end of each iteration.

Similar to fix in https://github.com/lxc/lxd/pull/8025

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
From 6ffef1d5a7cd31671e1595fa4670fe58570acb1b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@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.parr...@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
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to