diff --git a/shared/definition.go b/shared/definition.go index fb42f5e..63cba8c 100644 --- a/shared/definition.go +++ b/shared/definition.go @@ -37,6 +37,7 @@ type DefinitionSource struct { Keyserver string `yaml:"keyserver,omitempty"` Variant string `yaml:"variant,omitempty"` Suite string `yaml:"suite,omitempty"` + AptSources string `yaml:"apt_sources,omitempty"` } // A DefinitionTargetLXC represents LXC specific files as part of the metadata. diff --git a/sources/debootstrap.go b/sources/debootstrap.go index da98d55..70183a2 100644 --- a/sources/debootstrap.go +++ b/sources/debootstrap.go @@ -5,6 +5,8 @@ import ( "path" "path/filepath" + "gopkg.in/flosch/pongo2.v3" + "github.com/lxc/distrobuilder/shared" ) @@ -57,5 +59,38 @@ func (s *Debootstrap) Run(source shared.DefinitionSource, release, arch, rootfsD defer os.Remove(link) } - return shared.RunCommand("debootstrap", args...) + err := shared.RunCommand("debootstrap", args...) + if err != nil { + return err + } + + if source.AptSources != "" { + ctx := pongo2.Context{ + "source": source, + // We use an anonymous struct instead of DefinitionImage because we + // need the mapped architecture, and Release is all one + // needs in the sources.list. + "image": struct { + Release string + }{ + release, + }, + } + + out, err := shared.RenderTemplate(source.AptSources, ctx) + if err != nil { + return err + } + + // Replace content of sources.list with the templated content. + file, err := os.Create(filepath.Join(rootfsDir, "etc", "apt", "sources.list")) + if err != nil { + return err + } + defer file.Close() + + file.WriteString(out) + } + + return nil } diff --git a/sources/ubuntu-http.go b/sources/ubuntu-http.go index ef61a00..bfda436 100644 --- a/sources/ubuntu-http.go +++ b/sources/ubuntu-http.go @@ -11,6 +11,7 @@ import ( "strings" lxd "github.com/lxc/lxd/shared" + "gopkg.in/flosch/pongo2.v3" "github.com/lxc/distrobuilder/shared" ) @@ -61,7 +62,40 @@ func (s *UbuntuHTTP) Run(source shared.DefinitionSource, release, arch, rootfsDi return fmt.Errorf("Error downloading Ubuntu image: %s", err) } - return s.unpack(filepath.Join(os.TempDir(), s.fname), rootfsDir) + err = s.unpack(filepath.Join(os.TempDir(), s.fname), rootfsDir) + if err != nil { + return err + } + + if source.AptSources != "" { + ctx := pongo2.Context{ + "source": source, + // We use an anonymous struct instead of DefinitionImage because we + // need the mapped architecture, and Release is all one needs in + // the sources.list. + "image": struct { + Release string + }{ + release, + }, + } + + out, err := shared.RenderTemplate(source.AptSources, ctx) + if err != nil { + return err + } + + // Replace content of sources.list with the templated content. + file, err := os.Create(filepath.Join(rootfsDir, "etc", "apt", "sources.list")) + if err != nil { + return err + } + defer file.Close() + + file.WriteString(out) + } + + return nil } func (s UbuntuHTTP) unpack(filePath, rootDir string) error {