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

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) ===
Closes: #4227

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
From cba0580e4733814478a41b4fdb67bcc0539dca1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com>
Date: Thu, 8 Feb 2018 18:24:04 -0500
Subject: [PATCH] file: Implement retrieving symlinks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes: #4227

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 doc/api-extensions.md |  3 +++
 lxc/file.go           | 24 ++++++++++++++++++++++++
 lxd/container_file.go |  2 +-
 lxd/main_nsexec.go    | 19 +++++++++++++++++--
 shared/version/api.go |  1 +
 5 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 1ba3db34d..2091cc7f3 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -395,3 +395,6 @@ getting a stream of events over websocket.
 ## proxy
 This adds a new `proxy` device type to containers, allowing forwarding
 of connections between the host and container.
+
+## file\_get\_symlink
+This makes it possible to retrieve symlinks using the file API.
diff --git a/lxc/file.go b/lxc/file.go
index d0b5cb127..600a8ada7 100644
--- a/lxc/file.go
+++ b/lxc/file.go
@@ -110,6 +110,16 @@ func (c *fileCmd) recursivePullFile(d lxd.ContainerServer, 
container string, p s
                if err != nil {
                        return err
                }
+       } else if resp.Type == "symlink" {
+               linkTarget, err := ioutil.ReadAll(buf)
+               if err != nil {
+                       return err
+               }
+
+               err = os.Symlink(strings.TrimSpace(string(linkTarget)), target)
+               if err != nil {
+                       return err
+               }
        } else {
                return fmt.Errorf(i18n.G("Unknown file type '%s'"), resp.Type)
        }
@@ -504,6 +514,20 @@ func (c *fileCmd) pull(conf *config.Config, args []string) 
error {
                if targetPath == "-" {
                        f = os.Stdout
                } else {
+                       if resp.Type == "symlink" {
+                               linkTarget, err := ioutil.ReadAll(buf)
+                               if err != nil {
+                                       return err
+                               }
+
+                               err = 
os.Symlink(strings.TrimSpace(string(linkTarget)), targetPath)
+                               if err != nil {
+                                       return err
+                               }
+
+                               continue
+                       }
+
                        f, err = os.Create(targetPath)
                        if err != nil {
                                return err
diff --git a/lxd/container_file.go b/lxd/container_file.go
index a7f6974a8..0ac112449 100644
--- a/lxd/container_file.go
+++ b/lxd/container_file.go
@@ -65,7 +65,7 @@ func containerFileGet(c container, path string, r 
*http.Request) Response {
                "X-LXD-type": type_,
        }
 
-       if type_ == "file" {
+       if type_ == "file" || type_ == "symlink" {
                // Make a file response struct
                files := make([]fileResponseEntry, 1)
                files[0].identifier = filepath.Base(path)
diff --git a/lxd/main_nsexec.go b/lxd/main_nsexec.go
index 65dcfd7b3..1af0a37c8 100644
--- a/lxd/main_nsexec.go
+++ b/lxd/main_nsexec.go
@@ -188,6 +188,7 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, 
char *container, bool is
        int exists = 1;
        bool is_dir_manip = type != NULL && !strcmp(type, "directory");
        bool is_symlink_manip = type != NULL && !strcmp(type, "symlink");
+       char link_target[PATH_MAX];
 
        if (!is_dir_manip && !is_symlink_manip) {
                host_fd = open(host, O_RDWR);
@@ -268,7 +269,7 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, 
char *container, bool is
                return 0;
        }
 
-       if (stat(container, &st) < 0)
+       if (fstatat(AT_FDCWD, container, &st, AT_SYMLINK_NOFOLLOW) < 0)
                exists = 0;
 
        container_open_flags = O_RDWR;
@@ -283,6 +284,21 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, 
char *container, bool is
        if (exists && S_ISDIR(st.st_mode))
                container_open_flags = O_DIRECTORY;
 
+       if (!is_put && exists && S_ISLNK(st.st_mode)) {
+               fprintf(stderr, "uid: %ld\n", (long)st.st_uid);
+               fprintf(stderr, "gid: %ld\n", (long)st.st_gid);
+               fprintf(stderr, "mode: %ld\n", (unsigned long)st.st_mode & 
(S_IRWXU | S_IRWXG | S_IRWXO));
+               fprintf(stderr, "type: symlink\n");
+
+               if (readlink(container, link_target, PATH_MAX) < 0) {
+                       error("error: readlink");
+                       goto close_host;
+               }
+
+               dprintf(host_fd, "%s\n", link_target);
+               goto close_container;
+       }
+
        umask(0);
        container_fd = open(container, container_open_flags, 0);
        if (container_fd < 0) {
@@ -321,7 +337,6 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, 
char *container, bool is
                }
                ret = 0;
        } else {
-
                if (fstat(container_fd, &st) < 0) {
                        error("error: stat");
                        goto close_container;
diff --git a/shared/version/api.go b/shared/version/api.go
index feb31aab8..f31b714fc 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -87,4 +87,5 @@ var APIExtensions = []string{
        "maas_network",
        "devlxd_events",
        "proxy",
+       "file_get_symlink",
 }
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to