diff options
-rw-r--r-- | meta/classes/populate_sdk_ext.bbclass | 16 | ||||
-rw-r--r-- | scripts/lib/devtool/sdk.py | 118 |
2 files changed, 100 insertions, 34 deletions
diff --git a/meta/classes/populate_sdk_ext.bbclass b/meta/classes/populate_sdk_ext.bbclass index ebb57bba6b..bb8831bf31 100644 --- a/meta/classes/populate_sdk_ext.bbclass +++ b/meta/classes/populate_sdk_ext.bbclass | |||
@@ -47,6 +47,7 @@ SDK_TITLE_task-populate-sdk-ext = "${@d.getVar('DISTRO_NAME', True) or d.getVar( | |||
47 | python copy_buildsystem () { | 47 | python copy_buildsystem () { |
48 | import re | 48 | import re |
49 | import shutil | 49 | import shutil |
50 | import glob | ||
50 | import oe.copy_buildsystem | 51 | import oe.copy_buildsystem |
51 | 52 | ||
52 | oe_init_env_script = d.getVar('OE_INIT_ENV_SCRIPT', True) | 53 | oe_init_env_script = d.getVar('OE_INIT_ENV_SCRIPT', True) |
@@ -224,6 +225,21 @@ python copy_buildsystem () { | |||
224 | if name.endswith("_package.tgz"): | 225 | if name.endswith("_package.tgz"): |
225 | f = os.path.join(root, name) | 226 | f = os.path.join(root, name) |
226 | os.remove(f) | 227 | os.remove(f) |
228 | |||
229 | # Write manifest file | ||
230 | # Note: at the moment we cannot include the env setup script here to keep | ||
231 | # it updated, since it gets modified during SDK installation (see | ||
232 | # sdk_ext_postinst() below) thus the checksum we take here would always | ||
233 | # be different. | ||
234 | manifest_file_list = ['conf/*'] | ||
235 | manifest_file = os.path.join(baseoutpath, 'conf', 'sdk-conf-manifest') | ||
236 | with open(manifest_file, 'w') as f: | ||
237 | for item in manifest_file_list: | ||
238 | for fn in glob.glob(os.path.join(baseoutpath, item)): | ||
239 | if fn == manifest_file: | ||
240 | continue | ||
241 | chksum = bb.utils.sha256_file(fn) | ||
242 | f.write('%s\t%s\n' % (chksum, os.path.relpath(fn, baseoutpath))) | ||
227 | } | 243 | } |
228 | 244 | ||
229 | def extsdk_get_buildtools_filename(d): | 245 | def extsdk_get_buildtools_filename(d): |
diff --git a/scripts/lib/devtool/sdk.py b/scripts/lib/devtool/sdk.py index 4fcd36a0df..80ea8711cc 100644 --- a/scripts/lib/devtool/sdk.py +++ b/scripts/lib/devtool/sdk.py | |||
@@ -75,6 +75,21 @@ def install_sstate_objects(sstate_objects, src_sdk, dest_sdk): | |||
75 | logger.debug("Copying %s to %s" % (sb, dst)) | 75 | logger.debug("Copying %s to %s" % (sb, dst)) |
76 | shutil.copy(sb, dst) | 76 | shutil.copy(sb, dst) |
77 | 77 | ||
78 | def check_manifest(fn, basepath): | ||
79 | import bb.utils | ||
80 | changedfiles = [] | ||
81 | with open(fn, 'r') as f: | ||
82 | for line in f: | ||
83 | splitline = line.split() | ||
84 | if len(splitline) > 1: | ||
85 | chksum = splitline[0] | ||
86 | fpath = splitline[1] | ||
87 | curr_chksum = bb.utils.sha256_file(os.path.join(basepath, fpath)) | ||
88 | if chksum != curr_chksum: | ||
89 | logger.debug('File %s changed: old csum = %s, new = %s' % (os.path.join(basepath, fpath), curr_chksum, chksum)) | ||
90 | changedfiles.append(fpath) | ||
91 | return changedfiles | ||
92 | |||
78 | def sdk_update(args, config, basepath, workspace): | 93 | def sdk_update(args, config, basepath, workspace): |
79 | # Fetch locked-sigs.inc file from remote/local destination | 94 | # Fetch locked-sigs.inc file from remote/local destination |
80 | updateserver = args.updateserver | 95 | updateserver = args.updateserver |
@@ -98,6 +113,18 @@ def sdk_update(args, config, basepath, workspace): | |||
98 | else: | 113 | else: |
99 | is_remote = False | 114 | is_remote = False |
100 | 115 | ||
116 | layers_dir = os.path.join(basepath, 'layers') | ||
117 | conf_dir = os.path.join(basepath, 'conf') | ||
118 | |||
119 | # Grab variable values | ||
120 | tinfoil = setup_tinfoil(config_only=True, basepath=basepath) | ||
121 | try: | ||
122 | stamps_dir = tinfoil.config_data.getVar('STAMPS_DIR', True) | ||
123 | sstate_mirrors = tinfoil.config_data.getVar('SSTATE_MIRRORS', True) | ||
124 | site_conf_version = tinfoil.config_data.getVar('SITE_CONF_VERSION', True) | ||
125 | finally: | ||
126 | tinfoil.shutdown() | ||
127 | |||
101 | if not is_remote: | 128 | if not is_remote: |
102 | # devtool sdk-update /local/path/to/latest/sdk | 129 | # devtool sdk-update /local/path/to/latest/sdk |
103 | new_locked_sig_file_path = os.path.join(updateserver, 'conf/locked-sigs.inc') | 130 | new_locked_sig_file_path = os.path.join(updateserver, 'conf/locked-sigs.inc') |
@@ -121,16 +148,14 @@ def sdk_update(args, config, basepath, workspace): | |||
121 | install_sstate_objects(sstate_objects, updateserver.rstrip('/'), basepath) | 148 | install_sstate_objects(sstate_objects, updateserver.rstrip('/'), basepath) |
122 | logger.info("Updating configuration files") | 149 | logger.info("Updating configuration files") |
123 | new_conf_dir = os.path.join(updateserver, 'conf') | 150 | new_conf_dir = os.path.join(updateserver, 'conf') |
124 | old_conf_dir = os.path.join(basepath, 'conf') | 151 | shutil.rmtree(conf_dir) |
125 | shutil.rmtree(old_conf_dir) | 152 | shutil.copytree(new_conf_dir, conf_dir) |
126 | shutil.copytree(new_conf_dir, old_conf_dir) | ||
127 | logger.info("Updating layers") | 153 | logger.info("Updating layers") |
128 | new_layers_dir = os.path.join(updateserver, 'layers') | 154 | new_layers_dir = os.path.join(updateserver, 'layers') |
129 | old_layers_dir = os.path.join(basepath, 'layers') | 155 | shutil.rmtree(layers_dir) |
130 | shutil.rmtree(old_layers_dir) | 156 | ret = subprocess.call("cp -a %s %s" % (new_layers_dir, layers_dir), shell=True) |
131 | ret = subprocess.call("cp -a %s %s" % (new_layers_dir, old_layers_dir), shell=True) | ||
132 | if ret != 0: | 157 | if ret != 0: |
133 | logger.error("Copying %s to %s failed" % (new_layers_dir, old_layers_dir)) | 158 | logger.error("Copying %s to %s failed" % (new_layers_dir, layers_dir)) |
134 | return ret | 159 | return ret |
135 | else: | 160 | else: |
136 | # devtool sdk-update http://myhost/sdk | 161 | # devtool sdk-update http://myhost/sdk |
@@ -138,50 +163,75 @@ def sdk_update(args, config, basepath, workspace): | |||
138 | try: | 163 | try: |
139 | os.makedirs(os.path.join(tmpsdk_dir, 'conf')) | 164 | os.makedirs(os.path.join(tmpsdk_dir, 'conf')) |
140 | new_locked_sig_file_path = os.path.join(tmpsdk_dir, 'conf', 'locked-sigs.inc') | 165 | new_locked_sig_file_path = os.path.join(tmpsdk_dir, 'conf', 'locked-sigs.inc') |
141 | # Fetch locked-sigs.inc from update server | 166 | # Fetch manifest from server |
142 | ret = subprocess.call("wget -q -O - %s/conf/locked-sigs.inc > %s" % (updateserver, new_locked_sig_file_path), shell=True) | 167 | tmpmanifest = os.path.join(tmpsdk_dir, 'conf', 'sdk-conf-manifest') |
143 | if ret != 0: | 168 | ret = subprocess.call("wget -q -O %s %s/conf/sdk-conf-manifest" % (tmpmanifest, updateserver), shell=True) |
144 | logger.error("Fetching conf/locked-sigs.inc from %s to %s failed" % (updateserver, new_locked_sig_file_path)) | 169 | changedfiles = check_manifest(tmpmanifest, basepath) |
145 | return ret | 170 | if not changedfiles: |
146 | else: | 171 | logger.info("Already up-to-date") |
147 | logger.info("Fetching conf/locked-sigs.inc from %s to %s succeeded" % (updateserver, new_locked_sig_file_path)) | ||
148 | update_dict = generate_update_dict(new_locked_sig_file_path, old_locked_sig_file_path) | ||
149 | logger.debug("update_dict = %s" % update_dict) | ||
150 | if len(update_dict) == 0: | ||
151 | logger.info("No need to update.") | ||
152 | return 0 | 172 | return 0 |
153 | # Update metadata | 173 | # Update metadata |
154 | logger.debug("Updating meta data via git ...") | 174 | logger.debug("Updating metadata via git ...") |
155 | # Try using 'git pull', if failed, use 'git clone' | 175 | # Try using 'git pull', if failed, use 'git clone' |
156 | if os.path.exists(os.path.join(basepath, 'layers/.git')): | 176 | if os.path.exists(os.path.join(basepath, 'layers/.git')): |
157 | ret = subprocess.call("cd layers && git pull %s/layers/.git" % updateserver, shell=True) | 177 | ret = subprocess.call("git pull %s/layers/.git" % updateserver, shell=True, cwd=layers_dir) |
158 | else: | 178 | else: |
159 | ret = -1 | 179 | ret = -1 |
160 | if ret != 0: | 180 | if ret != 0: |
161 | ret = subprocess.call("rm -rf layers && git clone %s/layers/.git" % updateserver, shell=True) | 181 | ret = subprocess.call("git clone %s/layers/.git" % updateserver, shell=True, cwd=tmpsdk_dir) |
162 | if ret != 0: | 182 | if ret != 0: |
163 | logger.error("Updating meta data via git failed") | 183 | logger.error("Updating metadata via git failed") |
164 | return ret | 184 | return ret |
165 | logger.debug("Updating conf files ...") | 185 | logger.debug("Updating conf files ...") |
166 | conf_files = ['local.conf', 'bblayers.conf', 'devtool.conf', 'locked-sigs.inc'] | 186 | for changedfile in changedfiles: |
167 | for conf in conf_files: | 187 | ret = subprocess.call("wget -q -O %s %s/%s" % (changedfile, updateserver, changedfile), shell=True, cwd=tmpsdk_dir) |
168 | ret = subprocess.call("wget -q -O - %s/conf/%s > conf/%s" % (updateserver, conf, conf), shell=True) | ||
169 | if ret != 0: | 188 | if ret != 0: |
170 | logger.error("Update %s failed" % conf) | 189 | logger.error("Updating %s failed" % changedfile) |
171 | return ret | 190 | return ret |
172 | with open(os.path.join(basepath, 'conf/local.conf'), 'a') as f: | 191 | |
173 | f.write('SSTATE_MIRRORS_append = " file://.* %s/sstate-cache/PATH \\n "\n' % updateserver) | 192 | # Ok, all is well at this point - move everything over |
193 | tmplayers_dir = os.path.join(tmpsdk_dir, 'layers') | ||
194 | if os.path.exists(tmplayers_dir): | ||
195 | shutil.rmtree(layers_dir) | ||
196 | shutil.move(tmplayers_dir, layers_dir) | ||
197 | for changedfile in changedfiles: | ||
198 | destfile = os.path.join(basepath, changedfile) | ||
199 | os.remove(destfile) | ||
200 | shutil.move(os.path.join(tmpsdk_dir, changedfile), destfile) | ||
201 | os.remove(os.path.join(conf_dir, 'sdk-conf-manifest')) | ||
202 | shutil.move(tmpmanifest, conf_dir) | ||
203 | |||
204 | if not sstate_mirrors: | ||
205 | with open(os.path.join(conf_dir, 'site.conf'), 'a') as f: | ||
206 | f.write('SCONF_VERSION = "%s"\n' % site_conf_version) | ||
207 | f.write('SSTATE_MIRRORS_append = " file://.* %s/sstate-cache/PATH \\n "\n' % updateserver) | ||
174 | finally: | 208 | finally: |
175 | shutil.rmtree(tmpsdk_dir) | 209 | shutil.rmtree(tmpsdk_dir) |
176 | 210 | ||
177 | if not args.skip_prepare: | 211 | if not args.skip_prepare: |
212 | # Find all potentially updateable tasks | ||
213 | sdk_update_targets = [] | ||
214 | tasks = ['do_populate_sysroot', 'do_packagedata'] | ||
215 | for root, _, files in os.walk(stamps_dir): | ||
216 | for fn in files: | ||
217 | if not '.sigdata.' in fn: | ||
218 | for task in tasks: | ||
219 | if '.%s.' % task in fn or '.%s_setscene.' % task in fn: | ||
220 | sdk_update_targets.append('%s:%s' % (os.path.basename(root), task)) | ||
178 | # Run bitbake command for the whole SDK | 221 | # Run bitbake command for the whole SDK |
179 | sdk_update_targets = config.get('SDK', 'sdk_update_targets', config.get('SDK', 'sdk_targets')) | ||
180 | logger.info("Preparing build system... (This may take some time.)") | 222 | logger.info("Preparing build system... (This may take some time.)") |
181 | try: | 223 | try: |
182 | exec_build_env_command(config.init_path, basepath, 'bitbake %s --setscene-only' % sdk_update_targets) | 224 | exec_build_env_command(config.init_path, basepath, 'bitbake --setscene-only %s' % ' '.join(sdk_update_targets), stderr=subprocess.STDOUT) |
183 | except: | 225 | output, _ = exec_build_env_command(config.init_path, basepath, 'bitbake -n %s' % ' '.join(sdk_update_targets), stderr=subprocess.STDOUT) |
184 | logger.error('bitbake %s failed' % sdk_update_targets) | 226 | runlines = [] |
227 | for line in output.splitlines(): | ||
228 | if 'Running task ' in line: | ||
229 | runlines.append(line) | ||
230 | if runlines: | ||
231 | logger.error('Unexecuted tasks found in preparation log:\n %s' % '\n '.join(runlines)) | ||
232 | return -1 | ||
233 | except bb.process.ExecutionError as e: | ||
234 | logger.error('Preparation failed:\n%s' % e.stdout) | ||
185 | return -1 | 235 | return -1 |
186 | return 0 | 236 | return 0 |
187 | 237 | ||