Improved Primitive support and better testing
[osm/N2VC.git] / modules / libjuju / docs / upstream-updates / index.rst
1 Syncing Upstream Updates
2 ========================
3
4 Updating the facade and definitions code generated from the schema
5 to reflect changes in upstream Juju consists of two steps:
6
7 * Creating a new `schemas-juju-<version>.json` file from the Juju code-base
8 * Generating the libjuju Python code from that schema
9
10 Rarely, you may also have to add or update an override.
11
12
13 Creating a Schema File
14 ----------------------
15
16 First, you will need to fetch SchemaGen_ and a copy of the Juju source.
17 Once your copy of the Juju source is at the version you want to update to
18 (probably the `develop` branch, or a release tag) and you have updated
19 and reinstalled SchemaGen to reflect those changes, you just need to send
20 the output into a file in the libjuju repository:
21
22 .. code:: bash
23
24   schemagen > juju/client/schemas-juju-2.2-rc1.json
25
26 The version number you use in the filename should match the upstream
27 version of Juju.  You should then also move the `latest` pointer to
28 the new file:
29
30 .. code:: bash
31
32   rm juju/client/schemas-juju-latest.json
33   ln -s schemas-juju-2.2-rc1.json juju/client/schemas-juju-latest.json
34
35
36 Generating the Python Code
37 --------------------------
38
39 Once you have a new schema file, you can update the Python code
40 using the `client` make target:
41
42 .. code:: bash
43
44   make client
45
46 You should expect to see updates to the `juju/client/_definitions.py` file,
47 as well as one or more of the `juju/client/_clientX.py` files, depending on
48 which facades were touched.
49
50
51 Integrating into the Object Layer
52 ---------------------------------
53
54 Once the raw client APIs are synced, you may need to integrate any new or
55 changed API calls into the object layer, to provide a clean, Pythonic way
56 to interact with the model.  This may be as simple as adding an optional
57 parameter to an existing model method, tweaking what manipulations, if any
58 the model method does to the data before it is sent to the API, or it may
59 require adding an entirely new model method to capture the new functionality.
60
61 In general, the approach should be to make the interactions with the model
62 layer use the same patterns as when you use the CLI, just with Python idioms
63 and OO approaches.
64
65 When trying to determine what client calls need to be made and what data to
66 be sent for a given Juju CLI action, it is very useful to add
67 `--debug --logging-config TRACE` to any Juju CLI command to view the full
68 conversation between the CLI client and the API server.  For example:
69
70 ```
71 [johnsca@murdoch:~] $ juju deploy --debug --logging-config TRACE ./builds/test
72 11:51:20 INFO  juju.cmd supercommand.go:56 running juju [2.3.5 gc go1.10]
73 11:51:20 DEBUG juju.cmd supercommand.go:57   args: []string{"/snap/juju/3884/bin/juju", "deploy", "--debug", "--logging-config", "TRACE", "./builds/test"}
74 11:51:20 INFO  juju.juju api.go:67 connecting to API addresses: [35.172.119.191:17070 172.31.94.16:17070 252.94.16.1:17070]
75 11:51:20 TRACE juju.api certpool.go:49 cert dir "/etc/juju/certs.d" does not exist
76 11:51:20 DEBUG juju.api apiclient.go:843 successfully dialed "wss://35.172.119.191:17070/model/a7317969-6dab-4ba4-844b-af3d661c228d/api"
77 11:51:20 INFO  juju.api apiclient.go:597 connection established to "wss://35.172.119.191:17070/model/a7317969-6dab-4ba4-844b-af3d661c228d/api"
78 ...
79 11:51:20 INFO  juju.cmd.juju.application series_selector.go:71 with the configured model default series "xenial"
80 11:51:20 DEBUG httpbakery client.go:244 client do POST https://35.172.119.191:17070/model/a7317969-6dab-4ba4-844b-af3d661c228d/charms?revision=0&schema=local&series=xenial {
81 11:51:21 DEBUG httpbakery client.go:246 } -> error <nil>
82 11:51:21 INFO  cmd deploy.go:1096 Deploying charm "local:xenial/test-0".
83 11:51:21 TRACE juju.rpc.jsoncodec codec.go:225 -> {"request-id":3,"type":"Charms","version":2,"request":"CharmInfo","params":{"url":"local:xenial/test-0"}}
84 11:51:21 TRACE juju.rpc.jsoncodec codec.go:120 <- {"request-id":3,"response":{"revision":0,"url":"local:xenial/test-0","config":{"test":{"type":"string","default":""}},"meta":{"name":"test","summary":"test","description":"test","subordinate":false,"series":["xenial"],"resources":{"dummy":{"name":"dummy","type":"file","path":"dummy.snap","description":"dummy snap"}},"min-juju-version":"0.0.0"},"actions":{}}}
85 11:51:21 TRACE juju.rpc.jsoncodec codec.go:225 -> {"request-id":4,"type":"Charms","version":2,"request":"IsMetered","params":{"url":"local:xenial/test-0"}}
86 11:51:21 TRACE juju.rpc.jsoncodec codec.go:120 <- {"request-id":4,"response":{"metered":false}}
87 11:51:21 TRACE juju.rpc.jsoncodec codec.go:225 -> {"request-id":5,"type":"Resources","version":1,"request":"AddPendingResources","params":{"tag":"application-test","url":"local:xenial/test-0","channel":"","macaroon":null,"resources":[{"name":"dummy","type":"file","path":"dummy.snap","description":"dummy snap","origin":"store","revision":-1,"fingerprint":"","size":0}]}}
88 11:51:21 TRACE juju.rpc.jsoncodec codec.go:120 <- {"request-id":5,"response":{"pending-ids":["c0ffdd92-da23-4fb2-8d41-d82d58423447"]}}
89 11:51:21 TRACE juju.rpc.jsoncodec codec.go:225 -> {"request-id":6,"type":"Application","version":5,"request":"Deploy","params":{"applications":[{"application":"test","series":"xenial","charm-url":"local:xenial/test-0","channel":"","num-units":1,"config-yaml":"","constraints":{},"resources":{"dummy":"c0ffdd92-da23-4fb2-8d41-d82d58423447"}}]}}
90 11:51:21 TRACE juju.rpc.jsoncodec codec.go:120 <- {"request-id":6,"response":{"results":[{}]}}
91 11:51:21 TRACE juju.rpc.jsoncodec codec.go:123 <- error: read tcp 192.168.1.102:52168->35.172.119.191:17070: use of closed network connection (closing true)
92 11:51:21 DEBUG juju.api monitor.go:35 RPC connection died
93 11:51:21 INFO  cmd supercommand.go:465 command finished
94 ```
95
96 Note that this will contain login information (which has been removed from the above).
97
98
99 Overrides
100 ---------
101
102 It should be quite rare, but occasionally the generated Python code does
103 not capture all of the logic needed to properly parse the output from the API
104 or may otherwise need some small amount of tweaking.  This is what the
105 `juju/client/overrides.py` file is for.  An example of this is the `Number`
106 type, which isn't standard JSON and must be parsed slightly differently.
107
108 At the top of that file are two lists, `__all__` and `__patches__`.  The
109 former replaces entire class implementations, while the latter patches
110 the attributes of the override classes into the matching generated class,
111 leaving the rest of the generated class untouched.
112
113
114 .. _SchemaGen: https://github.com/juju/schemagen