]>
Commit | Line | Data |
---|---|---|
a4a9a328 | 1 | = Setup PVE Development Environment = |
e143e9d8 | 2 | |
bb9d3865 | 3 | 0. Read https://pve.proxmox.com/wiki/Developer_Documentation |
2c2b3b55 TL |
4 | 1. Install Debian 9 'stretch' (you can also start from a PVE installation and |
5 | skip step 2 - 5, 7 - 11) | |
bb9d3865 MB |
6 | 2. Configure the network interface(s) |
7 | 3. Change the IP address of your hostname for proper name resolution | |
8 | in /etc/hosts | |
9 | Using 127.0.1.1 will not work, so change it to an IP address from your | |
10 | local network! | |
a4a9a328 | 11 | |
bb9d3865 MB |
12 | 4: Check that the Debian repositories are set properly. |
13 | See https://wiki.debian.org/SourcesList for more information. | |
a4a9a328 | 14 | |
bb9d3865 | 15 | 5. Optional: Install openssh-server and connect via ssh to the host. |
a4a9a328 | 16 | |
bb9d3865 MB |
17 | run: apt-get update && apt-get install openssh-server |
18 | Connect via ssh to host and switch user to root | |
a4a9a328 | 19 | |
bb9d3865 | 20 | 6. Configure 'pvetest' repository in /etc/apt/sources.list.d/: |
8bc53243 | 21 | |
bb9d3865 MB |
22 | run: echo "deb http://download.proxmox.com/debian stretch pvetest" > /etc/apt/sources.list.d/pve-development.list |
23 | ||
24 | 7. Add the repository key: | |
25 | ||
26 | run: wget -O- "http://download.proxmox.com/debian/proxmox-ve-release-5.x.gpg" | apt-key add - | |
27 | ||
28 | 8. run: apt-get update && apt-get dist-upgrade | |
29 | 9. run: apt-get install proxmox-ve | |
30 | 10. run: mv /etc/apt/sources.list.d/pve-enterprise.list /etc/apt/sources.list.d/pve-enterprise.list.bak | |
31 | ||
32 | 11. You should now have a working Proxmox VE installation. | |
33 | Open a browser: https://<host_IP_address>:8006 e.g. https://10.0.0.90:8006 | |
e143e9d8 | 34 | |
a4a9a328 DM |
35 | |
36 | = Install build prerequisites for development environment = | |
47e4eb11 | 37 | |
bb9d3865 MB |
38 | 12. run: |
39 | ||
1e83e254 | 40 | apt-get install build-essential git git-email debhelper \ |
48e957b9 MR |
41 | autotools-dev autogen dh-autoreconf dkms doxygen check pkg-config \ |
42 | groff quilt dpatch automake autoconf libtool lintian libdevel-cycle-perl \ | |
43 | libjson-perl libcommon-sense-perl liblinux-inotify2-perl libio-stringy-perl \ | |
8bc53243 DM |
44 | libstring-shellquote-perl dh-systemd rpm2cpio libsqlite3-dev sqlite3 \ |
45 | libglib2.0-dev librrd-dev librrds-perl rrdcached libdigest-hmac-perl \ | |
46 | libxml-parser-perl gdb libcrypt-openssl-random-perl \ | |
47 | libcrypt-openssl-rsa-perl libnet-ldap-perl libauthen-pam-perl \ | |
48 | libjson-xs-perl libterm-readline-gnu-perl oathtool libmime-base32-perl \ | |
49 | liboath0 libpci-dev texi2html libsdl1.2-dev libgnutls28-dev \ | |
50 | libspice-protocol-dev xfslibs-dev libnuma-dev libaio-dev \ | |
1cfd43f6 | 51 | pve-libspice-server-dev libusbredirparser-dev glusterfs-common \ |
8bc53243 DM |
52 | libusb-1.0-0-dev librbd-dev libpopt-dev iproute bridge-utils numactl \ |
53 | glusterfs-common ceph-common python-ceph libgoogle-perftools4 \ | |
54 | libfile-chdir-perl lvm2 glusterfs-client liblockfile-simple-perl \ | |
37640d62 | 55 | libsystemd-dev libreadline-gplv2-dev libio-multiplex-perl \ |
8bc53243 DM |
56 | libnetfilter-log-dev libipset3 ipset socat libsasl2-dev libogg-dev \ |
57 | python-pyparsing libfilesys-df-perl libcrypt-ssleay-perl \ | |
58 | libfile-readbackwards-perl libanyevent-perl libanyevent-http-perl \ | |
692160c1 | 59 | unzip liblocale-po-perl libfile-sync-perl cstream \ |
8bc53243 | 60 | lzop dtach apt-transport-https hdparm gdisk parted ttf-dejavu-core \ |
37640d62 | 61 | liblzma-dev dosfstools mtools libxen-dev libfuse-dev corosync-dev \ |
3ffb1395 | 62 | libcpg-dev libquorum-dev libcmap-dev libuuid-perl \ |
37640d62 | 63 | libqb-dev libapparmor-dev docbook2x libcap-dev dh-apparmor \ |
fe949d0e | 64 | graphviz libseccomp-dev libglib-perl libgtk3-perl libnss3-dev libdlm-dev \ |
bb9d3865 MB |
65 | libudev-dev asciidoc-dblatex source-highlight libiscsi-dev libiscsi7 \ |
66 | librsvg2-bin | |
67 | ||
e143e9d8 | 68 | |
a4a9a328 DM |
69 | = Compile PVE packages from Source = |
70 | ||
bb9d3865 MB |
71 | 13: Download and install git repositories as Proxmox modules: |
72 | ||
73 | run: mkdir /root/proxmox && cd /root/proxmox | |
74 | ||
75 | run: git clone git://git.proxmox.com/git/pve-common.git | |
76 | ||
77 | 'pve-common.git' is some kind of starting repository and needed for some | |
78 | other repositories as dependency. | |
79 | Install this to get an idea of how the installation process is working. | |
80 | ||
81 | See https://git.proxmox.com/ for all available repositories. | |
82 | ||
83 | 14: Most packages can be installed with 'make dinstall' command. | |
84 | run: cd pve-common && make dinstall | |
85 | ||
86 | 15: Reboot the system. | |
87 | 16. Learn to use the quilt patch scripts. | |
88 | 17. Happy coding! | |
e143e9d8 DM |
89 | |
90 | ||
a4a9a328 | 91 | = REST vs. SOAP = |
e143e9d8 DM |
92 | |
93 | We decided to change our SOAP API (1.X) and use a REST like API. The | |
94 | concept is described in [1] (Resource Oriented Architecture | |
95 | (ROA)). The main advantage is that we are able to remove a lot of code | |
96 | (the whole SOAP stack) to reduce software complexity. | |
97 | ||
98 | We also moved away from server side content generation. Instead we use | |
99 | the ExtJS Rich Internet Application Framework | |
100 | (http://www.sencha.com). | |
101 | ||
102 | That framework, like any other AJAX toolkit, can talk directly to the | |
103 | REST API using JSON. So we were able to remove the server side | |
104 | template toolkit completely. | |
105 | ||
a4a9a328 | 106 | = JSON and JSON Schema = |
e143e9d8 DM |
107 | |
108 | We use JSON as data format, because it is simple and parse-able by any | |
109 | web browser. | |
110 | ||
111 | Additionally, we use JSON Schema [2] to formally describe our API. So | |
112 | we can automatically generate the whole API Documentation, and we can | |
113 | verify all parameters and return values. | |
114 | ||
60f4e8c7 | 115 | A great side effect was that we are able to use JSON Schema to |
e143e9d8 DM |
116 | produce command line argument parsers automatically. In fact, the REST |
117 | API and the command line tools use the same code. | |
118 | ||
119 | Object linkage is done using the JSON Hyper Schema (links property). | |
120 | ||
121 | A small utility called 'pvesh' exposes the whole REST API on the command | |
122 | line. | |
123 | ||
124 | So here is a summary of the advantage: | |
125 | ||
126 | - easy, human readable data format (native web browser format) | |
127 | - automatic parameter verification (we can also verify return values) | |
128 | - automatic generation of API documentation | |
129 | - easy way to create command line tools (using same API). | |
130 | ||
a4a9a328 | 131 | = API Implementation (PVE::RESTHandler) = |
e143e9d8 DM |
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 { | |
ef73f03b | 162 | my ($param) = @_; |
e143e9d8 DM |
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 | ||
a4a9a328 DM |
220 | = References = |
221 | ||
e143e9d8 DM |
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/ |