Создание CloudFoundry/IBM Bluemix buildpack или веб сервис на Awk (gawk)

от автора

gawk — глазеть разинув рот, таращить глаза

Дальше никаких шуток, я действительно опишу как запустить Awk (Gawk) веб сервис на IBM Bluemix.

CloudFoundry и созданная на его основе платформа IBM Bluemix поддерживают много разных языков программирования и веб фреймворков. Все это благодаря поддержке билдпаков (мой перевод слова buildpack). Билдпак можно рассматривать как плагин, который отвечает за установку и настройку среды выполнения приложения. Создают билдпак обычно в двух случаях.

Бывает, что язык или фреймворк поддерживается, но для приложения нужны сторонние библиотеки, например OpenCV, которые невозможно поставить стандатрным для этого языка менеджером зависимостей (npm, pip, bundler). В этом случае модифицируется существующий билдпак, в который добавляется установка нужных библиотек. Большинство билдпаков лежат на github, делается форк, с помощью которого можно будет деплоить приложение.

Второй случай более редкий — язык пока не поддерживается, т.е. билдпак пока никто не создал. В этом случае придется сделать его с нуля, что и будет описано чуть ниже. Я долго искал какой язык пока не поддерживается CloudFoundry, выбор пал на Brainfuck. К сожалению, когда я дописал билдпак, я понял, что быстро написать веб сервер на этом языке у меня не получится. Поиск показал, что и у других с этой задачей возникли сложности.

Чтобы было чуть понятнее в чем проблема — билдпак настраивает среду, в которую затем помещается пользовательское приложение, ему через переменные окружения передаются порт и имя хоста, где приложение должно начать обрабатывать HTTP запросы. Т.е. простого hello world мало. Я продолжил поиски и нашел реализацию веб серверов на PostScript и Awk (точнее gawk). В итоге я выбрал Awk и начал писать новый билдпак.

Документация хорошо описывает общие концепции, также можно посмотреть готовые билдпаки. В самом простом случае необходимо создать создать папку bin и поместить в нее 3 исполнимых файла:

detect — определяет можно ли применять данный билдпак к приложению. Если да, то скрипт должен вернуть 0 и напечатать имя языка или фреймворка. В нашем случае мы проверяем наличие app.awk в корне приложения, введем такое соглашение.

#!/usr/bin/env bash # bin/detect <build-dir>  # Any awk web app must have app.awk file if [ -f $1/app.awk ]; then   echo "gawk"   exit 0 fi  exit 1  

compile должен устновить все что нужно и скомпилировать пользовательское приложение, если это требуется. В нашем случае надо загрузить и установить gawk. Чтобы экономить время во время разворачивания приложения можно было собрать его вручную под разные версии Ubuntu и выбирать подходящую на этом шаге. Но сборка gawk не такой затратный процесс, кроме того, поддерживается кэш, так что для большинства проектов компиляция будет выполняться один раз. Зато мы точно получим файл, собранный под нужную версию ОС и архитектуру.

#!/usr/bin/env bash # bin/compile <build-dir> <cache-dir>  set -e  build_dir=$1 cache_dir=$2  awk_cache=$cache_dir/gawk-4.1.3 awk_url="http://ftp.gnu.org/gnu/gawk/gawk-4.1.3.tar.gz"  if [ -f $awk_cache/gawk ]; then     echo "Using cached gawk" else     # download and compile gawk     mkdir -p $awk_cache     curl -o $cache_dir/gawk.tar.gz "$awk_url"     cd $cache_dir     tar zxvf  gawk.tar.gz      cd $awk_cache     ./configure     make fi  # copy gawk to build dir cp $awk_cache/gawk $build_dir   # set path and test gawk PATH=$build_dir:$PATH gawk -V  # create a launcher to wrap env vars passing echo "#!/usr/bin/env bash\n" > $build_dir/awk-start echo "/app/gawk -v PORT=\"\$PORT\" -v HOST=\"\$VCAP_APP_HOST\" -f \$1" >> $build_dir/awk-start chmod +x $build_dir/awk-start 

