summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/remotedata.py
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2020-03-23 12:43:25 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-03-24 22:01:03 +0000
commitd53958766e2c766b95b3947f69b64c409ed433d8 (patch)
tree45e943ca7b1cce938d730cf17cdbb4e472082258 /bitbake/lib/bb/remotedata.py
parent89705a60f3b566743703c3a7597ccc4507293dd9 (diff)
downloadpoky-d53958766e2c766b95b3947f69b64c409ed433d8.tar.gz
bitbake: tinfoil: Simplify remote datastore connections
The current approach to remote datastores used in tinfoil is breaking. For example, adding a devupstream extension to a recipe with a git upstream, making it the preferred version and then running "devtool modify" on it causes get_srcrev() circular dependency issues. The problem is the override handling in the datastore is broken. This gets broken since remotedata:recieve_datastore() sets d.dict but doesn't update d.overridedata (or d.inchistory or d.varhistory). We could play whack-a-mole but the current implementation seems to be flawed to me. It also doesn't cover, or only partially covers some datastore operations and each needs new dedicated command API. Instead, step back and reimplement the way the datastore connector works. With this change, the datastore is either remote or local but the data is not spread on two sides of the connection. All the API is proxied over the connection by a single function for the datastore (and two to support variable history and include history). This code does not support using the datastore as a parameter to any data store functions. We did have one case of that but its just bad code and can be replaced. The result is something which is much simpler and less invasive to the datastore code itself, meaning its behaviour should be much more consistent. The existing tests for the remote data no longer make any sense and are removed. The one bug this code would have is if key/value pairs are returned over the IPC and those values contained a DataSmart object since we don't recurse into return values to find such things. Nothing appears to do that currently so lets worry about it if its ever an issue. This change should simplfy a ton of other issues and avoid a ton of other bugs so is a huge net gain. Tested with bitbake's and OE's selftests. (Bitbake rev: 85e03a64dd0a4ebe71009ec4bdf4192c04a9786e) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/remotedata.py')
-rw-r--r--bitbake/lib/bb/remotedata.py49
1 files changed, 4 insertions, 45 deletions
diff --git a/bitbake/lib/bb/remotedata.py b/bitbake/lib/bb/remotedata.py
index 7391e1b45c..6c9864dd6b 100644
--- a/bitbake/lib/bb/remotedata.py
+++ b/bitbake/lib/bb/remotedata.py
@@ -17,16 +17,16 @@ class RemoteDatastores:
17 self.cooker = cooker 17 self.cooker = cooker
18 self.datastores = {} 18 self.datastores = {}
19 self.locked = [] 19 self.locked = []
20 self.datastores[0] = self.cooker.data
20 self.nextindex = 1 21 self.nextindex = 1
21 22
22 def __len__(self): 23 def __len__(self):
23 return len(self.datastores) 24 return len(self.datastores)
24 25
25 def __getitem__(self, key): 26 def __getitem__(self, key):
26 if key is None: 27 # Cooker could have changed its datastore from under us
27 return self.cooker.data 28 self.datastores[0] = self.cooker.data
28 else: 29 return self.datastores[key]
29 return self.datastores[key]
30 30
31 def items(self): 31 def items(self):
32 return self.datastores.items() 32 return self.datastores.items()
@@ -63,44 +63,3 @@ class RemoteDatastores:
63 raise Exception('Tried to release locked datastore %d' % idx) 63 raise Exception('Tried to release locked datastore %d' % idx)
64 del self.datastores[idx] 64 del self.datastores[idx]
65 65
66 def receive_datastore(self, remote_data):
67 """Receive a datastore object sent from the client (as prepared by transmit_datastore())"""
68 dct = dict(remote_data)
69 d = bb.data_smart.DataSmart()
70 d.dict = dct
71 while True:
72 if '_remote_data' in dct:
73 dsindex = dct['_remote_data']['_content']
74 del dct['_remote_data']
75 if dsindex is None:
76 dct['_data'] = self.cooker.data.dict
77 else:
78 dct['_data'] = self.datastores[dsindex].dict
79 break
80 elif '_data' in dct:
81 idct = dict(dct['_data'])
82 dct['_data'] = idct
83 dct = idct
84 else:
85 break
86 return d
87
88 @staticmethod
89 def transmit_datastore(d):
90 """Prepare a datastore object for sending over IPC from the client end"""
91 # FIXME content might be a dict, need to turn that into a list as well
92 def copy_dicts(dct):
93 if '_remote_data' in dct:
94 dsindex = dct['_remote_data']['_content'].dsindex
95 newdct = dct.copy()
96 newdct['_remote_data'] = {'_content': dsindex}
97 return list(newdct.items())
98 elif '_data' in dct:
99 newdct = dct.copy()
100 newdata = copy_dicts(dct['_data'])
101 if newdata:
102 newdct['_data'] = newdata
103 return list(newdct.items())
104 return None
105 main_dict = copy_dicts(d.dict)
106 return main_dict