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