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