Первый аргумент — место сборки файлов (build_dir), второй — кэш. Наша задача положить нужные для запуска файлы в build_dir, в нашем случает это gawk. Кроме того, Awk скрипт не имеет доступа к переменным окружения, а нам нужно знать какой порт нам выделяет CloudFoundry для запуска (переменная окружения PORT). Поэтому я сделал небольшую обертку для удобного запуска.

release — передает метаданные, необходимые для запуска приложения. Обычно это переменные окружения и строка запуска по умолчанию. Она будет использоваться, если приложение не предоставляет этой информации, что обычно делается в файле Procfile.

#!/usr/bin/env bash # bin/release <build-dir>  cat <<EOF config_vars:     PATH: /app:$PATH default_process_types:     web: /app/awk-start app.awk EOF  

Проверяем работу скриптов локально, потом выкладываем все на github, запоминаем адрес https://github.com/hashmap/gawk-buildpack

Теперь пишем приложение. Создаем папку gawktest, в ней файл app.awk

# A Web Server in Awk # a simple, single user, web server built with gawk. # based on code form http://awk.info/?tools/server by Michael Sanders  BEGIN {    host     = "/inet/tcp/" PORT "/0/0"  # host string    status   = 200                       # 200 == OK    reason   = "OK"                      # server response    RS = ORS = "\r\n"                    # header line terminators    doc      = Setup()                   # html document    len      = length(doc) + length(ORS) # length of document    print "Staring AWK server"   while (1) {       print "HTTP/1.0", status, reason |& host       print "Connection: Close"        |& host       print "Pragma: no-cache"         |& host       print "Content-length:", len     |& host       print ORS doc                    |& host       close(host)     # close client connection       host |& getline # wait for new client request    }  }   function Setup() {    tmp = "<html>\   <head><title>Simple gawk server</title></head>\   <body>\   Hello from awk!\   </body>\   </html>"    return tmp  }  

Проверяем работу приложения локально:

 gawk -v PORT=8080 -f app.awk  

теперь можно отправлять на Bluemix, делаем стандартный cf push, но еще указываем адрес нашего билдпака:

gawktest  cf push gawktest -b https://github.com/hashmap/gawk-buildpack Updating app gawktest in org xxx@gmail.com / space dev as xxx@gmail.com... OK  Uploading gawktest... Uploading app files from: /Users/alex/projects/gawktest Uploading 32.3K, 3 files Done uploading OK  Stopping app gawktest in org xxx@gmail.com / space dev as xxx@gmail.com... OK  Starting app gawktest in org xxx@gmail.com / space dev as xxx@gmail.com... -----> Downloaded app package (8.0K) -----> Downloaded app buildpack cache (11M) Cloning into '/tmp/buildpacks/gawk-buildpack'... Using cached gawk GNU Awk 4.1.3, API: 1.1 Copyright (C) 1989, 1991-2015 Free Software Foundation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. -----> Uploading droplet (724K)  1 of 1 instances running  App started   OK  App gawktest was started using this command `/app/awk-start app.awk`  Showing health and status for app gawktest in org xxx@gmail.com / space dev as xxx@gmail.com... OK  requested state: started instances: 1/1 usage: 64M x 1 instances urls: gawktest.mybluemix.net last uploaded: Wed Jul 15 12:21:13 UTC 2015 stack: lucid64 buildpack: https://github.com/hashmap/gawk-buildpack       state     since                    cpu    memory        disk         details #0   running   2015-07-15 03:22:08 PM   0.0%   1.1M of 64M   1.9M of 1G 

Все работает и доступно, пока по крайней мере, не забывайте, что сервер однопользовательский. Т.к. это не первый запуск, то уже собранный gawk просто скопировался из кэша. При первом запуске нового приложения можно будет увидеть как он скачивается, распаковывается и собирается. Также для отладки печатается версия gawk и его лицензия.

Если кто напишет веб фреймворк на Brainfuck — дайте знать.

ссылка на оригинал статьи http://habrahabr.ru/post/262701/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *