Merge ~jocave/checkbox-support:add-snap-connect-script into checkbox-support:master

Proposed by Jonathan Cave
Status: Merged
Approved by: Jonathan Cave
Approved revision: 3e1a43b7d95af67d5b2689f8d5a7e58721442960
Merged at revision: 87cf772f3b95fb543f86111b0a857fcca94aaebc
Proposed branch: ~jocave/checkbox-support:add-snap-connect-script
Merge into: checkbox-support:master
Diff against target: 148 lines (+131/-0)
2 files modified
checkbox_support/scripts/snap_connect.py (+129/-0)
setup.py (+2/-0)
Reviewer Review Type Date Requested Status
Devices Certification Bot Needs Fixing
Paul Larson Approve
Review via email: mp+355450@code.launchpad.net

Description of the change

Create reusable version of snap_connect.py script that has previously been copied throughout project specific providers.

Tested in plano project.

To post a comment you must log in.
Revision history for this message
Paul Larson (pwlars) wrote :

+1

review: Approve
Revision history for this message
Devices Certification Bot (ce-certification-qa) wrote :

The merge was fine but running tests failed.

[trusty] starting container
[trusty] (timing) 0.00user 0.03system 0:30.34elapsed 0%CPU (0avgtext+0avgdata 5020maxresident)k
[trusty] (timing) 0inputs+80outputs (0major+1163minor)pagefaults 0swaps
[trusty] provisioning container
[trusty] (timing) 72.01user 104.30system 8:40.70elapsed 33%CPU (0avgtext+0avgdata 68700maxresident)k
[trusty] (timing) 8inputs+1609704outputs (16major+1279757minor)pagefaults 0swaps
[trusty-testing] Starting tests...
Found a test script: ./requirements/container-tests-checkbox-support
[trusty-testing] container-tests-checkbox-support: PASS
[trusty-testing] (timing) 14.23user 0.10system 0:44.61elapsed 32%CPU (0avgtext+0avgdata 129388maxresident)k
[trusty-testing] (timing) 0inputs+904outputs (0major+127407minor)pagefaults 0swaps
[trusty-testing] Fixing file permissions in source directory
[trusty-testing] Destroying container
Name: trusty-testing
State: STOPPED
[xenial] starting container
[xenial] Unable to start ephemeral container!
[xenial] stdout:
[xenial] stderr: https://paste.ubuntu.com/p/BBnS2RfMXN/
[xenial] NOTE: unable to execute tests, marked as failed
[xenial] Destroying failed container to reclaim resources
Destroyed container xenial-testing
[bionic] starting container
[bionic] (timing) 0.00user 0.01system 0:30.40elapsed 0%CPU (0avgtext+0avgdata 4996maxresident)k
[bionic] (timing) 0inputs+80outputs (0major+1163minor)pagefaults 0swaps
[bionic] provisioning container
[bionic] (timing) 37.15user 16.74system 6:51.66elapsed 13%CPU (0avgtext+0avgdata 89416maxresident)k
[bionic] (timing) 0inputs+2193096outputs (0major+1956724minor)pagefaults 0swaps
[bionic-testing] Starting tests...
Found a test script: ./requirements/container-tests-checkbox-support
[bionic-testing] container-tests-checkbox-support: PASS
[bionic-testing] (timing) 12.57user 0.18system 0:45.42elapsed 28%CPU (0avgtext+0avgdata 130904maxresident)k
[bionic-testing] (timing) 0inputs+2832outputs (0major+134360minor)pagefaults 0swaps
[bionic-testing] Fixing file permissions in source directory
[bionic-testing] Destroying container
Name: bionic-testing
State: STOPPED

