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/
Добавить комментарий