Getting Started with C¶
This tutorial will teach you how to build a “Hello, World!” chute using C and the microhttpd library.
Prerequisites¶
Please make sure you have pdtools v0.12.0 or newer installed.
pip install pdtools~=0.12
Create a chute configuration¶
Use the pdtools interactive initialize command to create a paradrop.yaml file for your chute.
python -m pdtools chute initialize
Use the following values as suggested responses to the prompts. If you have a different version of pdtools installed, the prompts may be slightly different.
name: c-hello-world
description: Hello World chute for ParaDrop using C.
type: normal
The end result should be a paradrop.yaml file similar to the following.
description: Hello World chute for ParaDrop using C.
name: c-hello-world
services:
main:
source: .
type: normal
version: 1
Develop the Application¶
Create a file named hello.c
with the following code. The code
for this application comes from an example file distributed with the
microhttpd library.
/*
This file is part of libmicrohttpd
(C) 2007 Christian Grothoff (and other contributing authors)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <microhttpd.h>
#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
static int
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data, size_t *upload_data_size, void **ptr)
{
static int aptr;
const char *me = cls;
struct MHD_Response *response;
int ret;
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
{
/* do never respond on first call */
*ptr = &aptr;
return MHD_YES;
}
*ptr = NULL; /* reset when done */
response = MHD_create_response_from_buffer (strlen (me),
(void *) me, MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
}
int
main (int argc, char *const *argv)
{
struct MHD_Daemon *d;
if (argc != 2)
{
printf ("%s PORT\n", argv[0]);
return 1;
}
d = MHD_start_daemon (
MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
atoi (argv[1]),
NULL, NULL, &ahc_echo, PAGE,
MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
MHD_OPTION_END);
if (d == NULL)
return 1;
pause ();
MHD_stop_daemon (d);
return 0;
}
Create a file named Dockerfile
with the following contents.
This project demonstrates what is called a multi-stage build
(https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds).
The first stage installs development packages for compiling the
project. The second stage merely copies the compiled binary and installs
binary shared libraries that are required in order to run the program.
FROM ubuntu:16.04
COPY hello.c .
RUN apt-get update && apt-get install -y libmicrohttpd-dev
RUN gcc -o hello hello.c -lmicrohttpd
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y libmicrohttpd10
COPY --from=0 hello /usr/bin/hello
EXPOSE 8888
CMD ["hello", "8888"]
Wrap Up¶
The web server in this application listens on port 8888. We need to include that information in the paradrop.yaml file as well. Use the following command to alter the configuration file.
python -m pdtools chute enable-web-service 8888
After that, you can continue developing the chute and install it on a ParaDrop node.
python -m pdtools node --target=<node address> install-chute