New N2VC interface + updated libjuju
[osm/N2VC.git] / README.md
1 # N2VC
2
3 ## Objective
4
5 The N2VC library provides an OSM-centric interface to the VCA. This enables any OSM module (SO, LCM, osmclient) to use a standard pattern for communicating with Juju and the charms responsible for configuring a VNF.
6
7 N2VC relies on the IM module, enforcing compliance with the OSM Information Model.
8
9 ## Caveats
10
11 This library is in active development for OSM Release FOUR. The interface is subject to change prior to release.
12
13 ## Roadmap
14 - Create the N2VC API (in progress)
15 - Create a Python library implementing the N2VC API (in progress)
16 - Implement N2VC API in SO
17 - Implement N2VC API in lcm
18 - Add support for N2VC in OSMClient
19
20 ## Requirements
21
22 Because this is still in heavy development, there are a few manual steps required to use this library.
23
24
25 ```
26 # This list is incomplete
27 apt install python3-nose
28 ```
29
30 ### Install LXD and Juju
31
32 In order to run the test(s) included in N2VC, you'll need to install Juju locally.
33
34 *Note: It's not necessary to install the juju library via pip3; N2VC uses a version bundled within the modules/ directory.*
35
36 ```bash
37 snap install lxd
38 snap install juju --classic
39 ```
40
41 ### Install the IM
42
43 The pyangbind library, used by the IM to parse the Yang data models does not support Python3 at the moment. Work is being done in coordination with the pyangbind maintainer, and Python3 support is expected to hand in the near future.
44
45 In the meantime, we will install and use Python3-compatible branches of pyangbind and the IM module.
46
47 ```
48 sudo apt install libxml2-dev libxslt1-dev build-essential
49
50 git clone http://github.com/adamisrael/pyangbind.git
51 cd pyangbind
52 pip3 install -r requirements.txt
53 pip3 install -r requirements.DEVELOPER.txt
54
55 sudo python3 setup.py develop
56 ```
57
58 Checkout the IM module and use the proposed branch from Gerrit:
59 ```bash
60 git clone https://osm.etsi.org/gerrit/osm/IM.git
61 cd IM
62 git fetch https://israelad@osm.etsi.org/gerrit/osm/IM refs/changes/78/5778/2 && git checkout FETCH_HEAD
63 sudo python3 setup.py develop
64 ```
65
66 ```bash
67 git clone https://osm.etsi.org/gerrit/osm/N2VC.git
68 cd N2VC
69 git fetch https://israelad@osm.etsi.org/gerrit/osm/N2VC refs/changes/70/5870/5 && git checkout FETCH_HEAD
70 sudo python3 setup.py develop
71
72 ```
73
74 ## Testing
75 A basic test has been written to exercise the functionality of the library, and to serve as a demonstration of how to use it.
76
77 ### Export settings to run test
78
79 Export a few environment variables so the test knows where to find the VCA, and the compiled pingpong charm from the devops repository.
80
81 ```bash
82 # You can find the ip of the VCA by running `juju status -m controller` and looking for the DNS for Machine 0
83 export VCA_HOST=
84 export VCA_PORT=17070
85 # You can find these variables in ~/.local/share/juju/accounts.yaml
86 export VCA_USER=admin
87 export VCA_SECRET=PASSWORD
88 ```
89
90 ### Run the test(s)
91
92 *Note: There is a bug in the cleanup of the N2VC/Juju that will throw an exception after the test has finished. This is on the list of things to fix for R4 and should not impact your tests or integration.*
93
94 ```bash
95 nosetests3 --nocapture tests/test_python.py
96 ```
97
98 ## Known Issues
99
100 Many. This is still in active development for Release FOUR.
101
102 - `GetMetrics` does not work yet. There seems to be
103 - An exception is thrown after using N2VC, probably related to the internal AllWatcher used by juju.Model. This shouldn't break usage of N2VC, but it is ugly and needs to be fixed.
104
105 ```
106 Exception ignored in: <generator object WebSocketCommonProtocol.close_connection at 0x7f29a3b3f780>                                     
107 Traceback (most recent call last):                                  
108   File "/home/stone/.local/lib/python3.6/site-packages/websockets/protocol.py", line 743, in close_connection                           
109     if (yield from self.wait_for_connection_lost()):                
110   File "/home/stone/.local/lib/python3.6/site-packages/websockets/protocol.py", line 768, in wait_for_connection_lost                   
111     self.timeout, loop=self.loop)
112   File "/usr/lib/python3.6/asyncio/tasks.py", line 342, in wait_for
113     timeout_handle = loop.call_later(timeout, _release_waiter, waiter)                                                                  
114   File "/usr/lib/python3.6/asyncio/base_events.py", line 543, in call_later                                                             
115     timer = self.call_at(self.time() + delay, callback, *args)      
116   File "/usr/lib/python3.6/asyncio/base_events.py", line 553, in call_at                                                                
117     self._check_closed()          
118   File "/usr/lib/python3.6/asyncio/base_events.py", line 357, in _check_closed                                                          
119     raise RuntimeError('Event loop is closed')                      
120 RuntimeError: Event loop is closed                                  
121 Exception ignored in: <generator object Queue.get at 0x7f29a2ac6938>                                                                    
122 Traceback (most recent call last):                                  
123   File "/usr/lib/python3.6/asyncio/queues.py", line 169, in get     
124     getter.cancel()  # Just in case getter is not done yet.         
125   File "/usr/lib/python3.6/asyncio/base_events.py", line 574, in call_soon                                                              
126     self._check_closed()          
127   File "/usr/lib/python3.6/asyncio/base_events.py", line 357, in _check_closed                                                          
128     raise RuntimeError('Event loop is closed')                      
129 RuntimeError: Event loop is closed                                  
130 Exception ignored in: <coroutine object AllWatcherFacade.Next at 0x7f29a3bd9990>                                                        
131 Traceback (most recent call last):                                  
132   File "/home/stone/src/osm/N2VC/modules/libjuju/juju/client/facade.py", line 412, in wrapper                                           
133     reply = await f(*args, **kwargs)                                
134   File "/home/stone/src/osm/N2VC/modules/libjuju/juju/client/_client1.py", line 59, in Next                                             
135     reply = await self.rpc(msg)   
136   File "/home/stone/src/osm/N2VC/modules/libjuju/juju/client/overrides.py", line 104, in rpc                                            
137     result = await self.connection.rpc(msg, encoder=TypeEncoder)    
138   File "/home/stone/src/osm/N2VC/modules/libjuju/juju/client/connection.py", line 306, in rpc                                           
139     result = await self._recv(msg['request-id'])                    
140   File "/home/stone/src/osm/N2VC/modules/libjuju/juju/client/connection.py", line 208, in _recv                                         
141     return await self.messages.get(request_id)                      
142   File "/home/stone/src/osm/N2VC/modules/libjuju/juju/utils.py", line 61, in get                                                        
143     value = await self._queues[id].get()                            
144   File "/usr/lib/python3.6/asyncio/queues.py", line 169, in get     
145     getter.cancel()  # Just in case getter is not done yet.         
146   File "/usr/lib/python3.6/asyncio/base_events.py", line 574, in call_soon                                                              
147     self._check_closed()          
148   File "/usr/lib/python3.6/asyncio/base_events.py", line 357, in _check_closed                                                          
149     raise RuntimeError('Event loop is closed')                      
150 RuntimeError: Event loop is closed
151 ```