[lxc-devel] [lxd/master] file: Implement retrieving symlinks
stgraber on Github
lxc-bot at linuxcontainers.org
Thu Feb 8 23:35:20 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 371 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180208/2cc326a8/attachment.bin>
-------------- next part --------------
From cba0580e4733814478a41b4fdb67bcc0539dca1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at 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 <stgraber at 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",
}
More information about the lxc-devel
mailing list