[lxc-devel] [distrobuilder/master] Improve /etc/hosts generator

stgraber on Github lxc-bot at linuxcontainers.org
Tue Mar 13 16:51:57 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 362 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180313/230b1009/attachment.bin>
-------------- next part --------------
From b233e6a315b064de23354846efd578886592a37d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 13 Mar 2018 12:22:36 -0400
Subject: [PATCH] Improve /etc/hosts generator
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 distrobuilder/main.go       |  8 ++++++-
 generators/hostname.go      | 13 ++++++++++++
 generators/hostname_test.go |  2 ++
 generators/hosts.go         | 52 ++++++++++++++++++++++++++++++++-------------
 generators/hosts_test.go    |  8 +++----
 5 files changed, 63 insertions(+), 20 deletions(-)

diff --git a/distrobuilder/main.go b/distrobuilder/main.go
index f623027..cae2fa8 100644
--- a/distrobuilder/main.go
+++ b/distrobuilder/main.go
@@ -20,11 +20,17 @@ __attribute__((constructor)) void init(void) {
 	}
 
 	// Unshare a new mntns so our mounts don't leak
-	if (unshare(CLONE_NEWNS | CLONE_NEWPID) < 0) {
+	if (unshare(CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWUTS) < 0) {
 		fprintf(stderr, "Failed to unshare namespaces: %s\n", strerror(errno));
 		_exit(1);
 	}
 
+	// Hardcode the hostname to "distrobuilder"
+	if (sethostname("distrobuilder", 13) < 0) {
+		fprintf(stderr, "Failed to set hostname: %s\n", strerror(errno));
+		_exit(1);
+	}
+
 	// Prevent mount propagation back to initial namespace
 	if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL) < 0) {
 		fprintf(stderr, "Failed to mark / private: %s\n", strerror(errno));
diff --git a/generators/hostname.go b/generators/hostname.go
index a227532..9ec4949 100644
--- a/generators/hostname.go
+++ b/generators/hostname.go
@@ -5,6 +5,7 @@ import (
 	"os"
 	"path/filepath"
 
+	lxd "github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 
 	"github.com/lxc/distrobuilder/image"
@@ -17,6 +18,12 @@ type HostnameGenerator struct{}
 // RunLXC creates a hostname template.
 func (g HostnameGenerator) RunLXC(cacheDir, sourceDir string, img *image.LXCImage,
 	defFile shared.DefinitionFile) error {
+
+	// Skip if the file doesn't exist
+	if !lxd.PathExists(filepath.Join(sourceDir, defFile.Path)) {
+		return nil
+	}
+
 	// Store original file
 	err := StoreFile(cacheDir, sourceDir, defFile.Path)
 	if err != nil {
@@ -43,6 +50,12 @@ func (g HostnameGenerator) RunLXC(cacheDir, sourceDir string, img *image.LXCImag
 // RunLXD creates a hostname template.
 func (g HostnameGenerator) RunLXD(cacheDir, sourceDir string, img *image.LXDImage,
 	defFile shared.DefinitionFile) error {
+
+	// Skip if the file doesn't exist
+	if !lxd.PathExists(filepath.Join(sourceDir, defFile.Path)) {
+		return nil
+	}
+
 	templateDir := filepath.Join(cacheDir, "templates")
 
 	err := os.MkdirAll(templateDir, 0755)
diff --git a/generators/hostname_test.go b/generators/hostname_test.go
index 446ae36..fc59c66 100644
--- a/generators/hostname_test.go
+++ b/generators/hostname_test.go
@@ -76,6 +76,8 @@ func TestHostnameGeneratorRunLXD(t *testing.T) {
 		t.Fatalf("Unexpected error: %s", err)
 	}
 
+	createTestFile(t, filepath.Join(cacheDir, "rootfs", "etc", "hostname"), "hostname")
+
 	err = generator.RunLXD(cacheDir, rootfsDir, image,
 		shared.DefinitionFile{Path: "/etc/hostname"})
 	if err != nil {
diff --git a/generators/hosts.go b/generators/hosts.go
index 3cdc4c7..7d5d26e 100644
--- a/generators/hosts.go
+++ b/generators/hosts.go
@@ -1,12 +1,14 @@
 package generators
 
 import (
-	"io"
+	"io/ioutil"
 	"os"
 	"path/filepath"
+	"strings"
 
 	"github.com/lxc/distrobuilder/image"
 	"github.com/lxc/distrobuilder/shared"
+	lxd "github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 )
 
@@ -16,21 +18,37 @@ type HostsGenerator struct{}
 // RunLXC creates a LXC specific entry in the hosts file.
 func (g HostsGenerator) RunLXC(cacheDir, sourceDir string, img *image.LXCImage,
 	defFile shared.DefinitionFile) error {
+
+	// Skip if the file doesn't exist
+	if !lxd.PathExists(filepath.Join(sourceDir, defFile.Path)) {
+		return nil
+	}
+
 	// Store original file
 	err := StoreFile(cacheDir, sourceDir, defFile.Path)
 	if err != nil {
 		return err
 	}
 
-	file, err := os.OpenFile(filepath.Join(sourceDir, defFile.Path),
-		os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+	// Read the current content
+	content, err := ioutil.ReadFile(filepath.Join(sourceDir, defFile.Path))
 	if err != nil {
 		return err
 	}
-	defer file.Close()
 
-	// Append hosts entry
-	file.WriteString("127.0.0.1\tLXC_NAME\n")
+	// Replace hostname with placeholder
+	content = []byte(strings.Replace(string(content), "distrobuilder", "LXC_NAME", -1))
+
+	// Add a new line if needed
+	if !strings.Contains(string(content), "LXC_NAME") {
+		content = append([]byte("127.0.1.1\tLXC_NAME\n"), content...)
+	}
+
+	// Overwrite the file
+	err = ioutil.WriteFile(filepath.Join(sourceDir, defFile.Path), content, 0644)
+	if err != nil {
+		return err
+	}
 
 	// Add hostname path to LXC's templates file
 	return img.AddTemplate(defFile.Path)
@@ -39,6 +57,12 @@ func (g HostsGenerator) RunLXC(cacheDir, sourceDir string, img *image.LXCImage,
 // RunLXD creates a hosts template.
 func (g HostsGenerator) RunLXD(cacheDir, sourceDir string, img *image.LXDImage,
 	defFile shared.DefinitionFile) error {
+
+	// Skip if the file doesn't exist
+	if !lxd.PathExists(filepath.Join(sourceDir, defFile.Path)) {
+		return nil
+	}
+
 	templateDir := filepath.Join(cacheDir, "templates")
 
 	// Create templates path
@@ -47,22 +71,20 @@ func (g HostsGenerator) RunLXD(cacheDir, sourceDir string, img *image.LXDImage,
 		return err
 	}
 
-	// Create hosts template
-	file, err := os.Create(filepath.Join(templateDir, "hosts.tpl"))
+	// Read the current content
+	content, err := ioutil.ReadFile(filepath.Join(sourceDir, defFile.Path))
 	if err != nil {
 		return err
 	}
-	defer file.Close()
 
-	hostsFile, err := os.Open(filepath.Join(sourceDir, defFile.Path))
+	// Replace hostname with placeholder
+	content = []byte(strings.Replace(string(content), "distrobuilder", "{{ container.name }}", -1))
+
+	// Write the template
+	err = ioutil.WriteFile(filepath.Join(templateDir, "hosts.tpl"), content, 0644)
 	if err != nil {
 		return err
 	}
-	defer hostsFile.Close()
-
-	// Copy old content, and append LXD specific entry
-	io.Copy(file, hostsFile)
-	file.WriteString("127.0.0.1\t{{ container.name }}\n")
 
 	img.Metadata.Templates[defFile.Path] = &api.ImageMetadataTemplate{
 		Template: "hosts.tpl",
diff --git a/generators/hosts_test.go b/generators/hosts_test.go
index 318243f..e848be3 100644
--- a/generators/hosts_test.go
+++ b/generators/hosts_test.go
@@ -34,7 +34,7 @@ func TestHostsGeneratorRunLXC(t *testing.T) {
 	}
 
 	createTestFile(t, filepath.Join(cacheDir, "rootfs", "etc", "hosts"),
-		"127.0.0.1\tlocalhost\n")
+		"127.0.0.1\tlocalhost\n127.0.0.1\tdistrobuilder\n")
 
 	err = generator.RunLXC(cacheDir, rootfsDir, image,
 		shared.DefinitionFile{Path: "/etc/hosts"})
@@ -43,7 +43,7 @@ func TestHostsGeneratorRunLXC(t *testing.T) {
 	}
 
 	validateTestFile(t, filepath.Join(cacheDir, "tmp", "etc", "hosts"),
-		"127.0.0.1\tlocalhost\n")
+		"127.0.0.1\tlocalhost\n127.0.0.1\tdistrobuilder\n")
 	validateTestFile(t, filepath.Join(cacheDir, "rootfs", "etc", "hosts"),
 		"127.0.0.1\tlocalhost\n127.0.0.1\tLXC_NAME\n")
 
@@ -53,7 +53,7 @@ func TestHostsGeneratorRunLXC(t *testing.T) {
 	}
 
 	validateTestFile(t, filepath.Join(cacheDir, "rootfs", "etc", "hosts"),
-		"127.0.0.1\tlocalhost\n")
+		"127.0.0.1\tlocalhost\n127.0.0.1\tdistrobuilder\n")
 }
 
 func TestHostsGeneratorRunLXD(t *testing.T) {
@@ -81,7 +81,7 @@ func TestHostsGeneratorRunLXD(t *testing.T) {
 	}
 
 	createTestFile(t, filepath.Join(cacheDir, "rootfs", "etc", "hosts"),
-		"127.0.0.1\tlocalhost\n")
+		"127.0.0.1\tlocalhost\n127.0.0.1\tdistrobuilder\n")
 
 	err = generator.RunLXD(cacheDir, rootfsDir, image,
 		shared.DefinitionFile{Path: "/etc/hosts"})


More information about the lxc-devel mailing list