diff --git a/.gitignore b/.gitignore index b464d1b..9ff837d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.o /libnss_docker.so.2 /test +/dockerip diff --git a/Makefile b/Makefile index a050a34..4475b2d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,9 @@ DESTDIR ?= NSSDIR ?= /usr/lib +BINDIR ?= /usr/bin + +STRIP = strip CC = gcc CFLAGS = -fPIC -Wall -Werror -ggdb `pkg-config --cflags glib-2.0` LDFLAGS = `pkg-config --libs glib-2.0` @@ -12,7 +15,7 @@ MODULE = libnss_docker.so.2 BINS = \ $(MODULE) \ - test + test dockerip $(MODULE): $(OBJS) Makefile $(CC) -fPIC -shared -o $@ -Wl,-soname,$@ $< $(LDFLAGS) @@ -20,14 +23,22 @@ $(MODULE): $(OBJS) Makefile TEST_OBJS = \ test.o +INSPECT_OBJS = \ + dockerip.o + test: $(TEST_OBJS) $(MODULE) Makefile $(CC) -o $@ $< $(LDFLAGS) +dockerip: $(INSPECT_OBJS) $(MODULE) Makefile + $(CC) -o $@ $< + $(STRIP) $@ + all: $(BINS) install: all - mkdir -p $(DESTDIR)$(NSSDIR) + mkdir -p $(DESTDIR)$(NSSDIR) $(DESTDIR)$(BINDIR) install -m 0644 $(MODULE) $(DESTDIR)$(NSSDIR)/$(MODULE) + install -g docker -m 2755 dockerip $(DESTDIR)$(BINDIR)/dockerip ldconfig clean: diff --git a/README.md b/README.md index 1ec6e60..352b576 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ This is still a work in progress! Installing ========== - git clone git@github.com:danni/docker-nss.git +Ensure `make`, `gcc`, and `libglib2.0-dev` are installed on the system. + + git clone git@github.com:weng-lab/docker-nss.git cd docker-nss sudo make all install sudo sed -i -re 's/^(hosts: .*$)/\1 docker/' /etc/nsswitch.conf diff --git a/dockerip.c b/dockerip.c new file mode 100644 index 0000000..80e4cfc --- /dev/null +++ b/dockerip.c @@ -0,0 +1,14 @@ +#include +#include +#include + +int main(int argc, char** argv) +{ + // run if one argument was supplied that does not start with '-' + if (argc == 2 && strnlen(argv[1], 255) > 2 && argv[1][0] != '-') { + const char* myargs[] = { "/usr/bin/docker", "inspect", "--format={{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}", argv[1] }; + return execlp(myargs[0], myargs[0], myargs[1], myargs[2], myargs[3], NULL); + } + printf("usage: %s \n", argv[0]); + return 1; +} diff --git a/nss.c b/nss.c index b96a267..bb02f0e 100644 --- a/nss.c +++ b/nss.c @@ -29,185 +29,144 @@ /* define a suffix that containers have */ #define SUFFIX ".docker" -#define ALIGN(a) (((a+sizeof(void*)-1)/sizeof(void*))*sizeof(void*)) - -static void -pack_hostent(struct hostent *result, - char *buffer, - size_t buflen, - const char *name, - const void *addr) +#define ALIGN(a) (((a + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*)) + +static void pack_hostent(struct hostent* result, char* buffer, size_t buflen, + const char* name, const void* addr) { - char *aliases, *r_addr, *addrlist; + char* aliases, *r_addr, *addrlist; size_t l, idx; /* we can't allocate any memory, the buffer is where we need to - * return things we want to use - * - * 1st, the hostname */ + * return things we want to use + * + * 1st, the hostname */ l = strlen(name); result->h_name = buffer; - memcpy (result->h_name, name, l); + memcpy(result->h_name, name, l); buffer[l] = '\0'; - idx = ALIGN (l+1); + idx = ALIGN(l + 1); /* 2nd, the empty aliases array */ aliases = buffer + idx; - *(char **) aliases = NULL; - idx += sizeof (char*); + *(char**)aliases = NULL; + idx += sizeof(char*); - result->h_aliases = (char **) aliases; + result->h_aliases = (char**)aliases; result->h_addrtype = AF_INET; - result->h_length = sizeof (struct in_addr); + result->h_length = sizeof(struct in_addr); /* 3rd, address */ r_addr = buffer + idx; memcpy(r_addr, addr, result->h_length); - idx += ALIGN (result->h_length); + idx += ALIGN(result->h_length); /* 4th, the addresses ptr array */ addrlist = buffer + idx; - ((char **) addrlist)[0] = r_addr; - ((char **) addrlist)[1] = NULL; + ((char**)addrlist)[0] = r_addr; + ((char**)addrlist)[1] = NULL; - result->h_addr_list = (char **) addrlist; + result->h_addr_list = (char**)addrlist; } -static gboolean -lookup_container_ip (const char *name, - struct in_addr *addr) +static gboolean lookup_container_ip(const char* name, struct in_addr* addr) { - char *stdout_s, *name_s; + char* stdout_s, *name_s; int exit_status; gboolean success = FALSE; /* remove the suffix */ - name_s = g_strdup (name); + name_s = g_strdup(name); *strrchr(name_s, '.') = '\0'; - char *argv[] = { - "docker", - "inspect", - "-format={{.NetworkSettings.IPAddress}}", - name_s, - NULL, - }; - - if (!g_spawn_sync(NULL, - argv, - NULL, - G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_SEARCH_PATH, - NULL, NULL, - &stdout_s, NULL, - &exit_status, - NULL)) - { - goto finally; - } - - if (exit_status != 0) - { + char* argv[] = { "/usr/bin/dockerip", name_s, NULL, }; + + if (!g_spawn_sync(NULL, argv, NULL, + G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_SEARCH_PATH, NULL, + NULL, &stdout_s, NULL, &exit_status, NULL)) { goto finally; - } + } - stdout_s = g_strstrip (stdout_s); - success = inet_aton (stdout_s, addr); + if (exit_status != 0) { + goto finally; + } + + stdout_s = g_strstrip(stdout_s); + success = inet_aton(stdout_s, addr); finally: - g_free (name_s); - g_free (stdout_s); + g_free(name_s); + g_free(stdout_s); return success; } -enum nss_status -_nss_docker_gethostbyname2_r (const char *name, - int af, - struct hostent *result, - char *buffer, - size_t buflen, - int *errnop, - int *h_errnop) +enum nss_status _nss_docker_gethostbyname2_r(const char* name, int af, + struct hostent* result, + char* buffer, size_t buflen, + int* errnop, int* h_errnop) { struct in_addr addr; - if (af != AF_INET) - { + if (af != AF_INET) { *errnop = EAFNOSUPPORT; *h_errnop = NO_DATA; return NSS_STATUS_UNAVAIL; - } + } - if (!g_str_has_suffix(name, SUFFIX)) - { + if (!g_str_has_suffix(name, SUFFIX)) { *errnop = ENOENT; *h_errnop = HOST_NOT_FOUND; return NSS_STATUS_NOTFOUND; - } + } - if (!lookup_container_ip (name, &addr)) - { + if (!lookup_container_ip(name, &addr)) { *errnop = ENOENT; *h_errnop = HOST_NOT_FOUND; return NSS_STATUS_NOTFOUND; - } + } pack_hostent(result, buffer, buflen, name, &addr); return NSS_STATUS_SUCCESS; } -enum nss_status -_nss_docker_gethostbyname_r (const char *name, - struct hostent *result, - char *buffer, - size_t buflen, - int *errnop, - int *h_errnop) +enum nss_status _nss_docker_gethostbyname_r(const char* name, + struct hostent* result, + char* buffer, size_t buflen, + int* errnop, int* h_errnop) { - return _nss_docker_gethostbyname2_r(name, - AF_INET, - result, - buffer, - buflen, - errnop, - h_errnop); + return _nss_docker_gethostbyname2_r(name, AF_INET, result, buffer, buflen, + errnop, h_errnop); } -enum nss_status -_nss_docker_gethostbyaddr_r (const void *addr, - socklen_t len, - int af, - struct hostent *result, - char *buffer, - size_t buflen, - int *errnop, - int *h_errnop) +enum nss_status _nss_docker_gethostbyaddr_r(const void* addr, socklen_t len, + int af, struct hostent* result, + char* buffer, size_t buflen, + int* errnop, int* h_errnop) { - if (af != AF_INET) - { + if (af != AF_INET) { *errnop = EAFNOSUPPORT; *h_errnop = NO_DATA; return NSS_STATUS_UNAVAIL; - } + } - if (len != sizeof (struct in_addr)) - { + if (len != sizeof(struct in_addr)) { *errnop = EINVAL; *h_errnop = NO_RECOVERY; return NSS_STATUS_UNAVAIL; - } + } /* FIXME: need to implement reverse lookups */ *errnop = EAFNOSUPPORT; *h_errnop = NO_DATA; return NSS_STATUS_UNAVAIL; /* - pack_hostent(result, buffer, buflen, "container.docker", addr); +pack_hostent(result, buffer, buflen, "container.docker", addr); - return NSS_STATUS_SUCCESS; - */ +return NSS_STATUS_SUCCESS; +*/ } diff --git a/test.c b/test.c index 1a62e30..2da4376 100644 --- a/test.c +++ b/test.c @@ -25,10 +25,9 @@ #define BADGER_DOCKER_IP "172.11.22.33" -static void -test_gethostbyname (void) +static void test_gethostbyname(void) { - struct hostent *results; + struct hostent* results; char buffer[INET_ADDRSTRLEN]; results = gethostbyname("badger.docker"); @@ -46,10 +45,9 @@ test_gethostbyname (void) g_assert_cmpstr(buffer, ==, BADGER_DOCKER_IP); } -static void -test_gethostbyname_not_docker (void) +static void test_gethostbyname_not_docker(void) { - struct hostent *results; + struct hostent* results; results = gethostbyname("badger"); @@ -57,10 +55,9 @@ test_gethostbyname_not_docker (void) g_assert_cmpint(h_errno, ==, HOST_NOT_FOUND); } -static void -test_gethostbyname_by_image_name (void) +static void test_gethostbyname_by_image_name(void) { - struct hostent *results; + struct hostent* results; results = gethostbyname("stoat.docker"); @@ -68,10 +65,9 @@ test_gethostbyname_by_image_name (void) g_assert_cmpint(h_errno, ==, HOST_NOT_FOUND); } -static void -test_gethostbyname_unknown_name (void) +static void test_gethostbyname_unknown_name(void) { - struct hostent *results; + struct hostent* results; results = gethostbyname("mushroom.docker"); @@ -79,10 +75,9 @@ test_gethostbyname_unknown_name (void) g_assert_cmpint(h_errno, ==, HOST_NOT_FOUND); } -static void -test_gethostbyname2 (void) +static void test_gethostbyname2(void) { - struct hostent *results; + struct hostent* results; char buffer[INET_ADDRSTRLEN]; results = gethostbyname2("badger.docker", AF_INET); @@ -100,10 +95,9 @@ test_gethostbyname2 (void) g_assert_cmpstr(buffer, ==, BADGER_DOCKER_IP); } -static void -test_gethostbyname2_inet6 (void) +static void test_gethostbyname2_inet6(void) { - struct hostent *results; + struct hostent* results; results = gethostbyname2("badger.docker", AF_INET6); @@ -112,7 +106,7 @@ test_gethostbyname2_inet6 (void) g_assert_cmpint(h_errno, ==, NO_DATA); } -# if 0 +#if 0 static void test_gethostbyaddr (void) { @@ -136,24 +130,22 @@ test_gethostbyaddr (void) inet_ntop(AF_INET, results->h_addr_list[0], buffer, INET_ADDRSTRLEN); g_assert_cmpstr(buffer, ==, "10.0.0.0"); } -# endif +#endif -int -main (int argc, - char **argv) +int main(int argc, char** argv) { - g_test_init (&argc, &argv, NULL); + g_test_init(&argc, &argv, NULL); g_test_add_func("/test/gethostbyname", test_gethostbyname); g_test_add_func("/test/gethostbyname_not_docker", - test_gethostbyname_not_docker); + test_gethostbyname_not_docker); g_test_add_func("/test/gethostbyname_by_image_name", - test_gethostbyname_by_image_name); + test_gethostbyname_by_image_name); g_test_add_func("/test/gethostbyname_unknown_name", - test_gethostbyname_unknown_name); + test_gethostbyname_unknown_name); g_test_add_func("/test/gethostbyname2", test_gethostbyname2); g_test_add_func("/test/gethostbyname2_inet6", test_gethostbyname2_inet6); // g_test_add_func("/test/gethostbyaddr", test_gethostbyaddr); - return g_test_run (); + return g_test_run(); }