[Статья изначально написана Себастьеном Гоасгуеном.]
CloStack — это клиент Clojure для Apache CloudStack. Clojure — это динамический язык программирования для виртуальной машины Java (JVM). Он скомпилирован непосредственно в байт-код JVM, но предлагает динамический и интерактивный характер интерпретируемого языка, такого как Python. Clojure является диалектом LISP и, как таковой, является в основном функциональным языком программирования.
Вы можете попробовать Clojure в своем браузере и ознакомиться с его циклом чтения eval (REPL). Чтобы начать, вы можете следовать руководству для не-LISP-программистов через этот веб-REPL.
Чтобы дать вам вкус к этому, вот как вы бы 2
и 2
:
user=> (+ 2 2) 4
И как бы вы определили функцию:
user=> (defn f [x y] #_=> (+ x y)) #'user/f user=> (f 2 3) 5
Это должно дать вам вкус функционального программирования ?
Установить Leinigen
leiningen — это инструмент для простого управления проектами Clojure. С lein
его помощью вы можете создать каркас проекта clojure, а также запустить цикл чтения eval (REPL) для проверки вашего кода.
Установить последнюю версию leiningen легко, получите скрипт и установите его на своем пути. Сделайте его исполняемым, и все готово.
В первый раз, когда вы запустите, lein repl
он сам себя усилит:
$ lein repl Downloading Leiningen to /Users/sebgoa/.lein/self-installs/leiningen-2.3.4-standalone.jar now... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 13.0M 100 13.0M 0 0 1574k 0 0:00:08 0:00:08 --:--:-- 2266k nREPL server started on port 58633 on host 127.0.0.1 REPL-y 0.3.0 Clojure 1.5.1 Docs: (doc function-name-here) (find-doc "part-of-name-here") Source: (source function-name-here) Javadoc: (javadoc java-object-or-class-here) Exit: Control+D or (exit) or (quit) Results: Stored in vars *1, *2, *3, an exception in *e user=> exit Bye for now!
Скачать CloStack
Чтобы установить CloStack, клонируйте репозиторий github и запустите lein repl
:
git clone https://github.com/pyr/clostack.git $ lein repl Retrieving codox/codox/0.6.4/codox-0.6.4.pom from clojars Retrieving codox/codox.leiningen/0.6.4/codox.leiningen-0.6.4.pom from clojars Retrieving leinjacker/leinjacker/0.4.1/leinjacker-0.4.1.pom from clojars Retrieving org/clojure/core.contracts/0.0.1/core.contracts-0.0.1.pom from central Retrieving org/clojure/core.unify/0.5.3/core.unify-0.5.3.pom from central Retrieving org/clojure/clojure/1.4.0/clojure-1.4.0.pom from central Retrieving org/clojure/core.contracts/0.0.1/core.contracts-0.0.1.jar from central Retrieving org/clojure/core.unify/0.5.3/core.unify-0.5.3.jar from central Retrieving org/clojure/clojure/1.4.0/clojure-1.4.0.jar from central Retrieving codox/codox/0.6.4/codox-0.6.4.jar from clojars Retrieving codox/codox.leiningen/0.6.4/codox.leiningen-0.6.4.jar from clojars Retrieving leinjacker/leinjacker/0.4.1/leinjacker-0.4.1.jar from clojars Retrieving org/clojure/clojure/1.3.0/clojure-1.3.0.pom from central Retrieving org/clojure/data.json/0.2.2/data.json-0.2.2.pom from central Retrieving http/async/client/http.async.client/0.5.2/http.async.client-0.5.2.pom from clojars Retrieving com/ning/async-http-client/1.7.10/async-http-client-1.7.10.pom from central Retrieving io/netty/netty/3.4.4.Final/netty-3.4.4.Final.pom from central Retrieving org/clojure/data.json/0.2.2/data.json-0.2.2.jar from central Retrieving com/ning/async-http-client/1.7.10/async-http-client-1.7.10.jar from central Retrieving io/netty/netty/3.4.4.Final/netty-3.4.4.Final.jar from central Retrieving http/async/client/http.async.client/0.5.2/http.async.client-0.5.2.jar from clojars nREPL server started on port 58655 on host 127.0.0.1 REPL-y 0.3.0 Clojure 1.5.1 Docs: (doc function-name-here) (find-doc "part-of-name-here") Source: (source function-name-here) Javadoc: (javadoc java-object-or-class-here) Exit: Control+D or (exit) or (quit) Results: Stored in vars *1, *2, *3, an exception in *e user=> exit
При первом запуске файла REPL будут загружены все зависимости clostack
.
Подготовьте переменные среды и сделайте ваш первый clostack
звонок
Экспортируйте несколько переменных среды, чтобы определить облако, которое вы будете использовать, а именно:
export CLOUDSTACK_ENDPOINT=http://localhost:8080/client/api export CLOUDSTACK_API_KEY=HGWEFHWERH8978yg98ysdfghsdfgsagf export CLOUDSTACK_API_SECRET=fhdsfhdf869guh3guwghseruig
Затем перезапустите REPL
$lein repl nREPL server started on port 59890 on host 127.0.0.1 REPL-y 0.3.0 Clojure 1.5.1 Docs: (doc function-name-here) (find-doc "part-of-name-here") Source: (source function-name-here) Javadoc: (javadoc java-object-or-class-here) Exit: Control+D or (exit) or (quit) Results: Stored in vars *1, *2, *3, an exception in *e user=> (use 'clostack.client) SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. nil
Вы можете безопасно отказаться от предупреждающего сообщения, которое указывает только на то, что «clostack» предназначен для использования в качестве библиотеки в проекте clojure.
Определите клиента для вашей конечной точки CloudStack
user=> (def cs (http-client)) #'user/cs
И вызывать API так:
user=> (list-zones cs) {:listzonesresponse {:count 1, :zone [{:id "1128bd56-b4d9-4ac6-a7b9-c715b187ce11", :name "CH-GV2", :networktype "Basic", :securitygroupsenabled true, :allocationstate "Enabled", :zonetoken "ccb0a60c-79c8-3230-ab8b-8bdbe8c45bb7", :dhcpprovider "VirtualRouter", :localstorageenabled true}]}}
Чтобы изучить вызовы API, которые вы можете сделать, откройте вкладку «Функции REPL». Введите list
или de
и нажмите клавишу табуляции, которую вы должны увидеть:
user=> (list list list* list-accounts list-async-jobs list-capabilities list-disk-offerings list-event-types list-events list-firewall-rules list-hypervisors list-instance-groups list-ip-forwarding-rules list-iso-permissions list-isos list-lb-stickiness-policies list-load-balancer-rule-instances list-load-balancer-rules list-network-ac-ls list-network-offerings list-networks list-os-categories list-os-types list-port-forwarding-rules list-private-gateways list-project-accounts list-project-invitations list-projects list-public-ip-addresses list-remote-access-vpns list-resource-limits list-security-groups list-service-offerings list-snapshot-policies list-snapshots list-ssh-key-pairs list-static-routes list-tags list-template-permissions list-templates list-virtual-machines list-volumes list-vp-cs list-vpc-offerings list-vpn-connections list-vpn-customer-gateways list-vpn-gateways list-vpn-users list-zones list? user=> (de dec dec' decimal? declare def default-data-readers definline definterface defmacro defmethod defmulti defn defn- defonce defprotocol defrecord defreq defstruct deftype delay delay? delete-account-from-project delete-firewall-rule delete-instance-group delete-ip-forwarding-rule delete-iso delete-lb-stickiness-policy delete-load-balancer-rule delete-network delete-network-acl delete-port-forwarding-rule delete-project delete-project-invitation delete-remote-access-vpn delete-security-group delete-snapshot delete-snapshot-policies delete-ssh-key-pair delete-static-route delete-tags delete-template delete-volume delete-vpc delete-vpn-connection delete-vpn-customer-gateway delete-vpn-gateway deliver denominator deploy-virtual-machine deref derive descendants destroy-virtual-machine destructure detach-iso detach-volume
Чтобы передать аргументы вызову, используйте синтаксис:
user=> (list-templates cs :templatefilter "executable")
Запустите виртуальную машину
Чтобы развернуть виртуальную машину, вам нужно получить serviceofferingid
тип экземпляра или, templateid
также известный как идентификатор изображения и zoneid
, вызов очень похож на CloudMonkey и возвращаетjobid
user=> (deploy-virtual-machine cs :serviceofferingid "71004023-bb72-4a97-b1e9-bc66dfce9470" :templateid "1d961c82-7c8c-4b84-b61b-601876dab8d0" :zoneid "1128bd56-b4d9-4ac6-a7b9-c715b187ce11") {:deployvirtualmachineresponse {:id "d0a887d2-e20b-4b25-98b3-c2995e4e428a", :jobid "21d20b5c-ea6e-4881-b0b2-0c2f9f1fb6be"}}
Вы можете передать дополнительные параметры для deploy-virtual-machine
вызова, такие как keypair
и securitygroupname
:
user=> (deploy-virtual-machine cs :serviceofferingid "71004023-bb72-4a97-b1e9-bc66dfce9470" :templateid "1d961c82-7c8c-4b84-b61b-601876dab8d0" :zoneid "1128bd56-b4d9-4ac6-a7b9-c715b187ce11" :keypair "exoscale") {:deployvirtualmachineresponse {:id "b5fdc41f-e151-43e7-a036-4d87b8536408", :jobid "418026fc-1009-4e7a-9721-7c9ad47b49e4"}}
Чтобы запросить асинхронное задание, вы можете использовать query-async-job
вызов API:
user=> (query-async-job-result cs :jobid "418026fc-1009-4e7a-9721-7c9ad47b49e4") {:queryasyncjobresultresponse {:jobid "418026fc-1009-4e7a-9721-7c9ad47b49e4", :jobprocstatus 0, :jobinstancetype "VirtualMachine", :accountid "b8c0baab-18a1-44c0-ab67-e24049212925", :jobinstanceid "b5fdc41f-e151-43e7-a036-4d87b8536408", :created "2013-12-16T12:25:21+0100", :jobstatus 0, :jobresultcode 0, :cmd "com.cloud.api.commands.DeployVMCmd", :userid "968f6b4e-b382-4802-afea-dd731d4cf9b9"}}
И , наконец , уничтожить виртуальную машину вы бы передать id
ВМ на destroy-virtual-machine
вызов , как так:
user=> (destroy-virtual-machine cs :id "d0a887d2-e20b-4b25-98b3-c2995e4e428a") {:destroyvirtualmachineresponse {:jobid "8fc8a8cf-9b54-435c-945d-e3ea2f183935"}}
С этими простыми основами вы можете продолжить изучение clostack
и CloudStack API.
Используйте CloStack
в своем собственном проекте clojure
Привет, мир в ближайшем будущем
Чтобы написать свой собственный проект clojure, который делает пользователя clostack
, используйте leiningen
для создания скелета проекта
lein new toto
Lein
автоматически создаст src/toto/core.clj
файл, отредактируйте его, чтобы заменить функцию foo
на -main
. Эта фиктивная функция возвращает Hellow World !
. Давайте попробуем выполнить это. Сначала нам нужно определить main
пространство имен в project.clj
файле. Отредактируйте это так:
defproject toto «0.1.0-SNAPSHOT»: описание «FIXME: написать описание»: url «http://example.com/FIXME»: license {: name «Eclipse Public License»: url «http: //www.eclipse .org / legal / epl-v10.html «}: main toto.core: зависимости [[org.clojure / clojure» 1.5.1 «]])
Обратите внимание :main toto.core
Теперь вы можете выполнить код с lein run john
. Действительно, если вы проверите в -main
функции, src/toto/core.clj
вы увидите, что она принимает аргумент. Удивительно, но вы должны увидеть следующий вывод:
$ lein run john john Hello, World!
Давайте теперь добавим зависимость CloStack и изменим main
функцию, чтобы она возвращала зону облака CloudStack.
Добавление зависимости Clostack
Отредактируйте, project.clj
чтобы добавить зависимость clostack
и несколько пакетов журналов:
:dependencies [[org.clojure/clojure "1.5.1"] [clostack "0.1.3"] [org.clojure/tools.logging "0.2.6"] [org.slf4j/slf4j-log4j12 "1.6.4"] [log4j/apache-log4j-extras "1.0"] [log4j/log4j "1.2.16" :exclusions [javax.mail/mail javax.jms/jms com.sun.jdkmk/jmxtools com.sun.jmx/jmxri]]])
lein
должен был создать resources
каталог. В нем создайте log4j.properties
файл примерно так:
$ more log4j.properties # Root logger option log4j.rootLogger=INFO, stdout # Direct log messages to stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
Обсуждение ведения журнала выходит за рамки этих рецептов, мы просто добавим его в конфигурацию для полного примера.
Теперь вы можете редактировать код src/toto/core.clj
с некоторыми основными вызовами.
(ns testclostack.core (:require [clostack.client :refer [http-client list-zones]])) (defn foo "I don't do a whole lot." [x] (println x "Hello, World!")) (def cs (http-client)) (defn -main [args] (println (list-zones cs)) (println args "Hey Wassup") (foo args) )
Просто запустите этот код clojure lein run joe
в исходном коде вашего проекта. И все, вы успешно открыли основы Clojure и использовали клиент CloudStack clostack
для написания своего первого кода Clojure. Теперь для чего-то более значительного, посмотрите на поддон