]>
Commit | Line | Data |
---|---|---|
e143e9d8 DM |
1 | ==================================== |
2 | Setup PVE v2 Development Environment | |
3 | ==================================== | |
4 | ||
5 | 1. Install Debian 'squeeze' | |
6 | 2. Install prerequisites for development environment: | |
7 | ||
8 | apt-get -y install build-essential subversion debhelper autotools-dev \ | |
9 | doxygen check pkg-config libnss3-dev groff quilt dpatch libxml2-dev \ | |
10 | libncurses5-dev libslang2-dev libldap2-dev xsltproc python-pexpect \ | |
11 | python-pycurl libdbus-1-dev openipmi sg3-utils libnet-snmp-perl \ | |
12 | libnet-telnet-perl snmp python-openssl libxml2-utils automake autoconf \ | |
13 | libsqlite3-dev sqlite3 libfuse-dev libglib2.0-dev librrd-dev \ | |
14 | librrds-perl rrdcached lintian libdevel-cycle-perl libjson-perl \ | |
15 | liblinux-inotify2-perl libio-stringy-perl unzip fuse-utils \ | |
16 | libcrypt-openssl-random-perl libcrypt-openssl-rsa-perl \ | |
17 | libauthen-pam-perl libterm-readline-gnu-perl libssl-dev open-iscsi \ | |
18 | libapache2-mod-perl2 libfilesys-df-perl libfile-readbackwards-perl \ | |
19 | libpci-dev texi2html libgnutls-dev libsdl1.2-dev bridge-utils \ | |
20 | libvncserver0 rpm2cpio apache2-mpm-prefork libintl-perl \ | |
21 | libapache2-request-perl libnet-dns-perl vlan libio-socket-ssl-perl \ | |
22 | libfile-sync-perl ifenslave-2.6 libnet-ldap-perl console-data | |
23 | ||
24 | 3. Download and install the following svn modules in order from top to bottom: | |
25 | ||
26 | svn://devel.proxmox.com/var/svn/pve/ | |
27 | ||
28 | libqb/trunk | |
29 | corosync/trunk | |
30 | openais/trunk | |
31 | pve-common/trunk | |
32 | pve-cluster/trunk | |
33 | redhat-cluster/trunk | |
34 | pve-access-control/trunk | |
35 | pve-storage/pve2 | |
36 | pve-qemu-kvm/pve2 | |
37 | qemu-server/pve2 | |
38 | vncterm/pve2 | |
39 | pve-manager/pve2 | |
40 | pve-kernel-2.6.32-rh/pve2 | |
41 | ||
42 | Most source can be installed with 'make dinstall' command. | |
43 | ||
44 | 4. Reboot the system. | |
45 | 5. Learn to use the quilt patch scripts. | |
46 | 6. Happy coding. | |
47 | ||
48 | There is an experimental package containing the API documentation | |
49 | as ExtJS application: | |
50 | ||
51 | pve2-api-doc/trunk | |
52 | ||
53 | ||
54 | REST vs. SOAP | |
55 | ============= | |
56 | ||
57 | We decided to change our SOAP API (1.X) and use a REST like API. The | |
58 | concept is described in [1] (Resource Oriented Architecture | |
59 | (ROA)). The main advantage is that we are able to remove a lot of code | |
60 | (the whole SOAP stack) to reduce software complexity. | |
61 | ||
62 | We also moved away from server side content generation. Instead we use | |
63 | the ExtJS Rich Internet Application Framework | |
64 | (http://www.sencha.com). | |
65 | ||
66 | That framework, like any other AJAX toolkit, can talk directly to the | |
67 | REST API using JSON. So we were able to remove the server side | |
68 | template toolkit completely. | |
69 | ||
70 | JSON and JSON Schema | |
71 | ==================== | |
72 | ||
73 | We use JSON as data format, because it is simple and parse-able by any | |
74 | web browser. | |
75 | ||
76 | Additionally, we use JSON Schema [2] to formally describe our API. So | |
77 | we can automatically generate the whole API Documentation, and we can | |
78 | verify all parameters and return values. | |
79 | ||
80 | An great side effect was that we are able to use JSON Schema to | |
81 | produce command line argument parsers automatically. In fact, the REST | |
82 | API and the command line tools use the same code. | |
83 | ||
84 | Object linkage is done using the JSON Hyper Schema (links property). | |
85 | ||
86 | A small utility called 'pvesh' exposes the whole REST API on the command | |
87 | line. | |
88 | ||
89 | So here is a summary of the advantage: | |
90 | ||
91 | - easy, human readable data format (native web browser format) | |
92 | - automatic parameter verification (we can also verify return values) | |
93 | - automatic generation of API documentation | |
94 | - easy way to create command line tools (using same API). | |
95 | ||
96 | API Implementation (PVE::RESTHandler) | |
97 | ===================================== | |
98 | ||
99 | All classes exposing methods on the API use PVE::RESTHandler as base class. | |
100 | ||
101 | use base qw(PVE::RESTHandler); | |
102 | ||
103 | To expose methods, one needs to call register_method(): | |
104 | ||
105 | __PACKAGE__->register_method ($schema); | |
106 | ||
107 | Where $schema is a PVE method schema as described in | |
108 | PVE::JSONSchema. It includes a description of parameters and return | |
109 | values, and a reference to the actual code | |
110 | ||
111 | __PACKAGE__->register_method ({ | |
112 | name => 'echo', | |
113 | path => 'echo', | |
114 | method => 'GET', | |
115 | description => "simple return value of parameter 'text'", | |
116 | parameters => { | |
117 | additionalProperties => 0, | |
118 | properties => { | |
119 | text => { | |
120 | type => 'string', | |
121 | } | |
122 | }, | |
123 | }, | |
124 | returns => { | |
125 | type => 'string', | |
126 | }, | |
127 | code => sub { | |
128 | my ($conn, $resp, $param) = @_; | |
129 | ||
130 | return $param->{text}; | |
131 | } | |
132 | }); | |
133 | ||
134 | The 'name' property is only used if you want to call the method | |
135 | directly from Perl. You can do that using: | |
136 | ||
137 | print __PACKAGE__->echo({ text => "a test" }); | |
138 | ||
139 | We use Perl's AUTOLOAD feature to implement this. Note: You need to | |
140 | pass parameters a HASH reference. | |
141 | ||
142 | There is a special helper method called cli_handler(). This is used by | |
143 | the CLIHandler Class for command line tools, where you want to pass | |
144 | arguments as array of strings. This uses Getopt::Long to parse parameters. | |
145 | ||
146 | There is a second way to map names to methods - using the 'path' | |
147 | property. And you can register subclasses. That way you can set up a | |
148 | filesystem like hierarchy to access methods. | |
149 | ||
150 | Here is an example: | |
151 | ---------------------------- | |
152 | package C1; | |
153 | ||
154 | __PACKAGE__->register_method ({ | |
155 | subclass => "C2", | |
156 | path => 'sub2', | |
157 | }); | |
158 | ||
159 | ||
160 | __PACKAGE__->register_method ({ | |
161 | name => 'list1', | |
162 | path => 'index', | |
163 | method => 'GET', | |
164 | ... | |
165 | }); | |
166 | ||
167 | package C2; | |
168 | ||
169 | __PACKAGE__->register_method ({ | |
170 | name => 'list2', | |
171 | path => 'index', | |
172 | method => 'GET', | |
173 | ... | |
174 | }); | |
175 | ------------------------------- | |
176 | ||
177 | The utily method find_handler (in PVE::RESTHandler) can be use to do | |
178 | 'path' related method lookups. | |
179 | ||
180 | C1->find_handler('GET', "/index") => C1::list1 | |
181 | C1->find_handler('GET', "/sub2/index") => C2::list2 | |
182 | ||
183 | The HTTP server use the URL (a path) to find the corresponding method. | |
184 | ||
185 | ||
186 | References | |
187 | ========== | |
188 | [1] RESTful Web Services | |
189 | Web services for the real world | |
190 | ||
191 | By | |
192 | Leonard Richardson, Sam Ruby | |
193 | Publisher: | |
194 | O'Reilly Media | |
195 | Released: | |
196 | May 2007 | |
197 | ||
198 | [2] JSON Schema links: http://json-schema.org/ |