review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/checkbox_support/scripts/snap_connect.py b/checkbox_support/scripts/snap_connect.py
0new file mode 1006440new file mode 100644
index 0000000..7e8fac0
--- /dev/null
+++ b/checkbox_support/scripts/snap_connect.py
@@ -0,0 +1,129 @@
1#!/usr/bin/env python3
2# Copyright 2017 Canonical Ltd.
3# All rights reserved.
4#
5# Written by:
6# Jonathan Cave <jonathan.cave@canonical.com>
7# Maciej Kisielewski <maciej.kisielewski@canonical.com>
8
9"""
10This program connects snap plugs and lists connections between snaps.
11
12The syntax of program parameters is A:B:C, where :
13
14 A - plug to be connected
15 B - target snap (snap the plug will connect to)
16 C - target slot (slot to connect to)
17
18 Note that originating snap is implied. $SNAP_NAME is used.
19
20Example:
21 $ sudo ./snap_connect.py udisks2:udisks2:service
22
23running
24 $ sudo ./snap_connect.py A:B:C
25is equivalent to:
26 $ snap connect $SNAP_NAME:A B:C
27
28 Note that the program needs sudo if asked to connect plugs.
29"""
30
31import argparse
32import json
33import logging
34import requests_unixsocket
35import os
36import sys
37import time
38from collections import namedtuple
39
40
41Connection = namedtuple(
42 'Connection',
43 ['target_snap', 'target_slot', 'plug_snap', 'plug_plug'])
44
45
46class BadRequest(Exception):
47 pass
48
49
50def main():
51 parser = argparse.ArgumentParser()
52 parser.add_argument(
53 'connections', nargs='+', default=[],
54 metavar='plug:target_snap:target_slot')
55 args = parser.parse_args()
56 api = SnapdAPI()
57
58 for conn in [spec.split(':') for spec in args.connections]:
59 if len(conn) != 3:
60 raise SystemExit("Bad connection description")
61 assert os.environ['SNAP_NAME']
62 snap = os.environ['SNAP_NAME']
63 existing_connections = api.get_connections()
64 new_connection = Connection(
65 target_snap=conn[1], target_slot=conn[2],
66 plug_snap=snap, plug_plug=conn[0])
67 if new_connection not in existing_connections:
68 try:
69 api.connect(new_connection)
70 except BadRequest as exc:
71 logging.warning("Failed to connect %s to %s. %s" % (
72 conn[0], conn[1], exc))
73
74
75class SnapdAPI():
76 """Based on https://github.com/snapcore/snapd/wiki/REST-API"""
77 SNAPD_BASE_URL = 'http+unix://%2Frun%2Fsnapd.socket'
78
79 def __init__(self):
80 self.session = requests_unixsocket.Session()
81
82 def get_connections(self):
83 data = self._get('/v2/interfaces')
84 connections = []
85 if 'plugs' in data:
86 for plug in data['plugs']:
87 if 'connections' in plug:
88 for con in plug['connections']:
89 connections.append(Connection(
90 con['snap'], con['slot'],
91 plug['snap'], plug['plug']))
92 return connections
93
94 def connect(self, con):
95 json_data = json.dumps({
96 'action': 'connect',
97 'slots': [{'snap': con.target_snap, 'slot': con.target_slot}],
98 'plugs': [{'snap': con.plug_snap, 'plug': con.plug_plug}]
99 })
100 res = self._post('/v2/interfaces', json_data)
101 ready = False
102 while not ready:
103 # busy wait until snapd reports connection job as finised
104 time.sleep(0.5)
105 con_res = self._get('/v2/changes/{}'.format(res['change']))
106 ready = con_res['ready']
107
108 def _get(self, path):
109 res = self.session.get(self.SNAPD_BASE_URL + path)
110 if not res.ok:
111 logging.error("Got error %i attempting to access %s",
112 res.status_code, path)
113 sys.exit(1)
114 return res.json()['result']
115
116 def _post(self, path, data=None):
117 res = self.session.post(self.SNAPD_BASE_URL + path, data=data)
118 if not res.ok:
119 full_res = json.loads(res.text)
120 if res.status_code == 400:
121 raise BadRequest(full_res['result']['message'])
122 logging.error("Got error %i attempting to access %s",
123 res.status_code, path)
124 sys.exit(1)
125 return res.json()
126
127
128if __name__ == '__main__':
129 main()
diff --git a/setup.py b/setup.py
index df2923a..c2517fd 100755
--- a/setup.py
+++ b/setup.py
@@ -88,6 +88,8 @@ setup(
88 "checkbox_support.scripts.snap_configuration:main"),88 "checkbox_support.scripts.snap_configuration:main"),
89 ("checkbox-support-nmea_test="89 ("checkbox-support-nmea_test="
90 "checkbox_support.scripts.nmea_test:main"),90 "checkbox_support.scripts.nmea_test:main"),
91 ("checkbox-support-snap_connect="
92 "checkbox_support.scripts.snap_connect:main"),
91 ],93 ],
92 },94 },
93)95)

Subscribers

People subscribed via source and target branches