",
+ "console_type": null,
+ "first_port_name": null,
+ "height": 59,
+ "label": {
+ "rotation": 0,
+ "style": "font-size: 10;font-familly: Verdana",
+ "text": "test",
+ "x": null,
+ "y": -40
+ },
+ "name": "test",
+ "node_directory": null,
+ "node_id": "86b1aa27-5c82-4596-8246-3f7384f853a1",
+ "node_type": "vpcs",
+ "port_name_format": "Ethernet{0}",
+ "port_segment_size": 0,
+ "ports": [
+ {
+ "adapter_number": 0,
+ "data_link_types": {
+ "Ethernet": "DLT_EN10MB"
+ },
+ "link_type": "ethernet",
+ "name": "Ethernet0",
+ "port_number": 0,
+ "short_name": "e0"
+ }
+ ],
+ "project_id": "2071abcf-98b8-42b8-a6e7-6e0e5571e223",
+ "properties": {},
+ "status": "stopped",
+ "symbol": ":/symbols/computer.svg",
+ "width": 65,
+ "x": 0,
+ "y": 0,
+ "z": 0
+}
diff --git a/docs/api/notifications/compute.created.json b/docs/api/notifications/compute.created.json
new file mode 100644
index 00000000..48759ae3
--- /dev/null
+++ b/docs/api/notifications/compute.created.json
@@ -0,0 +1,15 @@
+{
+ "capabilities": {
+ "node_types": [],
+ "version": null
+ },
+ "compute_id": "my_compute",
+ "connected": false,
+ "cpu_usage_percent": null,
+ "host": "localhost",
+ "memory_usage_percent": null,
+ "name": "http://julien@localhost:84",
+ "port": 84,
+ "protocol": "http",
+ "user": "julien"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/compute.deleted.json b/docs/api/notifications/compute.deleted.json
new file mode 100644
index 00000000..2c489ad4
--- /dev/null
+++ b/docs/api/notifications/compute.deleted.json
@@ -0,0 +1,15 @@
+{
+ "capabilities": {
+ "node_types": [],
+ "version": null
+ },
+ "compute_id": "my_compute_id",
+ "connected": false,
+ "cpu_usage_percent": null,
+ "host": "localhost",
+ "memory_usage_percent": null,
+ "name": "http://julien@localhost:84",
+ "port": 84,
+ "protocol": "http",
+ "user": "julien"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/compute.updated.json b/docs/api/notifications/compute.updated.json
new file mode 100644
index 00000000..75d786f7
--- /dev/null
+++ b/docs/api/notifications/compute.updated.json
@@ -0,0 +1,15 @@
+{
+ "capabilities": {
+ "node_types": [],
+ "version": null
+ },
+ "compute_id": "my_compute_id",
+ "connected": false,
+ "cpu_usage_percent": null,
+ "host": "localhost",
+ "memory_usage_percent": null,
+ "name": "http://julien@localhost:84",
+ "port": 84,
+ "protocol": "https",
+ "user": "julien"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/drawing.created.json b/docs/api/notifications/drawing.created.json
new file mode 100644
index 00000000..aae49b31
--- /dev/null
+++ b/docs/api/notifications/drawing.created.json
@@ -0,0 +1,9 @@
+{
+ "drawing_id": "377bccc0-779a-44b0-ab5e-98dfd6dc46cd",
+ "project_id": "adb641a0-8ec9-4b5a-b8df-cc993638c601",
+ "rotation": 0,
+ "svg": "",
+ "x": 10,
+ "y": 20,
+ "z": 0
+}
\ No newline at end of file
diff --git a/docs/api/notifications/drawing.deleted.json b/docs/api/notifications/drawing.deleted.json
new file mode 100644
index 00000000..3d9bb8a5
--- /dev/null
+++ b/docs/api/notifications/drawing.deleted.json
@@ -0,0 +1,9 @@
+{
+ "drawing_id": "b2f8b12f-a4cc-4621-affc-cf3dcd4ba513",
+ "project_id": "24ef7002-5dd6-4054-bf8a-d2aface0885e",
+ "rotation": 0,
+ "svg": "",
+ "x": 0,
+ "y": 0,
+ "z": 0
+}
\ No newline at end of file
diff --git a/docs/api/notifications/drawing.updated.json b/docs/api/notifications/drawing.updated.json
new file mode 100644
index 00000000..9e645a8c
--- /dev/null
+++ b/docs/api/notifications/drawing.updated.json
@@ -0,0 +1,8 @@
+{
+ "drawing_id": "d86ab88f-28bf-4f22-aa4e-e6d3c423b98c",
+ "project_id": "8f53f0f7-9967-4a01-884f-36ea1800e5ef",
+ "rotation": 0,
+ "x": 42,
+ "y": 20,
+ "z": 0
+}
\ No newline at end of file
diff --git a/docs/api/notifications/ignore.json b/docs/api/notifications/ignore.json
new file mode 100644
index 00000000..9bf8f5c3
--- /dev/null
+++ b/docs/api/notifications/ignore.json
@@ -0,0 +1,3 @@
+{
+ "project_id": 42
+}
\ No newline at end of file
diff --git a/docs/api/notifications/link.created.json b/docs/api/notifications/link.created.json
new file mode 100644
index 00000000..904f713b
--- /dev/null
+++ b/docs/api/notifications/link.created.json
@@ -0,0 +1,34 @@
+{
+ "capture_file_name": null,
+ "capture_file_path": null,
+ "capturing": false,
+ "link_id": "9b74fb50-652a-47de-aa7a-f936fad2623a",
+ "link_type": "ethernet",
+ "nodes": [
+ {
+ "adapter_number": 0,
+ "label": {
+ "rotation": 0,
+ "style": "font-size: 10; font-style: Verdana",
+ "text": "0/3",
+ "x": -10,
+ "y": -10
+ },
+ "node_id": "009935d3-bb71-48ee-8f8c-4160ecf36a1f",
+ "port_number": 3
+ },
+ {
+ "adapter_number": 2,
+ "label": {
+ "rotation": 0,
+ "style": "font-size: 10; font-style: Verdana",
+ "text": "2/4",
+ "x": -10,
+ "y": -10
+ },
+ "node_id": "efd15e6d-cc6d-4b85-8e11-0389806f7231",
+ "port_number": 4
+ }
+ ],
+ "project_id": "19def516-231c-4a43-8fdb-1d49333c1f8e"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/link.deleted.json b/docs/api/notifications/link.deleted.json
new file mode 100644
index 00000000..41fc2297
--- /dev/null
+++ b/docs/api/notifications/link.deleted.json
@@ -0,0 +1,9 @@
+{
+ "capture_file_name": null,
+ "capture_file_path": null,
+ "capturing": false,
+ "link_id": "105966d0-8a04-4cf5-95a4-ff13f1de7660",
+ "link_type": "ethernet",
+ "nodes": [],
+ "project_id": "42a1b682-b5bf-4de4-b5af-5366fc20a111"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/link.updated.json b/docs/api/notifications/link.updated.json
new file mode 100644
index 00000000..e0a0ff7a
--- /dev/null
+++ b/docs/api/notifications/link.updated.json
@@ -0,0 +1,32 @@
+{
+ "capture_file_name": null,
+ "capture_file_path": null,
+ "capturing": false,
+ "link_id": "fab9fae2-1ca7-48a5-a3bf-e6cdebf7d89f",
+ "link_type": "ethernet",
+ "nodes": [
+ {
+ "adapter_number": 0,
+ "label": {
+ "text": "Hello",
+ "x": 64,
+ "y": 0
+ },
+ "node_id": "d978c6d1-4503-46ce-a11c-432b7dace22c",
+ "port_number": 3
+ },
+ {
+ "adapter_number": 2,
+ "label": {
+ "rotation": 0,
+ "style": "font-size: 10; font-style: Verdana",
+ "text": "2/4",
+ "x": -10,
+ "y": -10
+ },
+ "node_id": "d1779d19-320a-471b-9d50-91dd3d3f3ecd",
+ "port_number": 4
+ }
+ ],
+ "project_id": "e49cdc9f-ce2d-48b4-a317-7107f4c2c520"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/log.error.json b/docs/api/notifications/log.error.json
new file mode 100644
index 00000000..aaf314d7
--- /dev/null
+++ b/docs/api/notifications/log.error.json
@@ -0,0 +1,3 @@
+{
+ "message": "Permission denied on /tmp"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/log.info.json b/docs/api/notifications/log.info.json
new file mode 100644
index 00000000..f77299a5
--- /dev/null
+++ b/docs/api/notifications/log.info.json
@@ -0,0 +1,3 @@
+{
+ "message": "Image uploaded"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/log.warning.json b/docs/api/notifications/log.warning.json
new file mode 100644
index 00000000..5d630354
--- /dev/null
+++ b/docs/api/notifications/log.warning.json
@@ -0,0 +1,3 @@
+{
+ "message": "Warning ASA 8 is not officialy supported by GNS3"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/node.created.json b/docs/api/notifications/node.created.json
new file mode 100644
index 00000000..e24038fa
--- /dev/null
+++ b/docs/api/notifications/node.created.json
@@ -0,0 +1,3 @@
+{
+ "a": "b"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/node.updated.json b/docs/api/notifications/node.updated.json
new file mode 100644
index 00000000..2c043193
--- /dev/null
+++ b/docs/api/notifications/node.updated.json
@@ -0,0 +1,45 @@
+{
+ "command_line": "",
+ "compute_id": "local",
+ "console": 5006,
+ "console_host": "localhost",
+ "console_type": "telnet",
+ "first_port_name": null,
+ "height": 59,
+ "label": {
+ "rotation": 0,
+ "style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
+ "text": "PC2",
+ "x": 18,
+ "y": -25
+ },
+ "name": "PC2",
+ "node_directory": "/private/var/folders/3s/r2wbv07n7wg4vrsn874lmxxh0000gn/T/pytest-of-noplay/pytest-51/test_open0/project-files/vpcs/748bcd89-624a-40eb-a8d3-1d2e85c99b51",
+ "node_id": "748bcd89-624a-40eb-a8d3-1d2e85c99b51",
+ "node_type": "vpcs",
+ "port_name_format": "Ethernet{0}",
+ "port_segment_size": 0,
+ "ports": [
+ {
+ "adapter_number": 0,
+ "data_link_types": {
+ "Ethernet": "DLT_EN10MB"
+ },
+ "link_type": "ethernet",
+ "name": "Ethernet0",
+ "port_number": 0,
+ "short_name": "e0"
+ }
+ ],
+ "project_id": "3c1be6f9-b4ba-4737-b209-63c47c23359f",
+ "properties": {
+ "startup_script": "",
+ "startup_script_path": "startup.vpc"
+ },
+ "status": "stopped",
+ "symbol": ":/symbols/computer.svg",
+ "width": 65,
+ "x": -71,
+ "y": -98,
+ "z": 1
+}
\ No newline at end of file
diff --git a/docs/api/notifications/ping.json b/docs/api/notifications/ping.json
new file mode 100644
index 00000000..4df2d436
--- /dev/null
+++ b/docs/api/notifications/ping.json
@@ -0,0 +1,3 @@
+{
+ "compute_id": 12
+}
\ No newline at end of file
diff --git a/docs/api/notifications/project.closed.json b/docs/api/notifications/project.closed.json
new file mode 100644
index 00000000..72618444
--- /dev/null
+++ b/docs/api/notifications/project.closed.json
@@ -0,0 +1,12 @@
+{
+ "auto_close": true,
+ "auto_open": false,
+ "auto_start": false,
+ "filename": "test.gns3",
+ "name": "test",
+ "path": "/var/folders/3s/r2wbv07n7wg4vrsn874lmxxh0000gn/T/tmp0vixjsro/projects/74bd9388-bd2e-41cc-b8da-d014cfb9f908",
+ "project_id": "74bd9388-bd2e-41cc-b8da-d014cfb9f908",
+ "scene_height": 1000,
+ "scene_width": 2000,
+ "status": "closed"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/project.updated.json b/docs/api/notifications/project.updated.json
new file mode 100644
index 00000000..7d3091b0
--- /dev/null
+++ b/docs/api/notifications/project.updated.json
@@ -0,0 +1,12 @@
+{
+ "auto_close": true,
+ "auto_open": false,
+ "auto_start": false,
+ "filename": "test.gns3",
+ "name": "test2",
+ "path": "/var/folders/3s/r2wbv07n7wg4vrsn874lmxxh0000gn/T/tmpe4g8gdv7/projects/10010203-0405-0607-0809-0a0b0c0d0e0f",
+ "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f",
+ "scene_height": 1000,
+ "scene_width": 2000,
+ "status": "opened"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/settings.updated.json b/docs/api/notifications/settings.updated.json
new file mode 100644
index 00000000..69fbf10a
--- /dev/null
+++ b/docs/api/notifications/settings.updated.json
@@ -0,0 +1,3 @@
+{
+ "test": true
+}
\ No newline at end of file
diff --git a/docs/api/notifications/snapshot.restored.json b/docs/api/notifications/snapshot.restored.json
new file mode 100644
index 00000000..9dd96166
--- /dev/null
+++ b/docs/api/notifications/snapshot.restored.json
@@ -0,0 +1,6 @@
+{
+ "created_at": 1490088724,
+ "name": "test",
+ "project_id": "ecb64cf5-aec7-469a-a367-3d16f4377cd7",
+ "snapshot_id": "7e0bb824-e0aa-4ff1-b4f8-8453e99cb1bd"
+}
\ No newline at end of file
diff --git a/docs/api/notifications/test.json b/docs/api/notifications/test.json
new file mode 100644
index 00000000..9e26dfee
--- /dev/null
+++ b/docs/api/notifications/test.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/docs/api/v2/compute/capabilities/capabilities.rst b/docs/api/v2/compute/capabilities/capabilities.rst
index d0685663..7c6f7fcc 100644
--- a/docs/api/v2/compute/capabilities/capabilities.rst
+++ b/docs/api/v2/compute/capabilities/capabilities.rst
@@ -22,3 +22,9 @@ Output
version | ✔ | ['string', 'null'] | Version number |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_capabilities.txt
+
diff --git a/docs/api/v2/compute/cloud/projectsprojectidcloudnodes.rst b/docs/api/v2/compute/cloud/projectsprojectidcloudnodes.rst
index c9a5338e..abf7208e 100644
--- a/docs/api/v2/compute/cloud/projectsprojectidcloudnodes.rst
+++ b/docs/api/v2/compute/cloud/projectsprojectidcloudnodes.rst
@@ -61,3 +61,9 @@ Output
status | | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidcloudnodes.txt
+
diff --git a/docs/api/v2/compute/cloud/projectsprojectidcloudnodesnodeid.rst b/docs/api/v2/compute/cloud/projectsprojectidcloudnodesnodeid.rst
index ec97be6e..35577308 100644
--- a/docs/api/v2/compute/cloud/projectsprojectidcloudnodesnodeid.rst
+++ b/docs/api/v2/compute/cloud/projectsprojectidcloudnodesnodeid.rst
@@ -33,6 +33,12 @@ Output
status | | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_projectsprojectidcloudnodesnodeid.txt
+
PUT /v2/compute/projects/**{project_id}**/cloud/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -97,6 +103,12 @@ Output
status | | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_put_projectsprojectidcloudnodesnodeid.txt
+
DELETE /v2/compute/projects/**{project_id}**/cloud/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -113,3 +125,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidcloudnodesnodeid.txt
+
diff --git a/docs/api/v2/compute/cloud/projectsprojectidcloudnodesnodeidadaptersadapternumberdportsportnumberdnio.rst b/docs/api/v2/compute/cloud/projectsprojectidcloudnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
index 693ea808..a1f38f2b 100644
--- a/docs/api/v2/compute/cloud/projectsprojectidcloudnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
+++ b/docs/api/v2/compute/cloud/projectsprojectidcloudnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
@@ -20,6 +20,12 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidcloudnodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
DELETE /v2/compute/projects/**{project_id}**/cloud/nodes/**{node_id}**/adapters/**{adapter_number:\d+}**/ports/**{port_number:\d+}**/nio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -38,3 +44,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidcloudnodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
diff --git a/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeid.rst b/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeid.rst
index 4de9efa8..14d6f50a 100644
--- a/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeid.rst
+++ b/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeid.rst
@@ -83,3 +83,9 @@ Output
status | | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_put_projectsprojectiddockernodesnodeid.txt
+
diff --git a/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdnio.rst b/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdnio.rst
index 9728e7c2..58c2ce73 100644
--- a/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdnio.rst
+++ b/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdnio.rst
@@ -20,6 +20,12 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
DELETE /v2/compute/projects/**{project_id}**/docker/nodes/**{node_id}**/adapters/**{adapter_number:\d+}**/ports/**{port_number:\d+}**/nio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -38,3 +44,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
diff --git a/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdstartcapture.rst b/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdstartcapture.rst
index b224ea50..12b041d4 100644
--- a/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdstartcapture.rst
+++ b/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdstartcapture.rst
@@ -31,3 +31,9 @@ Input
data_link_type | | enum | Possible values: DLT_ATM_RFC1483, DLT_EN10MB, DLT_FRELAY, DLT_C_HDLC, DLT_PPP_SERIAL |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdstartcapture.txt
+
diff --git a/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdstopcapture.rst b/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdstopcapture.rst
index 4cc91dd6..e227f8a0 100644
--- a/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdstopcapture.rst
+++ b/docs/api/v2/compute/docker/projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdstopcapture.rst
@@ -21,3 +21,9 @@ Response status codes
- **404**: Instance doesn't exist
- **409**: Container not started
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectiddockernodesnodeidadaptersadapternumberdportsportnumberdstopcapture.txt
+
diff --git a/docs/api/v2/compute/iou/iouimages.rst b/docs/api/v2/compute/iou/iouimages.rst
index f2b0d7ab..95456098 100644
--- a/docs/api/v2/compute/iou/iouimages.rst
+++ b/docs/api/v2/compute/iou/iouimages.rst
@@ -11,3 +11,9 @@ Response status codes
**********************
- **200**: List of IOU images
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_iouimages.txt
+
diff --git a/docs/api/v2/compute/iou/projectsprojectidiounodes.rst b/docs/api/v2/compute/iou/projectsprojectidiounodes.rst
index 6bfcc865..46e44b20 100644
--- a/docs/api/v2/compute/iou/projectsprojectidiounodes.rst
+++ b/docs/api/v2/compute/iou/projectsprojectidiounodes.rst
@@ -71,3 +71,9 @@ Output
use_default_iou_values | | ['boolean', 'null'] | Use default IOU values |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidiounodes.txt
+
diff --git a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeid.rst b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeid.rst
index b7b93742..557883a2 100644
--- a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeid.rst
+++ b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeid.rst
@@ -47,6 +47,12 @@ Output
use_default_iou_values | | ['boolean', 'null'] | Use default IOU values |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_projectsprojectidiounodesnodeid.txt
+
PUT /v2/compute/projects/**{project_id}**/iou/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -122,6 +128,12 @@ Output
use_default_iou_values | | ['boolean', 'null'] | Use default IOU values |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_put_projectsprojectidiounodesnodeid.txt
+
DELETE /v2/compute/projects/**{project_id}**/iou/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -138,3 +150,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidiounodesnodeid.txt
+
diff --git a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdnio.rst b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdnio.rst
index 6f58909e..3036a9dd 100644
--- a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdnio.rst
+++ b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdnio.rst
@@ -20,6 +20,12 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
DELETE /v2/compute/projects/**{project_id}**/iou/nodes/**{node_id}**/adapters/**{adapter_number:\d+}**/ports/**{port_number:\d+}**/nio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -38,3 +44,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
diff --git a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdstartcapture.rst b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdstartcapture.rst
index 12670a6c..e957b80b 100644
--- a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdstartcapture.rst
+++ b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdstartcapture.rst
@@ -31,3 +31,9 @@ Input
data_link_type | | enum | Possible values: DLT_ATM_RFC1483, DLT_EN10MB, DLT_FRELAY, DLT_C_HDLC, DLT_PPP_SERIAL |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdstartcapture.txt
+
diff --git a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdstopcapture.rst b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdstopcapture.rst
index 2ea2fc51..6cd4afb9 100644
--- a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdstopcapture.rst
+++ b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdstopcapture.rst
@@ -21,3 +21,9 @@ Response status codes
- **404**: Instance doesn't exist
- **409**: VM not started
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidiounodesnodeidadaptersadapternumberdportsportnumberdstopcapture.txt
+
diff --git a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidreload.rst b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidreload.rst
index 7f6d6262..19af3275 100644
--- a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidreload.rst
+++ b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidreload.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidiounodesnodeidreload.txt
+
diff --git a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidstart.rst b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidstart.rst
index c8eda9d1..3df8062a 100644
--- a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidstart.rst
+++ b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidstart.rst
@@ -56,3 +56,9 @@ Output
use_default_iou_values | | ['boolean', 'null'] | Use default IOU values |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidiounodesnodeidstart.txt
+
diff --git a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidstop.rst b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidstop.rst
index d9348673..7934e045 100644
--- a/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidstop.rst
+++ b/docs/api/v2/compute/iou/projectsprojectidiounodesnodeidstop.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidiounodesnodeidstop.txt
+
diff --git a/docs/api/v2/compute/nat/projectsprojectidnatnodes.rst b/docs/api/v2/compute/nat/projectsprojectidnatnodes.rst
index 4d64ab54..1d6e2672 100644
--- a/docs/api/v2/compute/nat/projectsprojectidnatnodes.rst
+++ b/docs/api/v2/compute/nat/projectsprojectidnatnodes.rst
@@ -43,3 +43,9 @@ Output
status | | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidnatnodes.txt
+
diff --git a/docs/api/v2/compute/nat/projectsprojectidnatnodesnodeid.rst b/docs/api/v2/compute/nat/projectsprojectidnatnodesnodeid.rst
index fbaff64d..7507a612 100644
--- a/docs/api/v2/compute/nat/projectsprojectidnatnodesnodeid.rst
+++ b/docs/api/v2/compute/nat/projectsprojectidnatnodesnodeid.rst
@@ -31,6 +31,12 @@ Output
status | | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_projectsprojectidnatnodesnodeid.txt
+
PUT /v2/compute/projects/**{project_id}**/nat/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -74,6 +80,12 @@ Output
status | | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_put_projectsprojectidnatnodesnodeid.txt
+
DELETE /v2/compute/projects/**{project_id}**/nat/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -90,3 +102,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidnatnodesnodeid.txt
+
diff --git a/docs/api/v2/compute/nat/projectsprojectidnatnodesnodeidadaptersadapternumberdportsportnumberdnio.rst b/docs/api/v2/compute/nat/projectsprojectidnatnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
index 4563f285..7dc12995 100644
--- a/docs/api/v2/compute/nat/projectsprojectidnatnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
+++ b/docs/api/v2/compute/nat/projectsprojectidnatnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
@@ -20,6 +20,12 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidnatnodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
DELETE /v2/compute/projects/**{project_id}**/nat/nodes/**{node_id}**/adapters/**{adapter_number:\d+}**/ports/**{port_number:\d+}**/nio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -38,3 +44,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidnatnodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
diff --git a/docs/api/v2/compute/network/networkinterfaces.rst b/docs/api/v2/compute/network/networkinterfaces.rst
index 61d1ed3d..66f40f0d 100644
--- a/docs/api/v2/compute/network/networkinterfaces.rst
+++ b/docs/api/v2/compute/network/networkinterfaces.rst
@@ -11,3 +11,9 @@ Response status codes
**********************
- **200**: OK
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_networkinterfaces.txt
+
diff --git a/docs/api/v2/compute/network/projectsprojectidportsudp.rst b/docs/api/v2/compute/network/projectsprojectidportsudp.rst
index 0c6f0090..ca5f9b03 100644
--- a/docs/api/v2/compute/network/projectsprojectidportsudp.rst
+++ b/docs/api/v2/compute/network/projectsprojectidportsudp.rst
@@ -16,3 +16,9 @@ Response status codes
- **201**: UDP port allocated
- **404**: The project doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidportsudp.txt
+
diff --git a/docs/api/v2/compute/project/projects.rst b/docs/api/v2/compute/project/projects.rst
index 36379831..1ead42be 100644
--- a/docs/api/v2/compute/project/projects.rst
+++ b/docs/api/v2/compute/project/projects.rst
@@ -11,6 +11,12 @@ Response status codes
**********************
- **200**: Project list
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_projects.txt
+
POST /v2/compute/projects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -54,3 +60,9 @@ Output
status | | enum | Possible values: opened, closed |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projects.txt
+
diff --git a/docs/api/v2/compute/project/projectsprojectid.rst b/docs/api/v2/compute/project/projectsprojectid.rst
index 606c1c78..373b19a2 100644
--- a/docs/api/v2/compute/project/projectsprojectid.rst
+++ b/docs/api/v2/compute/project/projectsprojectid.rst
@@ -34,6 +34,12 @@ Output
status | | enum | Possible values: opened, closed |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_projectsprojectid.txt
+
DELETE /v2/compute/projects/**{project_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -48,3 +54,9 @@ Response status codes
- **204**: Changes have been written on disk
- **404**: The project doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectid.txt
+
diff --git a/docs/api/v2/compute/project/projectsprojectidclose.rst b/docs/api/v2/compute/project/projectsprojectidclose.rst
index c651d88d..b507cae8 100644
--- a/docs/api/v2/compute/project/projectsprojectidclose.rst
+++ b/docs/api/v2/compute/project/projectsprojectidclose.rst
@@ -16,3 +16,9 @@ Response status codes
- **204**: Project closed
- **404**: The project doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidclose.txt
+
diff --git a/docs/api/v2/compute/qemu/projectsprojectidqemunodes.rst b/docs/api/v2/compute/qemu/projectsprojectidqemunodes.rst
index b6b1b2f2..6ab2e8f1 100644
--- a/docs/api/v2/compute/qemu/projectsprojectidqemunodes.rst
+++ b/docs/api/v2/compute/qemu/projectsprojectidqemunodes.rst
@@ -116,3 +116,9 @@ Output
usage | ✔ | string | How to use the QEMU VM |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidqemunodes.txt
+
diff --git a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeid.rst b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeid.rst
index bc82ed07..ced6f8d5 100644
--- a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeid.rst
+++ b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeid.rst
@@ -69,6 +69,12 @@ Output
usage | ✔ | string | How to use the QEMU VM |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_projectsprojectidqemunodesnodeid.txt
+
PUT /v2/compute/projects/**{project_id}**/qemu/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -184,6 +190,12 @@ Output
usage | ✔ | string | How to use the QEMU VM |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_put_projectsprojectidqemunodesnodeid.txt
+
DELETE /v2/compute/projects/**{project_id}**/qemu/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -200,3 +212,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidqemunodesnodeid.txt
+
diff --git a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidadaptersadapternumberdportsportnumberdnio.rst b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidadaptersadapternumberdportsportnumberdnio.rst
index c83d8fa3..8aaa9c02 100644
--- a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidadaptersadapternumberdportsportnumberdnio.rst
+++ b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidadaptersadapternumberdportsportnumberdnio.rst
@@ -20,6 +20,12 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidqemunodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
DELETE /v2/compute/projects/**{project_id}**/qemu/nodes/**{node_id}**/adapters/**{adapter_number:\d+}**/ports/**{port_number:\d+}**/nio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -38,3 +44,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidqemunodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
diff --git a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidreload.rst b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidreload.rst
index 8bee2ec1..f7346523 100644
--- a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidreload.rst
+++ b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidreload.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidqemunodesnodeidreload.txt
+
diff --git a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidresume.rst b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidresume.rst
index 938c5ad0..f6c35a56 100644
--- a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidresume.rst
+++ b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidresume.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidqemunodesnodeidresume.txt
+
diff --git a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidstart.rst b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidstart.rst
index 4b59d12c..82150273 100644
--- a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidstart.rst
+++ b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidstart.rst
@@ -69,3 +69,9 @@ Output
usage | ✔ | string | How to use the QEMU VM |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidqemunodesnodeidstart.txt
+
diff --git a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidstop.rst b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidstop.rst
index 90b6447e..405185e7 100644
--- a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidstop.rst
+++ b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidstop.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidqemunodesnodeidstop.txt
+
diff --git a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidsuspend.rst b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidsuspend.rst
index f41b998b..78af62ee 100644
--- a/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidsuspend.rst
+++ b/docs/api/v2/compute/qemu/projectsprojectidqemunodesnodeidsuspend.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidqemunodesnodeidsuspend.txt
+
diff --git a/docs/api/v2/compute/qemu/qemubinaries.rst b/docs/api/v2/compute/qemu/qemubinaries.rst
index 572aa802..f1a4173b 100644
--- a/docs/api/v2/compute/qemu/qemubinaries.rst
+++ b/docs/api/v2/compute/qemu/qemubinaries.rst
@@ -22,3 +22,9 @@ Input
archs | | array | Architectures to filter binaries with |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_qemubinaries.txt
+
diff --git a/docs/api/v2/compute/qemu/qemucapabilities.rst b/docs/api/v2/compute/qemu/qemucapabilities.rst
index f1a5b841..eeb70e2f 100644
--- a/docs/api/v2/compute/qemu/qemucapabilities.rst
+++ b/docs/api/v2/compute/qemu/qemucapabilities.rst
@@ -20,3 +20,9 @@ Output
kvm | | array | Architectures that KVM is enabled for |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_qemucapabilities.txt
+
diff --git a/docs/api/v2/compute/qemu/qemuimg.rst b/docs/api/v2/compute/qemu/qemuimg.rst
index efa21555..b64f4d8d 100644
--- a/docs/api/v2/compute/qemu/qemuimg.rst
+++ b/docs/api/v2/compute/qemu/qemuimg.rst
@@ -31,3 +31,9 @@ Input
zeroed_grain | | enum | Possible values: on, off |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_qemuimg.txt
+
diff --git a/docs/api/v2/compute/server/version.rst b/docs/api/v2/compute/server/version.rst
index d58dc956..b4947701 100644
--- a/docs/api/v2/compute/server/version.rst
+++ b/docs/api/v2/compute/server/version.rst
@@ -21,3 +21,9 @@ Output
version | ✔ | string | Version number |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_version.txt
+
diff --git a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodes.rst b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodes.rst
index 710eed0c..04ce4503 100644
--- a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodes.rst
+++ b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodes.rst
@@ -60,3 +60,9 @@ Output
vmname | | string | VirtualBox VM name (in VirtualBox itself) |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvirtualboxnodes.txt
+
diff --git a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeid.rst b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeid.rst
index 461089b6..5af6251e 100644
--- a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeid.rst
+++ b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeid.rst
@@ -41,6 +41,12 @@ Output
vmname | | string | VirtualBox VM name (in VirtualBox itself) |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_projectsprojectidvirtualboxnodesnodeid.txt
+
PUT /v2/compute/projects/**{project_id}**/virtualbox/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -104,6 +110,12 @@ Output
vmname | | string | VirtualBox VM name (in VirtualBox itself) |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_put_projectsprojectidvirtualboxnodesnodeid.txt
+
DELETE /v2/compute/projects/**{project_id}**/virtualbox/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidadaptersadapternumberdportsportnumberdnio.rst b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
index 2bfdd646..98db45ad 100644
--- a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
+++ b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
@@ -20,6 +20,12 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvirtualboxnodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
DELETE /v2/compute/projects/**{project_id}**/virtualbox/nodes/**{node_id}**/adapters/**{adapter_number:\d+}**/ports/**{port_number:\d+}**/nio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -38,3 +44,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidvirtualboxnodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
diff --git a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidreload.rst b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidreload.rst
index 58a62435..87344ad3 100644
--- a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidreload.rst
+++ b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidreload.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvirtualboxnodesnodeidreload.txt
+
diff --git a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidresume.rst b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidresume.rst
index 2e4f8523..72a76026 100644
--- a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidresume.rst
+++ b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidresume.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvirtualboxnodesnodeidresume.txt
+
diff --git a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidstart.rst b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidstart.rst
index 506d8663..1efeb459 100644
--- a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidstart.rst
+++ b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidstart.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvirtualboxnodesnodeidstart.txt
+
diff --git a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidstop.rst b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidstop.rst
index 6050655a..6b747d82 100644
--- a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidstop.rst
+++ b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidstop.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvirtualboxnodesnodeidstop.txt
+
diff --git a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidsuspend.rst b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidsuspend.rst
index dc24b777..7fba3344 100644
--- a/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidsuspend.rst
+++ b/docs/api/v2/compute/virtualbox/projectsprojectidvirtualboxnodesnodeidsuspend.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvirtualboxnodesnodeidsuspend.txt
+
diff --git a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodes.rst b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodes.rst
index d0fb80de..3afe7156 100644
--- a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodes.rst
+++ b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodes.rst
@@ -49,3 +49,9 @@ Output
status | ✔ | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvpcsnodes.txt
+
diff --git a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeid.rst b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeid.rst
index 330e3490..edfa0920 100644
--- a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeid.rst
+++ b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeid.rst
@@ -36,6 +36,12 @@ Output
status | ✔ | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_get_projectsprojectidvpcsnodesnodeid.txt
+
PUT /v2/compute/projects/**{project_id}**/vpcs/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -84,6 +90,12 @@ Output
status | ✔ | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_put_projectsprojectidvpcsnodesnodeid.txt
+
DELETE /v2/compute/projects/**{project_id}**/vpcs/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -100,3 +112,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidvpcsnodesnodeid.txt
+
diff --git a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidadaptersadapternumberdportsportnumberdnio.rst b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
index 62e23572..89141be5 100644
--- a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
+++ b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidadaptersadapternumberdportsportnumberdnio.rst
@@ -20,6 +20,12 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvpcsnodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
DELETE /v2/compute/projects/**{project_id}**/vpcs/nodes/**{node_id}**/adapters/**{adapter_number:\d+}**/ports/**{port_number:\d+}**/nio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -38,3 +44,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_delete_projectsprojectidvpcsnodesnodeidadaptersadapternumberdportsportnumberdnio.txt
+
diff --git a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidreload.rst b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidreload.rst
index 0f721c01..b8f95b67 100644
--- a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidreload.rst
+++ b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidreload.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvpcsnodesnodeidreload.txt
+
diff --git a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidstart.rst b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidstart.rst
index 7a579b26..50a42ea1 100644
--- a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidstart.rst
+++ b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidstart.rst
@@ -36,3 +36,9 @@ Output
status | ✔ | enum | Possible values: started, stopped, suspended |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvpcsnodesnodeidstart.txt
+
diff --git a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidstop.rst b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidstop.rst
index 1f1fff3c..3c1b34ae 100644
--- a/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidstop.rst
+++ b/docs/api/v2/compute/vpcs/projectsprojectidvpcsnodesnodeidstop.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/compute_post_projectsprojectidvpcsnodesnodeidstop.txt
+
diff --git a/docs/api/v2/controller/drawing/projectsprojectiddrawings.rst b/docs/api/v2/controller/drawing/projectsprojectiddrawings.rst
index 972354dc..6886511c 100644
--- a/docs/api/v2/controller/drawing/projectsprojectiddrawings.rst
+++ b/docs/api/v2/controller/drawing/projectsprojectiddrawings.rst
@@ -15,6 +15,12 @@ Response status codes
**********************
- **200**: List of drawings returned
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_projectsprojectiddrawings.txt
+
POST /v2/projects/**{project_id}**/drawings
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -59,3 +65,9 @@ Output
z | | integer | Z property |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectiddrawings.txt
+
diff --git a/docs/api/v2/controller/drawing/projectsprojectiddrawingsdrawingid.rst b/docs/api/v2/controller/drawing/projectsprojectiddrawingsdrawingid.rst
index 6f16c063..3ff0b4a5 100644
--- a/docs/api/v2/controller/drawing/projectsprojectiddrawingsdrawingid.rst
+++ b/docs/api/v2/controller/drawing/projectsprojectiddrawingsdrawingid.rst
@@ -47,6 +47,12 @@ Output
z | | integer | Z property |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_put_projectsprojectiddrawingsdrawingid.txt
+
DELETE /v2/projects/**{project_id}**/drawings/**{drawing_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -62,3 +68,9 @@ Response status codes
- **204**: Drawing deleted
- **400**: Invalid request
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_delete_projectsprojectiddrawingsdrawingid.txt
+
diff --git a/docs/api/v2/controller/gns3_vm/gns3vm.rst b/docs/api/v2/controller/gns3_vm/gns3vm.rst
index e6acb4e4..423ff461 100644
--- a/docs/api/v2/controller/gns3_vm/gns3vm.rst
+++ b/docs/api/v2/controller/gns3_vm/gns3vm.rst
@@ -11,6 +11,12 @@ Response status codes
**********************
- **200**: GNS3 VM settings returned
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_gns3vm.txt
+
PUT /v2/gns3vm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -20,3 +26,9 @@ Response status codes
**********************
- **201**: GNS3 VM updated
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_put_gns3vm.txt
+
diff --git a/docs/api/v2/controller/gns3_vm/gns3vmengines.rst b/docs/api/v2/controller/gns3_vm/gns3vmengines.rst
index 6ee79e12..1c9f5c29 100644
--- a/docs/api/v2/controller/gns3_vm/gns3vmengines.rst
+++ b/docs/api/v2/controller/gns3_vm/gns3vmengines.rst
@@ -11,3 +11,9 @@ Response status codes
**********************
- **200**: OK
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_gns3vmengines.txt
+
diff --git a/docs/api/v2/controller/gns3_vm/gns3vmenginesenginevms.rst b/docs/api/v2/controller/gns3_vm/gns3vmenginesenginevms.rst
index b6158597..4b5cc690 100644
--- a/docs/api/v2/controller/gns3_vm/gns3vmenginesenginevms.rst
+++ b/docs/api/v2/controller/gns3_vm/gns3vmenginesenginevms.rst
@@ -16,3 +16,9 @@ Response status codes
- **200**: Success
- **400**: Invalid request
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_gns3vmenginesenginevms.txt
+
diff --git a/docs/api/v2/controller/link/projectsprojectidlinks.rst b/docs/api/v2/controller/link/projectsprojectidlinks.rst
index 1c8c739e..1916606f 100644
--- a/docs/api/v2/controller/link/projectsprojectidlinks.rst
+++ b/docs/api/v2/controller/link/projectsprojectidlinks.rst
@@ -15,6 +15,12 @@ Response status codes
**********************
- **200**: List of links returned
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_projectsprojectidlinks.txt
+
POST /v2/projects/**{project_id}**/links
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -59,3 +65,9 @@ Output
project_id | | string | Project UUID |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidlinks.txt
+
diff --git a/docs/api/v2/controller/link/projectsprojectidlinkslinkid.rst b/docs/api/v2/controller/link/projectsprojectidlinkslinkid.rst
index 65716bea..834a34b0 100644
--- a/docs/api/v2/controller/link/projectsprojectidlinkslinkid.rst
+++ b/docs/api/v2/controller/link/projectsprojectidlinkslinkid.rst
@@ -62,3 +62,9 @@ Response status codes
- **204**: Link deleted
- **400**: Invalid request
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_delete_projectsprojectidlinkslinkid.txt
+
diff --git a/docs/api/v2/controller/link/projectsprojectidlinkslinkidstartcapture.rst b/docs/api/v2/controller/link/projectsprojectidlinkslinkidstartcapture.rst
index 37a0e4f5..888ef4b2 100644
--- a/docs/api/v2/controller/link/projectsprojectidlinkslinkidstartcapture.rst
+++ b/docs/api/v2/controller/link/projectsprojectidlinkslinkidstartcapture.rst
@@ -42,3 +42,9 @@ Output
project_id | | string | Project UUID |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidlinkslinkidstartcapture.txt
+
diff --git a/docs/api/v2/controller/link/projectsprojectidlinkslinkidstopcapture.rst b/docs/api/v2/controller/link/projectsprojectidlinkslinkidstopcapture.rst
index ec1f0ccd..51ec1be7 100644
--- a/docs/api/v2/controller/link/projectsprojectidlinkslinkidstopcapture.rst
+++ b/docs/api/v2/controller/link/projectsprojectidlinkslinkidstopcapture.rst
@@ -17,3 +17,9 @@ Response status codes
- **201**: Capture stopped
- **400**: Invalid request
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidlinkslinkidstopcapture.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodes.rst b/docs/api/v2/controller/node/projectsprojectidnodes.rst
index d2177317..58bc8ea3 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodes.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodes.rst
@@ -78,6 +78,12 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidnodes.txt
+
GET /v2/projects/**{project_id}**/nodes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -91,3 +97,9 @@ Response status codes
**********************
- **200**: List of nodes returned
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_projectsprojectidnodes.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodesnodeid.rst b/docs/api/v2/controller/node/projectsprojectidnodesnodeid.rst
index 3258a098..08c66a42 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodesnodeid.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodesnodeid.rst
@@ -44,6 +44,12 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_projectsprojectidnodesnodeid.txt
+
PUT /v2/projects/**{project_id}**/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -117,6 +123,12 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_put_projectsprojectidnodesnodeid.txt
+
DELETE /v2/projects/**{project_id}**/nodes/**{node_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -133,3 +145,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_delete_projectsprojectidnodesnodeid.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodesnodeiddynamipsautoidlepc.rst b/docs/api/v2/controller/node/projectsprojectidnodesnodeiddynamipsautoidlepc.rst
index 83e3b94c..28d3bbfa 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodesnodeiddynamipsautoidlepc.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodesnodeiddynamipsautoidlepc.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_projectsprojectidnodesnodeiddynamipsautoidlepc.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodesnodeiddynamipsidlepcproposals.rst b/docs/api/v2/controller/node/projectsprojectidnodesnodeiddynamipsidlepcproposals.rst
index 8affe5a1..bc42aeca 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodesnodeiddynamipsidlepcproposals.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodesnodeiddynamipsidlepcproposals.rst
@@ -18,3 +18,9 @@ Response status codes
- **400**: Invalid request
- **404**: Instance doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_projectsprojectidnodesnodeiddynamipsidlepcproposals.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodesnodeidreload.rst b/docs/api/v2/controller/node/projectsprojectidnodesnodeidreload.rst
index 994a8c2d..299cffd1 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodesnodeidreload.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodesnodeidreload.rst
@@ -49,3 +49,9 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidnodesnodeidreload.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodesnodeidstart.rst b/docs/api/v2/controller/node/projectsprojectidnodesnodeidstart.rst
index afdf56e8..a05b8d1b 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodesnodeidstart.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodesnodeidstart.rst
@@ -49,3 +49,9 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidnodesnodeidstart.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodesnodeidstop.rst b/docs/api/v2/controller/node/projectsprojectidnodesnodeidstop.rst
index 7eba9826..32b19365 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodesnodeidstop.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodesnodeidstop.rst
@@ -49,3 +49,9 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidnodesnodeidstop.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodesnodeidsuspend.rst b/docs/api/v2/controller/node/projectsprojectidnodesnodeidsuspend.rst
index dcf6474d..1c64e4a8 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodesnodeidsuspend.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodesnodeidsuspend.rst
@@ -49,3 +49,9 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidnodesnodeidsuspend.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodesreload.rst b/docs/api/v2/controller/node/projectsprojectidnodesreload.rst
index 66719c66..7da934b0 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodesreload.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodesreload.rst
@@ -48,3 +48,9 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidnodesreload.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodesstart.rst b/docs/api/v2/controller/node/projectsprojectidnodesstart.rst
index 6ec39708..32eb740d 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodesstart.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodesstart.rst
@@ -48,3 +48,9 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidnodesstart.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodesstop.rst b/docs/api/v2/controller/node/projectsprojectidnodesstop.rst
index 94a3c5f1..3e19dafc 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodesstop.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodesstop.rst
@@ -48,3 +48,9 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidnodesstop.txt
+
diff --git a/docs/api/v2/controller/node/projectsprojectidnodessuspend.rst b/docs/api/v2/controller/node/projectsprojectidnodessuspend.rst
index 595b4740..f32e5935 100644
--- a/docs/api/v2/controller/node/projectsprojectidnodessuspend.rst
+++ b/docs/api/v2/controller/node/projectsprojectidnodessuspend.rst
@@ -48,3 +48,9 @@ Output
z | | integer | Z position of the node |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidnodessuspend.txt
+
diff --git a/docs/api/v2/controller/project/projects.rst b/docs/api/v2/controller/project/projects.rst
index cfc45158..78bf8367 100644
--- a/docs/api/v2/controller/project/projects.rst
+++ b/docs/api/v2/controller/project/projects.rst
@@ -44,6 +44,12 @@ Output
status | | enum | Possible values: opened, closed |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projects.txt
+
GET /v2/projects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -53,3 +59,9 @@ Response status codes
**********************
- **200**: List of projects
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_projects.txt
+
diff --git a/docs/api/v2/controller/project/projectsload.rst b/docs/api/v2/controller/project/projectsload.rst
index 8f018a42..e59bc766 100644
--- a/docs/api/v2/controller/project/projectsload.rst
+++ b/docs/api/v2/controller/project/projectsload.rst
@@ -43,3 +43,9 @@ Output
status | | enum | Possible values: opened, closed |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsload.txt
+
diff --git a/docs/api/v2/controller/project/projectsprojectid.rst b/docs/api/v2/controller/project/projectsprojectid.rst
index 3a257af0..6d084b30 100644
--- a/docs/api/v2/controller/project/projectsprojectid.rst
+++ b/docs/api/v2/controller/project/projectsprojectid.rst
@@ -16,6 +16,12 @@ Response status codes
- **200**: Project information returned
- **404**: The project doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_projectsprojectid.txt
+
PUT /v2/projects/**{project_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -60,6 +66,12 @@ Output
status | | enum | Possible values: opened, closed |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_put_projectsprojectid.txt
+
DELETE /v2/projects/**{project_id}**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -74,3 +86,9 @@ Response status codes
- **204**: Changes have been written on disk
- **404**: The project doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_delete_projectsprojectid.txt
+
diff --git a/docs/api/v2/controller/project/projectsprojectidclose.rst b/docs/api/v2/controller/project/projectsprojectidclose.rst
index 72c36ddb..a9a44218 100644
--- a/docs/api/v2/controller/project/projectsprojectidclose.rst
+++ b/docs/api/v2/controller/project/projectsprojectidclose.rst
@@ -34,3 +34,9 @@ Output
status | | enum | Possible values: opened, closed |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidclose.txt
+
diff --git a/docs/api/v2/controller/project/projectsprojectidduplicate.rst b/docs/api/v2/controller/project/projectsprojectidduplicate.rst
index 17a0611a..da438b74 100644
--- a/docs/api/v2/controller/project/projectsprojectidduplicate.rst
+++ b/docs/api/v2/controller/project/projectsprojectidduplicate.rst
@@ -49,3 +49,9 @@ Output
status | | enum | Possible values: opened, closed |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidduplicate.txt
+
diff --git a/docs/api/v2/controller/project/projectsprojectidopen.rst b/docs/api/v2/controller/project/projectsprojectidopen.rst
index 9af3191a..02c3e627 100644
--- a/docs/api/v2/controller/project/projectsprojectidopen.rst
+++ b/docs/api/v2/controller/project/projectsprojectidopen.rst
@@ -34,3 +34,9 @@ Output
status | | enum | Possible values: opened, closed |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidopen.txt
+
diff --git a/docs/api/v2/controller/server/settings.rst b/docs/api/v2/controller/server/settings.rst
index 8d9d6f63..ff3cac61 100644
--- a/docs/api/v2/controller/server/settings.rst
+++ b/docs/api/v2/controller/server/settings.rst
@@ -11,6 +11,12 @@ Response status codes
**********************
- **200**: OK
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_settings.txt
+
POST /v2/settings
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -20,3 +26,9 @@ Response status codes
**********************
- **201**: Writed
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_settings.txt
+
diff --git a/docs/api/v2/controller/server/shutdown.rst b/docs/api/v2/controller/server/shutdown.rst
index 8a1849d1..27d95fed 100644
--- a/docs/api/v2/controller/server/shutdown.rst
+++ b/docs/api/v2/controller/server/shutdown.rst
@@ -12,3 +12,9 @@ Response status codes
- **201**: Server is shutting down
- **403**: Server shutdown refused
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_shutdown.txt
+
diff --git a/docs/api/v2/controller/server/version.rst b/docs/api/v2/controller/server/version.rst
index b43d4d0b..70c5f5db 100644
--- a/docs/api/v2/controller/server/version.rst
+++ b/docs/api/v2/controller/server/version.rst
@@ -21,6 +21,12 @@ Output
version | ✔ | string | Version number |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_version.txt
+
POST /v2/version
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -51,3 +57,9 @@ Output
version | ✔ | string | Version number |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_version.txt
+
diff --git a/docs/api/v2/controller/snapshot/projectsprojectidsnapshots.rst b/docs/api/v2/controller/snapshot/projectsprojectidsnapshots.rst
index 4c537bbe..c37b5788 100644
--- a/docs/api/v2/controller/snapshot/projectsprojectidsnapshots.rst
+++ b/docs/api/v2/controller/snapshot/projectsprojectidsnapshots.rst
@@ -37,6 +37,12 @@ Output
snapshot_id | ✔ | string | Snapshot UUID |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidsnapshots.txt
+
GET /v2/projects/**{project_id}**/snapshots
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -51,3 +57,9 @@ Response status codes
- **200**: Snasphot list returned
- **404**: The project doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_projectsprojectidsnapshots.txt
+
diff --git a/docs/api/v2/controller/snapshot/projectsprojectidsnapshotssnapshotid.rst b/docs/api/v2/controller/snapshot/projectsprojectidsnapshotssnapshotid.rst
index 3540c7bd..bf3a0e59 100644
--- a/docs/api/v2/controller/snapshot/projectsprojectidsnapshotssnapshotid.rst
+++ b/docs/api/v2/controller/snapshot/projectsprojectidsnapshotssnapshotid.rst
@@ -17,3 +17,9 @@ Response status codes
- **204**: Changes have been written on disk
- **404**: The project or snapshot doesn't exist
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_delete_projectsprojectidsnapshotssnapshotid.txt
+
diff --git a/docs/api/v2/controller/snapshot/projectsprojectidsnapshotssnapshotidrestore.rst b/docs/api/v2/controller/snapshot/projectsprojectidsnapshotssnapshotidrestore.rst
index e8885eb2..7c55a564 100644
--- a/docs/api/v2/controller/snapshot/projectsprojectidsnapshotssnapshotidrestore.rst
+++ b/docs/api/v2/controller/snapshot/projectsprojectidsnapshotssnapshotidrestore.rst
@@ -35,3 +35,9 @@ Output
status | | enum | Possible values: opened, closed |
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_post_projectsprojectidsnapshotssnapshotidrestore.txt
+
diff --git a/docs/api/v2/controller/symbol/symbols.rst b/docs/api/v2/controller/symbol/symbols.rst
index a58a8b66..d6ed5aa6 100644
--- a/docs/api/v2/controller/symbol/symbols.rst
+++ b/docs/api/v2/controller/symbol/symbols.rst
@@ -11,3 +11,9 @@ Response status codes
**********************
- **200**: Symbols list returned
+Sample session
+***************
+
+
+.. literalinclude:: ../../../examples/controller_get_symbols.txt
+
diff --git a/docs/index.rst b/docs/index.rst
index 1acea149..c02cea54 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -31,5 +31,4 @@ GNS3 developements
.. toctree::
development
file_format
- port_name_format
diff --git a/docs/port_name_format.rst b/docs/port_name_format.rst
deleted file mode 100644
index 2c5a5d77..00000000
--- a/docs/port_name_format.rst
+++ /dev/null
@@ -1,40 +0,0 @@
-Port name formatting
-####################
-
-Some node like qemu allow you to personnalize the name of ports in order to match the name of the interfaces inside the emulator.
-
-Simple syntax
-==============
-The first {} will be replace by the interface number
-
-For example: "eth{}" will give:
-* eth0
-* eth1
-* eth2
-
-Or more verbose "eth{port0}" and "eth{0}" will do the same.
-
-Use segments
-============
-
-Segment allow you to split your interface in multiple ports
-
-For example "Ethernet{segment0}/{port0}" with a segment size of 3:
-
-- Ethernet0/0
-- Ethernet0/1
-- Ethernet0/2
-- Ethernet1/0
-- Ethernet1/1
-
-You can also change the start number.
-
-For example "Ethernet{segment1}/{port1}" with a segment size of 3:
-
-- Ethernet1/1
-- Ethernet1/2
-- Ethernet1/3
-- Ethernet2/1
-- Ethernet2/2
-
-This work from port0 to port9 if you need a bigger range ask us.
diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py
index b728401b..b536a271 100644
--- a/gns3server/compute/base_node.py
+++ b/gns3server/compute/base_node.py
@@ -28,7 +28,7 @@ import platform
from gns3server.utils.interfaces import interfaces
from ..compute.port_manager import PortManager
-from ..utils.asyncio import wait_run_in_executor
+from ..utils.asyncio import wait_run_in_executor, locked_coroutine
from ..utils.asyncio.telnet_server import AsyncioTelnetServer
from ..ubridge.hypervisor import Hypervisor
from ..ubridge.ubridge_error import UbridgeError
@@ -519,12 +519,16 @@ class BaseNode:
except UbridgeError as e:
raise UbridgeError("{}: {}".format(e, self._ubridge_hypervisor.read_stdout()))
- @asyncio.coroutine
+ @locked_coroutine
def _start_ubridge(self):
"""
Starts uBridge (handles connections to and from this node).
"""
+ # Prevent us to start multiple ubridge
+ if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running():
+ return
+
if self.ubridge_path is None:
raise NodeError("uBridge is not available, path doesn't exist, or you just installed GNS3 and need to restart your user session to refresh user permissions.")
diff --git a/gns3server/compute/docker/__init__.py b/gns3server/compute/docker/__init__.py
index 1ff3430d..835e7cd1 100644
--- a/gns3server/compute/docker/__init__.py
+++ b/gns3server/compute/docker/__init__.py
@@ -24,14 +24,14 @@ import asyncio
import logging
import aiohttp
import json
-import sys
from gns3server.utils import parse_version
+from gns3server.utils.asyncio import locked_coroutine
+from gns3server.compute.base_manager import BaseManager
+from gns3server.compute.docker.docker_vm import DockerVM
+from gns3server.compute.docker.docker_error import DockerError, DockerHttp304Error, DockerHttp404Error
log = logging.getLogger(__name__)
-from ..base_manager import BaseManager
-from .docker_vm import DockerVM
-from .docker_error import *
DOCKER_MINIMUM_API_VERSION = "1.21"
@@ -46,30 +46,38 @@ class Docker(BaseManager):
self._connected = False
# Allow locking during ubridge operations
self.ubridge_lock = asyncio.Lock()
+ self._connector = None
+ self._session = None
@asyncio.coroutine
- def connector(self):
- if not self._connected or self._connector.closed:
- if not sys.platform.startswith("linux"):
- raise DockerError("Docker is supported only on Linux")
-
+ def _check_connection(self):
+ if not self._connected:
try:
- self._connector = aiohttp.connector.UnixConnector(self._server_url, conn_timeout=2)
self._connected = True
+ connector = self.connector()
version = yield from self.query("GET", "version")
except (aiohttp.errors.ClientOSError, FileNotFoundError):
self._connected = False
raise DockerError("Can't connect to docker daemon")
-
if parse_version(version["ApiVersion"]) < parse_version(DOCKER_MINIMUM_API_VERSION):
raise DockerError("Docker API version is {}. GNS3 requires a minimum API version of {}".format(version["ApiVersion"], DOCKER_MINIMUM_API_VERSION))
+
+ def connector(self):
+ if self._connector is None or self._connector.closed:
+ if not sys.platform.startswith("linux"):
+ raise DockerError("Docker is supported only on Linux")
+ try:
+ self._connector = aiohttp.connector.UnixConnector(self._server_url, conn_timeout=2, limit=None)
+ except (aiohttp.errors.ClientOSError, FileNotFoundError):
+ raise DockerError("Can't connect to docker daemon")
return self._connector
@asyncio.coroutine
def unload(self):
yield from super().unload()
if self._connected:
- self._connector.close()
+ if self._connector and not self._connector.closed:
+ yield from self._connector.close()
@asyncio.coroutine
def query(self, method, path, data={}, params={}):
@@ -84,7 +92,7 @@ class Docker(BaseManager):
response = yield from self.http_query(method, path, data=data, params=params)
body = yield from response.read()
- if len(body):
+ if body and len(body):
if response.headers['CONTENT-TYPE'] == 'application/json':
body = json.loads(body.decode("utf-8"))
else:
@@ -93,7 +101,7 @@ class Docker(BaseManager):
return body
@asyncio.coroutine
- def http_query(self, method, path, data={}, params={}):
+ def http_query(self, method, path, data={}, params={}, timeout=300):
"""
Make a query to the docker daemon
@@ -101,18 +109,28 @@ class Docker(BaseManager):
:param path: Endpoint in API
:param data: Dictionnary with the body. Will be transformed to a JSON
:param params: Parameters added as a query arg
+ :param timeout: Timeout
:returns: HTTP response
"""
data = json.dumps(data)
url = "http://docker/" + path
+
+ if timeout is None:
+ timeout = 60 * 60 * 24 * 31 # One month timeout
+
try:
- response = yield from aiohttp.request(
+ if path != "version": # version is use by check connection
+ yield from self._check_connection()
+ if self._session is None or self._session.closed:
+ connector = self.connector()
+ self._session = aiohttp.ClientSession(connector=connector)
+ response = yield from self._session.request(
method,
url,
- connector=(yield from self.connector()),
params=params,
data=data,
headers={"content-type": "application/json", },
+ timeout=timeout
)
except (aiohttp.ClientResponseError, aiohttp.ClientOSError) as e:
raise DockerError("Docker has returned an error: {}".format(str(e)))
@@ -143,11 +161,50 @@ class Docker(BaseManager):
url = "http://docker/" + path
connection = yield from aiohttp.ws_connect(url,
- connector=(yield from self.connector()),
+ connector=self.connector(),
origin="http://docker",
autoping=True)
return connection
+ @locked_coroutine
+ def pull_image(self, image, progress_callback=None):
+ """
+ Pull image from docker repository
+
+ :params image: Image name
+ :params progress_callback: A function that receive a log message about image download progress
+ """
+
+ try:
+ yield from self.query("GET", "images/{}/json".format(image))
+ return # We already have the image skip the download
+ except DockerHttp404Error:
+ pass
+
+ if progress_callback:
+ progress_callback("Pull {} from docker hub".format(image))
+ response = yield from self.http_query("POST", "images/create", params={"fromImage": image}, timeout=None)
+ # The pull api will stream status via an HTTP JSON stream
+ content = ""
+ while True:
+ chunk = yield from response.content.read(1024)
+ if not chunk:
+ break
+ content += chunk.decode("utf-8")
+
+ try:
+ while True:
+ content = content.lstrip(" \r\n\t")
+ answer, index = json.JSONDecoder().raw_decode(content)
+ if "progress" in answer and progress_callback:
+ progress_callback("Pulling image {}:{}: {}".format(image, answer["id"], answer["progress"]))
+ content = content[index:]
+ except ValueError: # Partial JSON
+ pass
+ response.close()
+ if progress_callback:
+ progress_callback("Success pulling image {}".format(image))
+
@asyncio.coroutine
def list_images(self):
"""Gets Docker image list.
diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py
index ccfbbaf8..0ac110ac 100644
--- a/gns3server/compute/docker/docker_vm.py
+++ b/gns3server/compute/docker/docker_vm.py
@@ -24,7 +24,6 @@ import shutil
import psutil
import shlex
import aiohttp
-import json
import os
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
@@ -767,26 +766,9 @@ class DockerVM(BaseNode):
"""
Pull image from docker repository
"""
- log.info("Pull %s from docker hub", image)
- response = yield from self.manager.http_query("POST", "images/create", params={"fromImage": image})
- # The pull api will stream status via an HTTP JSON stream
- content = ""
- while True:
- chunk = yield from response.content.read(1024)
- if not chunk:
- break
- content += chunk.decode("utf-8")
-
- try:
- while True:
- content = content.lstrip(" \r\n\t")
- answer, index = json.JSONDecoder().raw_decode(content)
- if "progress" in answer:
- self.project.emit("log.info", {"message": "Pulling image {}:{}: {}".format(self._image, answer["id"], answer["progress"])})
- content = content[index:]
- except ValueError: # Partial JSON
- pass
- self.project.emit("log.info", {"message": "Success pulling image {}".format(self._image)})
+ def callback(msg):
+ self.project.emit("log.info", {"message": msg})
+ yield from self.manager.pull_image(image, progress_callback=callback)
@asyncio.coroutine
def _start_ubridge_capture(self, adapter_number, output_file):
diff --git a/gns3server/compute/dynamips/nodes/ethernet_switch.py b/gns3server/compute/dynamips/nodes/ethernet_switch.py
index 52d7c4ab..5798b1e4 100644
--- a/gns3server/compute/dynamips/nodes/ethernet_switch.py
+++ b/gns3server/compute/dynamips/nodes/ethernet_switch.py
@@ -88,7 +88,7 @@ class EthernetSwitch(Device):
:param ports: ports info
"""
if ports != self._ports:
- if len(self._nios) > 0:
+ if len(self._nios) > 0 and len(ports) != len(self._ports):
raise NodeError("Can't modify a switch already connected.")
port_number = 0
@@ -99,6 +99,13 @@ class EthernetSwitch(Device):
self._ports = ports
+ @asyncio.coroutine
+ def update_port_settings(self):
+ for port_settings in self._ports:
+ port_number = port_settings["port_number"]
+ if port_number in self._nios and self._nios[port_number] is not None:
+ yield from self.set_port_settings(port_number, port_settings)
+
@asyncio.coroutine
def create(self):
diff --git a/gns3server/compute/dynamips/nodes/frame_relay_switch.py b/gns3server/compute/dynamips/nodes/frame_relay_switch.py
index 943e3d02..6e8a242a 100644
--- a/gns3server/compute/dynamips/nodes/frame_relay_switch.py
+++ b/gns3server/compute/dynamips/nodes/frame_relay_switch.py
@@ -239,10 +239,10 @@ class FrameRelaySwitch(Device):
"""
if port1 not in self._nios:
- raise DynamipsError("Port {} is not allocated".format(port1))
+ return
if port2 not in self._nios:
- raise DynamipsError("Port {} is not allocated".format(port2))
+ return
nio1 = self._nios[port1]
nio2 = self._nios[port2]
diff --git a/gns3server/compute/iou/iou_vm.py b/gns3server/compute/iou/iou_vm.py
index 200c0b20..2823e751 100644
--- a/gns3server/compute/iou/iou_vm.py
+++ b/gns3server/compute/iou/iou_vm.py
@@ -566,7 +566,7 @@ class IOUVM(BaseNode):
self._terminate_process_iou()
if returncode != 0:
- if returncode == 11:
+ if returncode == -11:
message = "{} process has stopped, return code: {}. This could be an issue with the image using a different image can fix the issue.\n{}".format(process_name, returncode, self.read_iou_stdout())
else:
message = "{} process has stopped, return code: {}\n{}".format(process_name, returncode, self.read_iou_stdout())
diff --git a/gns3server/compute/project.py b/gns3server/compute/project.py
index adcecffb..34401f82 100644
--- a/gns3server/compute/project.py
+++ b/gns3server/compute/project.py
@@ -74,7 +74,7 @@ class Project:
try:
if os.path.exists(self.tmp_working_directory()):
shutil.rmtree(self.tmp_working_directory())
- except OSError:
+ except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Could not clean project directory: {}".format(e))
log.info("Project {id} with path '{path}' created".format(path=self._path, id=self._id))
diff --git a/gns3server/compute/virtualbox/virtualbox_vm.py b/gns3server/compute/virtualbox/virtualbox_vm.py
index 77466ec9..55de04dd 100644
--- a/gns3server/compute/virtualbox/virtualbox_vm.py
+++ b/gns3server/compute/virtualbox/virtualbox_vm.py
@@ -1014,7 +1014,9 @@ class VirtualBoxVM(BaseNode):
if self.ubridge:
yield from self._ubridge_send("bridge delete {name}".format(name="VBOX-{}-{}".format(self._id, adapter_number)))
- yield from self._control_vm("setlinkstate{} off".format(adapter_number + 1))
+ vm_state = yield from self._get_vm_state()
+ if vm_state == "running":
+ yield from self._control_vm("setlinkstate{} off".format(adapter_number + 1))
else:
vm_state = yield from self._get_vm_state()
if vm_state == "running":
diff --git a/gns3server/compute/vmware/__init__.py b/gns3server/compute/vmware/__init__.py
index 54303b17..db0591d5 100644
--- a/gns3server/compute/vmware/__init__.py
+++ b/gns3server/compute/vmware/__init__.py
@@ -396,7 +396,7 @@ class VMware(BaseManager):
try:
stdout_data, _ = yield from asyncio.wait_for(process.communicate(), timeout=timeout)
except asyncio.TimeoutError:
- raise VMwareError("vmrun has timed out after {} seconds!\nTry to run {} in a terminal to see more informations.\nAnd make sure GNS3 and VMware run under the same user.".format(timeout, command_string))
+ raise VMwareError("vmrun has timed out after {} seconds!\nTry to run {} in a terminal to see more informations.\n\nMake sure GNS3 and VMware run under the same user and whitelist vmrun.exe in your antivirus.".format(timeout, command_string))
if process.returncode:
# vmrun print errors on stdout
diff --git a/gns3server/config.py b/gns3server/config.py
index 8d7ad5f3..0e4b80c4 100644
--- a/gns3server/config.py
+++ b/gns3server/config.py
@@ -50,6 +50,7 @@ class Config:
# Monitor configuration files for changes
self._watched_files = {}
+ self._watch_callback = []
if sys.platform.startswith("win"):
@@ -116,6 +117,12 @@ class Config:
self.clear()
self._watch_config_file()
+ def listen_for_config_changes(self, callback):
+ """
+ Call the callback when the configuration file change
+ """
+ self._watch_callback.append(callback)
+
@property
def profile(self):
"""
@@ -143,6 +150,8 @@ class Config:
self.read_config()
for section in self._override_config:
self.set_section_config(section, self._override_config[section])
+ for callback in self._watch_callback:
+ callback()
def reload(self):
"""
diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py
index c397d522..e916947a 100644
--- a/gns3server/controller/__init__.py
+++ b/gns3server/controller/__init__.py
@@ -16,7 +16,9 @@
# along with this program. If not, see .
import os
+import sys
import json
+import uuid
import socket
import shutil
import asyncio
@@ -55,7 +57,7 @@ class Controller:
# Store settings shared by the different GUI will be replace by dedicated API later
self._settings = None
-
+ self._local_server = None
self._config_file = os.path.join(Config.instance().config_dir, "gns3_controller.conf")
log.info("Load controller configuration file {}".format(self._config_file))
@@ -75,6 +77,7 @@ class Controller:
log.info("Start controller")
self.load_base_files()
server_config = Config.instance().get_section_config("Server")
+ Config.instance().listen_for_config_changes(self._update_config)
host = server_config.get("host", "localhost")
# If console_host is 0.0.0.0 client will use the ip they use
@@ -88,15 +91,19 @@ class Controller:
name = "Main server"
computes = yield from self._load_controller_settings()
- yield from self.add_compute(compute_id="local",
- name=name,
- protocol=server_config.get("protocol", "http"),
- host=host,
- console_host=console_host,
- port=server_config.getint("port", 3080),
- user=server_config.get("user", ""),
- password=server_config.get("password", ""),
- force=True)
+ try:
+ self._local_server = yield from self.add_compute(compute_id="local",
+ name=name,
+ protocol=server_config.get("protocol", "http"),
+ host=host,
+ console_host=console_host,
+ port=server_config.getint("port", 3080),
+ user=server_config.get("user", ""),
+ password=server_config.get("password", ""),
+ force=True)
+ except aiohttp.web_exceptions.HTTPConflict as e:
+ log.fatal("Can't acces to the local server, make sure anything else is not running on the same port")
+ sys.exit(1)
for c in computes:
try:
yield from self.add_compute(**c)
@@ -106,6 +113,16 @@ class Controller:
yield from self.gns3vm.auto_start_vm()
yield from self._project_auto_open()
+ def _update_config(self):
+ """
+ Call this when the server configuration file
+ change
+ """
+ if self._local_server:
+ server_config = Config.instance().get_section_config("Server")
+ self._local_server.user = server_config.get("user")
+ self._local_server.password = server_config.get("password")
+
@asyncio.coroutine
def stop(self):
log.info("Stop controller")
@@ -239,14 +256,17 @@ class Controller:
data = json.load(f)
server_settings = data.get("Servers", {})
for remote in server_settings.get("remote_servers", []):
- yield from self.add_compute(
- host=remote.get("host", "localhost"),
- port=remote.get("port", 3080),
- protocol=remote.get("protocol", "http"),
- name=remote.get("url"),
- user=remote.get("user"),
- password=remote.get("password")
- )
+ try:
+ yield from self.add_compute(
+ host=remote.get("host", "localhost"),
+ port=remote.get("port", 3080),
+ protocol=remote.get("protocol", "http"),
+ name=remote.get("url"),
+ user=remote.get("user"),
+ password=remote.get("password")
+ )
+ except aiohttp.web.HTTPConflict:
+ pass # if the server is broken we skip it
if "vm" in server_settings:
vmname = None
vm_settings = server_settings["vm"]
@@ -282,12 +302,12 @@ class Controller:
"""
Store settings shared by the different GUI will be replace by dedicated API later. Dictionnary
"""
- assert self._settings is not None
return self._settings
@settings.setter
def settings(self, val):
self._settings = val
+ self._settings["modification_uuid"] = str(uuid.uuid4()) # We add a modification id to the settings it's help the gui to detect changes
self.save()
self.notification.emit("settings.updated", val)
diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py
index 85f10575..03e03257 100644
--- a/gns3server/controller/compute.py
+++ b/gns3server/controller/compute.py
@@ -128,7 +128,7 @@ class Compute:
self._user = user.strip()
if password:
self._password = password.strip()
- self._auth = aiohttp.BasicAuth(self._user, self._password)
+ self._auth = aiohttp.BasicAuth(self._user, self._password, "utf-8")
else:
self._password = None
self._auth = aiohttp.BasicAuth(self._user, "")
@@ -397,6 +397,8 @@ class Compute:
raise aiohttp.web.HTTPConflict(text="Invalid auth for server {}".format(self._id))
except aiohttp.web.HTTPServiceUnavailable:
raise aiohttp.web.HTTPConflict(text="The server {} is unavailable".format(self._id))
+ except ValueError:
+ raise aiohttp.web.HTTPConflict(text="Invalid server url for server {}".format(self._id))
if "version" not in response.json:
self._http_session.close()
@@ -502,7 +504,7 @@ class Compute:
response = yield from self._session().request(method, url, headers=headers, data=data, auth=self._auth, chunked=chunked, timeout=timeout)
except asyncio.TimeoutError as e:
raise ComputeError("Timeout error when connecting to {}".format(url))
- except (aiohttp.errors.ClientOSError, aiohttp.errors.ClientRequestError, aiohttp.ClientResponseError) as e:
+ except (aiohttp.errors.ClientOSError, aiohttp.errors.ClientRequestError, aiohttp.errors.ServerDisconnectedError, aiohttp.ClientResponseError, ValueError) as e:
raise ComputeError(str(e))
body = yield from response.read()
if body and not raw:
diff --git a/gns3server/controller/export_project.py b/gns3server/controller/export_project.py
index 1cc93a12..6f3f6556 100644
--- a/gns3server/controller/export_project.py
+++ b/gns3server/controller/export_project.py
@@ -191,3 +191,5 @@ def _export_images(project, image, z):
arcname = os.path.join("images", directory, os.path.basename(image))
z.write(path, arcname)
break
+ else:
+ raise aiohttp.web.HTTPConflict(text="Topology could not be exported because the image {} is not available. If you use multiple server, we need a copy of the image on the main server.".format(path))
diff --git a/gns3server/controller/import_project.py b/gns3server/controller/import_project.py
index a29ff363..63dd4507 100644
--- a/gns3server/controller/import_project.py
+++ b/gns3server/controller/import_project.py
@@ -75,7 +75,10 @@ def import_project(controller, project_id, stream, location=None, name=None, kee
else:
projects_path = controller.projects_directory()
path = os.path.join(projects_path, project_name)
- os.makedirs(path, exist_ok=True)
+ try:
+ os.makedirs(path, exist_ok=True)
+ except UnicodeEncodeError as e:
+ raise aiohttp.web.HTTPConflict(text="The project name contain non supported or invalid characters")
myzip.extractall(path)
topology = load_topology(os.path.join(path, "project.gns3"))
diff --git a/gns3server/controller/link.py b/gns3server/controller/link.py
index 03c5f12c..90ec12fc 100644
--- a/gns3server/controller/link.py
+++ b/gns3server/controller/link.py
@@ -18,6 +18,7 @@
import os
import re
import uuid
+import html
import asyncio
import aiohttp
@@ -83,7 +84,7 @@ class Link:
"x": -10,
"y": -10,
"rotation": 0,
- "text": "{}/{}".format(adapter_number, port_number),
+ "text": html.escape("{}/{}".format(adapter_number, port_number)),
"style": "font-size: 10; font-style: Verdana"
}
diff --git a/gns3server/controller/node.py b/gns3server/controller/node.py
index 49337325..d43c3be6 100644
--- a/gns3server/controller/node.py
+++ b/gns3server/controller/node.py
@@ -17,6 +17,7 @@
import aiohttp
import asyncio
+import html
import copy
import uuid
import os
@@ -238,7 +239,7 @@ class Node:
self._label = {
"y": round(self._height / 2 + 10) * -1,
- "text": self._name,
+ "text": html.escape(self._name),
"style": style,
"x": None, # None: mean the client should center it
"rotation": 0
diff --git a/gns3server/controller/ports/port.py b/gns3server/controller/ports/port.py
index a44e7f99..b801ddbf 100644
--- a/gns3server/controller/ports/port.py
+++ b/gns3server/controller/ports/port.py
@@ -66,7 +66,7 @@ class Port:
# If port name format has change we use the port name as the short name (1.X behavior)
if self._short_name:
return self._short_name
- elif not self._name.startswith(self.long_name_type()):
+ elif not self._name.startswith("{}{}".format(self.long_name_type(), self._interface_number)):
return self._name
return self.short_name_type + "{}/{}".format(self._interface_number, self._port_number)
diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py
index c6caa7bf..6622145f 100644
--- a/gns3server/controller/project.py
+++ b/gns3server/controller/project.py
@@ -637,7 +637,7 @@ class Project:
for node in topology.get("nodes", []):
compute = self.controller.get_compute(node.pop("compute_id"))
name = node.pop("name")
- node_id = node.pop("node_id")
+ node_id = node.pop("node_id", str(uuid.uuid4()))
yield from self.add_node(compute, name, node_id, dump=False, **node)
for link_data in topology.get("links", []):
link = yield from self.add_link(link_id=link_data["link_id"])
@@ -663,7 +663,10 @@ class Project:
pass
self._status = "closed"
self._loading = False
- raise e
+ if isinstance(e, ComputeError):
+ raise aiohttp.web.HTTPConflict(text=str(e))
+ else:
+ raise e
try:
os.remove(path + ".backup")
except OSError:
@@ -699,6 +702,7 @@ class Project:
if self._status == "closed":
yield from self.open()
+ self.dump()
try:
with tempfile.TemporaryDirectory() as tmpdir:
zipstream = yield from export_project(self, tmpdir, keep_compute_id=True, allow_all_nodes=True)
diff --git a/gns3server/controller/topology.py b/gns3server/controller/topology.py
index bdb1a318..10e4de6a 100644
--- a/gns3server/controller/topology.py
+++ b/gns3server/controller/topology.py
@@ -16,6 +16,7 @@
# along with this program. If not, see .
import os
+import html
import json
import copy
import uuid
@@ -285,7 +286,10 @@ def _convert_1_3_later(topo, topo_path):
for old_node in topo.get("nodes", []):
node = {}
node["console"] = old_node["properties"].get("console", None)
- node["compute_id"] = server_id_to_compute_id[old_node["server_id"]]
+ try:
+ node["compute_id"] = server_id_to_compute_id[old_node["server_id"]]
+ except KeyError:
+ node["compute_id"] = "local"
node["console_type"] = old_node["properties"].get("console_type", "telnet")
node["name"] = old_node["label"]["text"]
node["label"] = _convert_label(old_node["label"])
@@ -376,9 +380,11 @@ def _convert_1_3_later(topo, topo_path):
node["symbol"] = ":/symbols/router.svg"
elif old_node["type"] == "Cloud":
- old_node["ports"] = _create_cloud(node, old_node, ":/symbols/cloud.svg")
+ symbol = old_node.get("symbol", ":/symbols/cloud.svg")
+ old_node["ports"] = _create_cloud(node, old_node, symbol)
elif old_node["type"] == "Host":
- old_node["ports"] = _create_cloud(node, old_node, ":/symbols/computer.svg")
+ symbol = old_node.get("symbol", ":/symbols/computer.svg")
+ old_node["ports"] = _create_cloud(node, old_node, symbol)
else:
raise NotImplementedError("Conversion of {} is not supported".format(old_node["type"]))
@@ -463,7 +469,7 @@ def _convert_1_3_later(topo, topo_path):
size=int(font_info[1]),
weight=weight,
style=style,
- text=note["text"]
+ text=html.escape(note["text"])
)
new_note = {
"drawing_id": str(uuid.uuid4()),
@@ -550,7 +556,7 @@ def _convert_label(label):
"""
style = qt_font_to_style(label.get("font"), label.get("color"))
return {
- "text": label["text"],
+ "text": html.escape(label["text"]),
"rotation": 0,
"style": style,
"x": int(label["x"]),
diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py
index d5e350a5..defbe8e1 100644
--- a/gns3server/crash_report.py
+++ b/gns3server/crash_report.py
@@ -54,7 +54,7 @@ class CrashReport:
Report crash to a third party service
"""
- DSN = "sync+https://5b834577b69a4b77b112f020412237b5:b648d289253740daad5c08a939ceffd7@sentry.io/38482"
+ DSN = "sync+https://7c028290d17b4035916285b304d42311:ddf752e704c7423cacab93f8e34f713c@sentry.io/38482"
if hasattr(sys, "frozen"):
cacert = get_resource("cacert.pem")
if cacert is not None and os.path.isfile(cacert):
diff --git a/gns3server/handlers/api/compute/ethernet_switch_handler.py b/gns3server/handlers/api/compute/ethernet_switch_handler.py
index 72a05107..608e5121 100644
--- a/gns3server/handlers/api/compute/ethernet_switch_handler.py
+++ b/gns3server/handlers/api/compute/ethernet_switch_handler.py
@@ -54,10 +54,10 @@ class EthernetSwitchHandler:
# Use the Dynamips Ethernet switch to simulate this node
dynamips_manager = Dynamips.instance()
node = yield from dynamips_manager.create_node(request.json.pop("name"),
- request.match_info["project_id"],
- request.json.get("node_id"),
- node_type="ethernet_switch",
- ports=request.json.get("ports_mapping"))
+ request.match_info["project_id"],
+ request.json.get("node_id"),
+ node_type="ethernet_switch",
+ ports=request.json.get("ports_mapping"))
# On Linux, use the generic switch
# builtin_manager = Builtin.instance()
@@ -114,6 +114,7 @@ class EthernetSwitchHandler:
yield from node.set_name(request.json["name"])
if "ports_mapping" in request.json:
node.ports_mapping = request.json["ports_mapping"]
+ yield from node.update_port_settings()
# builtin_manager = Builtin.instance()
# node = builtin_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
diff --git a/gns3server/handlers/api/compute/virtualbox_handler.py b/gns3server/handlers/api/compute/virtualbox_handler.py
index f7ee4b45..5e74592d 100644
--- a/gns3server/handlers/api/compute/virtualbox_handler.py
+++ b/gns3server/handlers/api/compute/virtualbox_handler.py
@@ -22,6 +22,7 @@ from gns3server.web.route import Route
from gns3server.schemas.nio import NIO_SCHEMA
from gns3server.schemas.node import NODE_CAPTURE_SCHEMA
from gns3server.compute.virtualbox import VirtualBox
+from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError
from gns3server.compute.project_manager import ProjectManager
from gns3server.schemas.virtualbox import (
@@ -116,9 +117,15 @@ class VirtualBoxHandler:
name = request.json.pop("name")
vmname = request.json.pop("vmname", None)
if name != vm.name:
+ oldname = vm.name
vm.name = name
if vm.linked_clone:
- yield from vm.set_vmname(vm.name)
+ try:
+ yield from vm.set_vmname(vm.name)
+ except VirtualBoxError as e: # In case of error we rollback (we can't change the name when running)
+ vm.name = oldname
+ vm.updated()
+ raise e
if "adapters" in request.json:
adapters = int(request.json.pop("adapters"))
diff --git a/gns3server/handlers/api/controller/server_handler.py b/gns3server/handlers/api/controller/server_handler.py
index f6551550..a0208a69 100644
--- a/gns3server/handlers/api/controller/server_handler.py
+++ b/gns3server/handlers/api/controller/server_handler.py
@@ -103,7 +103,15 @@ class ServerHandler:
description="Retrieve gui settings from the server. Temporary will we removed in later release")
def read_settings(request, response):
- response.json(Controller.instance().settings)
+ settings = None
+ while True:
+ # The init of the server could take some times
+ # we ensure settings are loaded before returning them
+ settings = Controller.instance().settings
+ if settings is not None:
+ break
+ yield from asyncio.sleep(0.5)
+ response.json(settings)
@Route.post(
r"/settings",
@@ -113,6 +121,8 @@ class ServerHandler:
})
def write_settings(request, response):
controller = Controller.instance()
+ if controller.settings is None: # Server is not loaded ignore settings update to prevent buggy client sync issue
+ return
controller.settings = request.json
try:
controller.save()
diff --git a/gns3server/handlers/api/controller/symbol_handler.py b/gns3server/handlers/api/controller/symbol_handler.py
index ac225233..7122a2e3 100644
--- a/gns3server/handlers/api/controller/symbol_handler.py
+++ b/gns3server/handlers/api/controller/symbol_handler.py
@@ -49,7 +49,7 @@ class SymbolHandler:
controller = Controller.instance()
try:
yield from response.file(controller.symbols.get_path(request.match_info["symbol_id"]))
- except (KeyError, FileNotFoundError):
+ except (KeyError, FileNotFoundError, PermissionError):
response.set_status(404)
@Route.post(
diff --git a/gns3server/run.py b/gns3server/run.py
index 41421b17..ccfb1a9d 100644
--- a/gns3server/run.py
+++ b/gns3server/run.py
@@ -26,9 +26,7 @@ import datetime
import sys
import locale
import argparse
-import shutil
import psutil
-import asyncio
from gns3server.web.web_server import WebServer
@@ -107,7 +105,6 @@ def parse_arguments(argv):
parser.add_argument("--daemon", action="store_true", help="start as a daemon")
parser.add_argument("--pid", help="store process pid")
parser.add_argument("--profile", help="Settings profile (blank will use default settings files)")
- parser.add_argument("--discovery", action="store_true", help="Make server discoverable on the network")
args = parser.parse_args(argv)
if args.config:
@@ -128,8 +125,7 @@ def parse_arguments(argv):
"allow": config.getboolean("allow_remote_console", False),
"quiet": config.getboolean("quiet", False),
"debug": config.getboolean("debug", False),
- "logfile": config.getboolean("logfile", ""),
- "server_discovery": config.getboolean("server_discovery", False)
+ "logfile": config.getboolean("logfile", "")
}
parser.set_defaults(**defaults)
diff --git a/gns3server/ubridge/hypervisor.py b/gns3server/ubridge/hypervisor.py
index 452e2524..1e6ae825 100644
--- a/gns3server/ubridge/hypervisor.py
+++ b/gns3server/ubridge/hypervisor.py
@@ -174,7 +174,7 @@ class Hypervisor(UBridgeHypervisor):
except (OSError, PermissionError, subprocess.SubprocessError) as e:
ubridge_stdout = self.read_stdout()
log.error("Could not start ubridge: {}\n{}".format(e, ubridge_stdout))
- raise UBridgeHypervisor("Could not start ubridge: {}\n{}".format(e, ubridge_stdout))
+ raise UbridgeError("Could not start ubridge: {}\n{}".format(e, ubridge_stdout))
def _termination_callback(self, returncode):
"""
@@ -201,7 +201,10 @@ class Hypervisor(UBridgeHypervisor):
except asyncio.TimeoutError:
if self._process.returncode is None:
log.warn("uBridge process {} is still running... killing it".format(self._process.pid))
- self._process.kill()
+ try:
+ self._process.kill()
+ except ProcessLookupError:
+ pass
if self._stdout_file and os.access(self._stdout_file, os.W_OK):
try:
diff --git a/gns3server/utils/images.py b/gns3server/utils/images.py
index fd867aa6..0f7bc8f5 100644
--- a/gns3server/utils/images.py
+++ b/gns3server/utils/images.py
@@ -58,7 +58,7 @@ def list_images(type):
if filename.endswith(".md5sum") or filename.startswith("."):
continue
elif ((filename.endswith(".image") or filename.endswith(".bin")) and type == "dynamips") \
- or (filename.endswith(".bin") and type == "iou") \
+ or ((filename.endswith(".bin") or filename.startswith("i86bi")) and type == "iou") \
or (not filename.endswith(".bin") and not filename.endswith(".image") and type == "qemu"):
files.add(filename)
diff --git a/gns3server/utils/picture.py b/gns3server/utils/picture.py
index 0fd740d8..50d17996 100644
--- a/gns3server/utils/picture.py
+++ b/gns3server/utils/picture.py
@@ -99,8 +99,8 @@ def get_size(data, default_width=0, default_height=0):
root = tree.getroot()
try:
- width = _svg_convert_size(root.attrib["width"])
- height = _svg_convert_size(root.attrib["height"])
+ width = _svg_convert_size(root.attrib.get("width", "0"))
+ height = _svg_convert_size(root.attrib.get("height", "0"))
except IndexError:
raise ValueError("Invalid SVG file")
diff --git a/gns3server/web/route.py b/gns3server/web/route.py
index 3f5a153c..7c06952b 100644
--- a/gns3server/web/route.py
+++ b/gns3server/web/route.py
@@ -21,7 +21,6 @@ import urllib
import asyncio
import aiohttp
import logging
-import urllib
import traceback
import jsonschema
@@ -114,7 +113,7 @@ class Route(object):
return
if "AUTHORIZATION" in request.headers:
- if request.headers["AUTHORIZATION"] == aiohttp.helpers.BasicAuth(user, password).encode():
+ if request.headers["AUTHORIZATION"] == aiohttp.helpers.BasicAuth(user, password, "utf-8").encode():
return
log.error("Invalid auth. Username should %s", user)
diff --git a/gns3server/web/web_server.py b/gns3server/web/web_server.py
index bccb3083..1e8bd1b8 100644
--- a/gns3server/web/web_server.py
+++ b/gns3server/web/web_server.py
@@ -22,11 +22,7 @@ Set up and run the server.
import os
import sys
import signal
-import socket
-import json
-import ipaddress
import asyncio
-import threading
import aiohttp
import aiohttp_cors
import functools
@@ -38,7 +34,6 @@ from ..config import Config
from ..compute import MODULES
from ..compute.port_manager import PortManager
from ..controller import Controller
-from ..version import __version__
# do not delete this import
@@ -191,63 +186,12 @@ class WebServer:
atexit.register(close_asyncio_loop)
- def _udp_server_discovery(self):
+ @asyncio.coroutine
+ def _on_startup(self, *args):
"""
- UDP multicast and broadcast server discovery (Linux only)
+ Called when the HTTP server start
"""
-
- import ctypes
- uint32_t = ctypes.c_uint32
- in_addr_t = uint32_t
-
- class in_addr(ctypes.Structure):
- _fields_ = [('s_addr', in_addr_t)]
-
- class in_pktinfo(ctypes.Structure):
- _fields_ = [('ipi_ifindex', ctypes.c_int),
- ('ipi_spec_dst', in_addr),
- ('ipi_addr', in_addr)]
-
- IP_PKTINFO = 8
- with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
- membership = socket.inet_aton("239.42.42.1") + socket.inet_aton("0.0.0.0")
- sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, membership)
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
- sock.setsockopt(socket.SOL_IP, IP_PKTINFO, 1)
- try:
- sock.bind(("", self._port))
- except OSError as e:
- log.error("UDP server discovery could not bind on port {}: {}".format(self._port, e))
- return
-
- log.info("UDP server discovery started on port {}".format(self._port))
- while self._loop.is_running():
- try:
- data, ancdata, _, address = sock.recvmsg(255, socket.CMSG_LEN(255))
- except OSError as e:
- log.error("Error while receiving UDP server discovery request: {}".format(e))
- continue
- cmsg_level, cmsg_type, cmsg_data = ancdata[0]
- if cmsg_level == socket.SOL_IP and cmsg_type == IP_PKTINFO:
- pktinfo = in_pktinfo.from_buffer_copy(cmsg_data)
- request_address = ipaddress.IPv4Address(memoryview(pktinfo.ipi_addr).tobytes())
- receiving_interface = socket.if_indextoname(pktinfo.ipi_ifindex)
- log.debug("UDP server discovery request received on {} using {}".format(receiving_interface,
- request_address))
- local_address = ipaddress.IPv4Address(memoryview(pktinfo.ipi_spec_dst).tobytes())
- if self._host != "0.0.0.0" and self._host != str(local_address):
- log.debug("Ignoring UDP discovery request received on {} instead of {}".format(local_address,
- self._host))
- continue
- server_info = {"version": __version__,
- "ip": str(local_address),
- "port": self._port}
- data = json.dumps(server_info)
- sock.sendto(data.encode(), address)
- log.debug("Sent server info to {}:{} {}".format(address[0], address[1], data))
- time.sleep(1) # this is to prevent too many request to slow down the server
- log.debug("UDP server discovery stopped")
+ yield from Controller.instance().start()
def run(self):
"""
@@ -288,8 +232,9 @@ class WebServer:
for key, val in os.environ.items():
log.debug("ENV %s=%s", key, val)
- self._loop.run_until_complete(Controller.instance().start())
self._app = aiohttp.web.Application()
+ # Background task started with the server
+ self._app.on_startup.append(self._on_startup)
# Allow CORS for this domains
cors = aiohttp_cors.setup(self._app, defaults={
@@ -322,11 +267,6 @@ class WebServer:
if server_config.getboolean("shell"):
asyncio.async(self.start_shell())
- if sys.platform.startswith("linux") and server_config.getboolean("server_discovery"):
- # UDP discovery is only supported on Linux
- udp_server_discovery = threading.Thread(target=self._udp_server_discovery, daemon=True)
- udp_server_discovery.start()
-
try:
self._loop.run_forever()
except TypeError as e:
diff --git a/requirements.txt b/requirements.txt
index c5400455..21a43549 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
jsonschema>=2.4.0
-aiohttp>=1.3.0,<=1.4.0
-aiohttp_cors>=0.4.0
-yarl>=0.9.8
+aiohttp>=1.3.5,<=1.4.0 # pyup: ignore
+aiohttp-cors==0.5.1 # pyup: ignore
+yarl>=0.9.8,<0.10 # pyup: ignore
typing>=3.5.3.0 # Otherwise yarl fail with python 3.4
Jinja2>=2.7.3
raven>=5.23.0
diff --git a/scripts/remote-install.sh b/scripts/remote-install.sh
index c89f40fb..260c8d8d 100644
--- a/scripts/remote-install.sh
+++ b/scripts/remote-install.sh
@@ -31,9 +31,7 @@ function help {
}
function log {
- tput setaf 2
echo "=> $1" >&2
- tput sgr0
}
lsb_release -d | grep "LTS" > /dev/null
diff --git a/scripts/run_on_gns3vm.sh b/scripts/run_on_gns3vm.sh
new file mode 100755
index 00000000..4bde8eb0
--- /dev/null
+++ b/scripts/run_on_gns3vm.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# This script will push current dev to a GNS3 VM and
+# will also start the server in console
+
+SERVER_ADDRESS=$1
+
+if [ "$SERVER_ADDRESS" == "" ]
+then
+ echo "usage: run_on_gns3vm.sh VM_IP"
+ exit 1
+fi
+
+ssh gns3@$SERVER_ADDRESS "sudo service gns3 stop"
+rsync -avz --exclude==".git/*" --exclude=='docs/*' --exclude="__pycache__" --exclude=='tests/*' . "gns3@$SERVER_ADDRESS:gns3server"
+
+ssh gns3@$SERVER_ADDRESS "killall python3;cd gns3server;python3 -m gns3server"
diff --git a/setup.py b/setup.py
index cdb37d9c..02663755 100644
--- a/setup.py
+++ b/setup.py
@@ -20,7 +20,7 @@ from setuptools import setup, find_packages
from setuptools.command.test import test as TestCommand
# we only support Python 3 version >= 3.4
-if sys.version_info < (3, 4):
+if len(sys.argv) >= 2 and sys.argv[1] == "install" and sys.version_info < (3, 4):
raise SystemExit("Python 3.4 or higher is required")
diff --git a/tests/compute/docker/test_docker.py b/tests/compute/docker/test_docker.py
index 79523543..25779ca6 100644
--- a/tests/compute/docker/test_docker.py
+++ b/tests/compute/docker/test_docker.py
@@ -19,17 +19,17 @@ import pytest
import asyncio
from unittest.mock import MagicMock
-from tests.utils import asyncio_patch
+from tests.utils import asyncio_patch, AsyncioMagicMock
from gns3server.compute.docker import Docker
-from gns3server.compute.docker.docker_error import DockerError
+from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Error
@pytest.fixture
def vm():
vm = Docker()
vm._connected = True
- vm._connector = MagicMock()
- vm._connector.closed = False
+ vm._session = MagicMock()
+ vm._session.closed = False
return vm
@@ -44,14 +44,14 @@ def test_query_success(loop, vm):
return b'{"c": false}'
response.read.side_effect = read
- with asyncio_patch("aiohttp.request", return_value=response) as mock:
- data = loop.run_until_complete(asyncio.async(vm.query("POST", "test", data={"a": True}, params={"b": 1})))
- mock.assert_called_with('POST',
- 'http://docker/test',
- connector=vm._connector,
- data='{"a": true}',
- headers={'content-type': 'application/json'},
- params={'b': 1})
+ vm._session.request = AsyncioMagicMock(return_value=response)
+ data = loop.run_until_complete(asyncio.async(vm.query("POST", "test", data={"a": True}, params={"b": 1})))
+ vm._session.request.assert_called_with('POST',
+ 'http://docker/test',
+ data='{"a": true}',
+ headers={'content-type': 'application/json'},
+ params={'b': 1},
+ timeout=300)
assert data == {"c": False}
@@ -66,15 +66,15 @@ def test_query_error(loop, vm):
return b"NOT FOUND"
response.read.side_effect = read
- with asyncio_patch("aiohttp.request", return_value=response) as mock:
- with pytest.raises(DockerError):
- data = loop.run_until_complete(asyncio.async(vm.query("POST", "test", data={"a": True}, params={"b": 1})))
- mock.assert_called_with('POST',
- 'http://docker/test',
- connector=vm._connector,
- data='{"a": true}',
- headers={'content-type': 'application/json'},
- params={'b': 1})
+ vm._session.request = AsyncioMagicMock(return_value=response)
+ with pytest.raises(DockerError):
+ data = loop.run_until_complete(asyncio.async(vm.query("POST", "test", data={"a": True}, params={"b": 1})))
+ vm._session.request.assert_called_with('POST',
+ 'http://docker/test',
+ data='{"a": true}',
+ headers={'content-type': 'application/json'},
+ params={'b': 1},
+ timeout=300)
def test_query_error_json(loop, vm):
@@ -87,15 +87,15 @@ def test_query_error_json(loop, vm):
return b'{"message": "Error"}'
response.read.side_effect = read
- with asyncio_patch("aiohttp.request", return_value=response) as mock:
- with pytest.raises(DockerError):
- data = loop.run_until_complete(asyncio.async(vm.query("POST", "test", data={"a": True}, params={"b": 1})))
- mock.assert_called_with('POST',
- 'http://docker/test',
- connector=vm._connector,
- data='{"a": true}',
- headers={'content-type': 'application/json'},
- params={'b': 1})
+ vm._session.request = AsyncioMagicMock(return_value=response)
+ with pytest.raises(DockerError):
+ data = loop.run_until_complete(asyncio.async(vm.query("POST", "test", data={"a": True}, params={"b": 1})))
+ vm._session.request.assert_called_with('POST',
+ 'http://docker/test',
+ data='{"a": true}',
+ headers={'content-type': 'application/json'},
+ params={'b': 1},
+ timeout=300)
def test_list_images(loop):
@@ -134,3 +134,31 @@ def test_list_images(loop):
assert {"image": "ubuntu:latest"} in images
assert {"image": "ubuntu:12.10"} in images
assert {"image": "ubuntu:quantal"} in images
+
+
+def test_pull_image(loop):
+ class Response:
+ """
+ Simulate a response splitted in multiple packets
+ """
+
+ def __init__(self):
+ self._read = -1
+
+ @asyncio.coroutine
+ def read(self, size):
+ self._read += 1
+ if self._read == 0:
+ return b'{"progress": "0/100",'
+ elif self._read == 1:
+ return '"id": 42}'
+ else:
+ None
+
+ mock_query = MagicMock()
+ mock_query.content.return_value = Response()
+
+ with asyncio_patch("gns3server.compute.docker.Docker.query", side_effect=DockerHttp404Error("404")):
+ with asyncio_patch("gns3server.compute.docker.Docker.http_query", return_value=mock_query) as mock:
+ images = loop.run_until_complete(asyncio.async(Docker.instance().pull_image("ubuntu")))
+ mock.assert_called_with("POST", "images/create", params={"fromImage": "ubuntu"}, timeout=None)
diff --git a/tests/compute/docker/test_docker_vm.py b/tests/compute/docker/test_docker_vm.py
index d55b411e..70517b5b 100644
--- a/tests/compute/docker/test_docker_vm.py
+++ b/tests/compute/docker/test_docker_vm.py
@@ -795,33 +795,6 @@ def test_adapter_remove_nio_binding_invalid_adapter(vm, loop):
loop.run_until_complete(asyncio.async(vm.adapter_remove_nio_binding(12)))
-def test_pull_image(loop, vm):
- class Response:
- """
- Simulate a response splitted in multiple packets
- """
-
- def __init__(self):
- self._read = -1
-
- @asyncio.coroutine
- def read(self, size):
- self._read += 1
- if self._read == 0:
- return b'{"progress": "0/100",'
- elif self._read == 1:
- return '"id": 42}'
- else:
- None
-
- mock_query = MagicMock()
- mock_query.content.return_value = Response()
-
- with asyncio_patch("gns3server.compute.docker.Docker.http_query", return_value=mock_query) as mock:
- images = loop.run_until_complete(asyncio.async(vm.pull_image("ubuntu")))
- mock.assert_called_with("POST", "images/create", params={"fromImage": "ubuntu"})
-
-
def test_start_capture(vm, tmpdir, manager, free_console_port, loop):
output_file = str(tmpdir / "test.pcap")
diff --git a/tests/controller/test_controller.py b/tests/controller/test_controller.py
index f27b712b..f734300f 100644
--- a/tests/controller/test_controller.py
+++ b/tests/controller/test_controller.py
@@ -192,7 +192,8 @@ def test_import_remote_gns3vm_1_x(controller, controller_config_path, async_run)
def test_settings(controller):
controller._notification = MagicMock()
controller.settings = {"a": 1}
- controller._notification.emit.assert_called_with("settings.updated", {"a": 1})
+ controller._notification.emit.assert_called_with("settings.updated", controller.settings)
+ assert controller.settings["modification_uuid"] is not None
def test_load_projects(controller, projects_dir, async_run):
diff --git a/tests/handlers/api/controller/test_settings.py b/tests/handlers/api/controller/test_settings.py
index 2bc52f39..a87df472 100644
--- a/tests/handlers/api/controller/test_settings.py
+++ b/tests/handlers/api/controller/test_settings.py
@@ -29,4 +29,5 @@ def test_settings(http_controller):
assert response.status == 201
response = http_controller.get('/settings', example=True)
assert response.status == 200
- assert response.json == query
+ assert response.json["test"] is True
+ assert response.json["modification_uuid"] is not None