diff options
author | Santiago Collazo <scollazo@activitycentral.com> | 2012-10-29 19:12:40 (GMT) |
---|---|---|
committer | Santiago Collazo <scollazo@activitycentral.com> | 2012-10-29 19:12:40 (GMT) |
commit | 9da2b723e2f5cf9fbebb08b266278e1c912450b3 (patch) | |
tree | e32baf7ee451b1a6c2f67733549b9151259fb9f9 | |
parent | efdde2059ed8872711c91c5879bc38c624ead10a (diff) | |
parent | d6ec465cd85b4ecf3efdeb937804e8153348b8f2 (diff) |
Merge with upstream master
93 files changed, 1438 insertions, 1096 deletions
diff --git a/bin/zhashfs.c b/bin/zhashfs.c index 12a0ffb..9832f31 100644 --- a/bin/zhashfs.c +++ b/bin/zhashfs.c @@ -1,5 +1,8 @@ // Handle partitions #include <stdio.h> +#include <stdint.h> +#include <linux/fiemap.h> +#include <linux/fs.h> #define TFM_DESC #include <tomcrypt.h> @@ -13,6 +16,14 @@ static long zbufsize; static long zblocksize; static char *hashname; +static long eblocks = -1; + +/* + * A bitmap detailing which eblocks are used, and which are empty. + * (actually a char array, one byte per eblock, because I'm lazy) + */ +static unsigned char *eblocks_used; + #define PATTERN_SIZE 4096 #define DO(x) do { run_cmd((x), __LINE__, __FILE__, #x); } while (0); @@ -69,23 +80,95 @@ static int read_block(unsigned char *buf, FILE *infile, int is_last_block) return readlen; } +struct fiemap *read_fiemap(int fd) +{ + struct fiemap *fiemap; + int extents_size; + + if ((fiemap = (struct fiemap*)malloc(sizeof(struct fiemap))) == NULL) { + fprintf(stderr, "Out of memory allocating fiemap\n"); + return NULL; + } + memset(fiemap, 0, sizeof(struct fiemap)); + + fiemap->fm_start = 0; + fiemap->fm_length = ~0; + fiemap->fm_flags = 0; + fiemap->fm_extent_count = 0; + fiemap->fm_mapped_extents = 0; + + /* Find out how many extents there are */ + if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0) { + fprintf(stderr, "fiemap ioctl() failed\n"); + return NULL; + } + + /* Read in the extents */ + extents_size = sizeof(struct fiemap_extent) * (fiemap->fm_mapped_extents); + + /* Resize fiemap to allow us to read in the extents */ + if ((fiemap = (struct fiemap*)realloc(fiemap, sizeof(struct fiemap) + + extents_size)) == NULL) { + fprintf(stderr, "Out of memory allocating fiemap\n"); + return NULL; + } + + memset(fiemap->fm_extents, 0, extents_size); + fiemap->fm_extent_count = fiemap->fm_mapped_extents; + fiemap->fm_mapped_extents = 0; + + if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0) { + fprintf(stderr, "fiemap ioctl() failed\n"); + return NULL; + } + + return fiemap; +} + +/* Given a file extent, determine which eblocks in the output file need to + * represent that extent, and mark them as used in the eblocks_used map. */ +static void process_extent(struct fiemap_extent *ex) +{ + long i; + uint64_t last_byte = ex->fe_logical + ex->fe_length - 1; + long first_eblock = ex->fe_logical / zblocksize; + long last_eblock = last_byte / zblocksize; + + printf("Extent(%lld, %lld) occupies eblocks %d to %d\n", ex->fe_logical, ex->fe_length, first_eblock, last_eblock); + for (i = first_eblock; i <= last_eblock; i++) + eblocks_used[i] = 1; +} + +/* + * Use FIEMAP to determine the extents that make up a file. + * Allocate eblocks_used array based on length of file, and then mark + * the set of eblocks that contain data based on the extents. + */ +static void read_extents(FILE *infile) +{ + int i; + struct fiemap *fiemap = read_fiemap(fileno(infile)); + LTC_ARGCHK(fiemap != NULL); + + eblocks_used = malloc(eblocks); + LTC_ARGCHK(eblocks_used != 0); + memset(eblocks_used, 0, eblocks); + + for (i=0; i < fiemap->fm_mapped_extents; i++) + process_extent(&fiemap->fm_extents[i]); +} + int main(int argc, char **argv) { char *fname; unsigned char *buf; // EBLOCKSIZE FILE *infile; - long eblocks = -1; long i; off_t insize; int readlen; int skip; - unsigned char *pbuf; // fill pattern buffer - char pname[PATH_MAX]; // fill pattern file name - FILE *pfile; // fill pattern file - int patterned, n; - if (argc < 6) { fprintf(stderr, "%s: zblocksize hashname signed_file_name spec_file_name zdata_file_name [ #blocks ]\n", argv[0]); return EXIT_FAILURE; @@ -119,21 +202,6 @@ int main(int argc, char **argv) infile = fopen(argv[3], "rb"); LTC_ARGCHK(infile != NULL); - /* open and read an optional fill pattern file */ - pbuf = NULL; - strncpy(pname, argv[3], sizeof(pname) - 6); - strcat(pname, ".fill"); - pname[sizeof(pname) - 1] = 0; - - pfile = fopen(pname, "rb"); - if (pfile != NULL) { - pbuf = malloc(PATTERN_SIZE); - LTC_ARGCHK(pbuf != NULL); - n = fread(pbuf, 1, PATTERN_SIZE, pfile); - LTC_ARGCHK(n == PATTERN_SIZE); - fclose(pfile); - } - /* open output file */ outfile = fopen(argv[4], "wb"); LTC_ARGCHK(outfile != NULL); @@ -158,6 +226,8 @@ int main(int argc, char **argv) // LTC_ARGCHK((eblocks * zblocksize) == insize); } + read_extents(infile); + /* Remove possible path prefix */ fname = strrchr(argv[5], '/'); if (fname == NULL) @@ -171,48 +241,20 @@ int main(int argc, char **argv) fprintf(stdout, "Total blocks: %ld\n", eblocks); - fseek(infile, zblocksize, SEEK_SET); + /* wipe the partition table first in case of partial completion */ + memset(buf, 0, zblocksize); + write_block(0, buf); /* make a hash of the file */ for (i=1; i < eblocks; i++) { + if (!eblocks_used[i]) + continue; + + fseeko(infile, (uint64_t) i * zblocksize, SEEK_SET); readlen = read_block(buf, infile, i == eblocks-1); LTC_ARGCHK(readlen == zblocksize); -#ifdef notdef - skip = 1; - for (p = (unsigned char *)buf; p < &buf[zblocksize]; p++) { - if (*p != 0xff) { - skip = 0; - break; - } - } -#else - skip = 0; -#endif - - if (pbuf) { - /* check if this zblock is fully patterned as unused, and if - any parts of the zblock are patterned then zero them, for ease - of compression */ - - patterned = 1; - for (n = 0; n < (zblocksize / PATTERN_SIZE); n++) { - if (memcmp(&buf[n*PATTERN_SIZE], pbuf, PATTERN_SIZE)) { - patterned = 0; - } else { - memset(&buf[n*PATTERN_SIZE], 0, PATTERN_SIZE); - } - } - - /* skip any block that is fully patterned, thus relying on the - fs-update card erase-blocks */ - - if (patterned) skip++; - } - - if (!skip) - write_block(i, buf); - + write_block(i, buf); fprintf(stdout, "\r%ld", i); fflush(stdout); } @@ -54,7 +54,31 @@ release was made. Usage: - olpc-os-builder <path to build config> + olpc-os-builder [options] <path to build config> [path to build config...] + + +Offline use: + +olpc-os-builder naturally involves a fair amount of downloading in its work. +These downloads are cached, meaning that while the first run will do a lot +of downloading, subsequent runs will reuse the locally cached content. + +However, those subsequent runs will still go online in order to check that +cached content is up-to-date. This can be time consuming, especially +on slow connections. + +If you want olpc-os-builder to trust its local caches, and not even go +online to check that they are current, you can provide the --cache-only +command-line option. + +For obvious reasons, cache-only mode requires you to have previously run +the same build configuration in "normal" mode beforehand (i.e. without +--cache-only specified), so that caches are populated. + +Be aware that less cache validation is performed during --cache-only runs. +This means that corrupt caches or truncated files could be treated as good +in cache-only mode, whereas such problems are generally detected and +corrected when connectivity is used. Configuration: @@ -63,24 +87,37 @@ Various build configurations can be found in the examples directory included with the distribution, including configurations used to build OLPC OS releases. -Build configuration files have a series of sections, each section -title is enclosed in square brackets. Inside each section, there are -options. For example, "mysection" below has one option, named +Build configuration files specify a series of modules, each module +title being enclosed by square brackets. Inside each module, there are +options. For example, "mymodule" below has one option, named "option1" with value "myvalue": - [mysection] + [mymodule] option1=myvalue Options can reside on multiple lines, provided that all lines beyond the first one are indented, e.g.: - [mysection] + [mymodule] option1=this is an option that spans 4 lines but lines 2 through 4 must be indented option2=foo +The modules selected by your build configuration file correspond to modules +shipped by olpc-os-builder. A module is loaded simply by specifying it in +the build configuration. You do not have to specify any options in the cases +when the default settings meet your needs, or when the module has no options, +e.g.: + + [sugar] + [gnome] + +Multiple configuration files can be specified. They will be parsed in the +order provided (i.e. later config files can override values from earlier +ones). + Interpolation (basic assignment and use of variables) can be used, according to Python's SafeConfigParser documentation. @@ -88,7 +125,7 @@ Default variables automatically provided: oob_config_dir - The directory where the currently selected config file resides + The directory where the first specified config file resides In general, each section that can exist in the configuration file corresponds to a specific module. The section name is the same as the @@ -104,6 +141,11 @@ fedora_release The numeric release number of the Fedora operating system to base the OLPC OS build on. For example, 11 for Fedora 11. +fedora_arch + + The processor architecture to use for Fedora package selection. + See http://mirrors.fedoraproject.org/ for the available values. + olpc_version_major The major version component of the OLPC version tag to include in @@ -122,24 +164,28 @@ olpc_version_release in the OS image. For example, in the OLPC OS 10.1.0 release, this would be 0. -image_name - - The naming scheme to use for the output files. The value of this field - must include "%%d", this will be replaced with the build number. - For example, a value of "per%%d-6" would result the output being called - "per703-6" for build number 703. The default value is "os%%d". - The reason that 2 percentage signs are needed is because RawConfigParser - is in use; a % therefore triggers the INI interpolation feature, unless - presented in the escaped form %%. - customization_info + This identifier will be displayed in the Sugar control panel and + in other places on the system, to indicate the source of the OS + build. + Please set this to a string that indicates your identity, to make clear that the resultant build is a modified version of OLPC's official release. For example, you could use something like "customized for Paraguay" when producing an OS build for OLPC's Paraguayan deployment. +customization_tag + + This tag will be included in the names of the output files, as a quick + way of identifying origin. The default value is "xx". + + Please set this to a tag (one or two characters) representing your + identity. Your two-letter country code may be a good choice here. + For example, for the OLPC Paraguay project, "py" would be a sensible + choice. "o" is used by OLPC. + target_platform A textual description of the target platform for the build, for @@ -149,15 +195,6 @@ langs A set of languages to support in the resultant OS image. -modules - - A comma-separated selection of modules to include in the build. - -modules_<ANYTHING> - - Additional modules to include (allowing you to append to the list of - modules in an additional configuration file) - In general, options need to be set with care. Aim to stick with the values shown in the examples where possible. For example, if you were @@ -167,6 +204,17 @@ adapting all of the module code to work with the ever-changing components of each official Fedora release. +Output: + +At the end of the process, a series of filenames are saved in an output +directory. The path to this directory is printed at the end of the process. +Files within this directory are named according to a version scheme +encompassing the major and minor version number, the build numer, the target +laptop model, and the customisation tag. See +http://wiki.laptop.org/go/Release_Process#Version_numbering for more details +on this scheme. + + Design goals: - revolve around Fedora's image-creator infrastructure, meaning that diff --git a/examples/f14-xo1.5.ini b/examples/f18-xo1.5.ini index 7cb735c..4d32643 100644 --- a/examples/f14-xo1.5.ini +++ b/examples/f18-xo1.5.ini @@ -1,42 +1,33 @@ [global] -fedora_release=14 -olpc_version_major=11 -olpc_version_minor=3 +fedora_release=18 +fedora_arch=i386 +olpc_version_major=0 +olpc_version_minor=0 olpc_version_release=0 target_platform=XO-1.5 -langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de -modules= - base, - xo1_5, - buildnr_from_file, - yumcfg, - sd_card_image, - repos, - x11, - sugar, - sugarlabs_activities, - sugar_activities_extra, - gnome +langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de,hy + +[base] + +[xo1_5] [sd_card_image] -; 4GB image -size_1=3865470566,zd4 -; 2GB image -size_2=1932735283,zd2 [repos] -fedora_arch=i386 fedora=fedora,fedora-updates,fedora-updates-testing -olpc_publicrpms_1=1,f14 -olpc_publicrpms_2=1,f14-xo1.5 +olpc_publicrpms_1=1,f18 +olpc_publicrpms_2=1,f18-xo1.5 add_excludes_to=fedora,fedora-updates,fedora-updates-testing [yumcfg] -addrepo_1=1,olpc-f14,http://rpmdropbox.laptop.org/f14/ -addrepo_2=1,olpc-f14-xo1.5,http://rpmdropbox.laptop.org/f14-xo1.5/ -force_enable=fedora-updates-testing +addrepo_1=1,olpc-f18,http://rpmdropbox.laptop.org/f18/ +addrepo_2=1,olpc-f18-xo1.5,http://rpmdropbox.laptop.org/f18-xo1.5/ add_excludes_to=fedora,fedora-updates,fedora-updates-testing +[x11] + +[gnome] + [sugar] favorites_view_add= org.sugarlabs.InfoSlicer, @@ -54,7 +45,8 @@ favorites_view_add= tv.alterna.Clock, org.eq.FotoToon, org.sugarlabs.AbacusActivity, - org.sugarlabs.PortfolioActivity + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph favorites_view_del= org.laptop.sugar.ReadActivity, org.laptop.TamTamSynthLab @@ -68,7 +60,6 @@ protected_activities= org.laptop.RecordActivity [sugarlabs_activities] -sugar_version=0.92 experimental=1 activities=org.laptop.HelpActivity, org.laptop.AbiWordActivity, @@ -111,10 +102,11 @@ activities=org.laptop.HelpActivity, com.laptop.Ruler, org.sugarlabs.HelloWorld, org.laptop.Words, - org.sugarlabs.PortfolioActivity + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph [sugar_activities_extra] -url_1=http://dev.laptop.org/~reuben/scratch-19.xo +url_1=http://wiki.laptop.org/images/8/86/Scratch-23.xo url_6=http://dev.laptop.org/~gonzalo/Biology-10.xol url_7=http://wiki.laptop.org/images/7/77/Wikibooks-8.xol url_8=http://wiki.laptop.org/images/5/5e/NatureImages-8.xol diff --git a/examples/f14-xo1.75.ini b/examples/f18-xo1.75.ini index 1ad1344..ee1c20e 100644 --- a/examples/f14-xo1.75.ini +++ b/examples/f18-xo1.75.ini @@ -1,38 +1,34 @@ [global] -fedora_release=14 -olpc_version_major=11 -olpc_version_minor=3 +fedora_release=18 +fedora_arch=armhfp +olpc_version_major=0 +olpc_version_minor=0 olpc_version_release=0 target_platform=XO-1.75 -langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de -modules= - base, - xo1_75, - buildnr_from_file, - yumcfg, - sd_card_image, - repos, - x11, - sugar, - sugarlabs_activities, - sugar_activities_extra, - gnome +langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de,hy + +[base] + +[xo1_75] [sd_card_image] -; 4GB image -size_1=3865470566,zd4 [repos] -fedora_arch=arm -fedora=fedora,fedora-updates -olpc_publicrpms_1=1,f14 -olpc_publicrpms_2=1,f14-xo1.75 -add_excludes_to=fedora,fedora-updates +fedora=fedora,fedora-updates-testing +olpc_publicrpms_1=1,f18 +olpc_publicrpms_2=1,f18-xo1.75 +add_excludes_to=fedora,fedora-updates-testing [yumcfg] -addrepo_1=1,olpc-f14,http://rpmdropbox.laptop.org/f14/ -addrepo_2=1,olpc-f14-xo1.75,http://rpmdropbox.laptop.org/f14-xo1.75/ -add_excludes_to=fedora,fedora-updates +addrepo_1=1,olpc-f18,http://rpmdropbox.laptop.org/f18/ +addrepo_2=1,olpc-f18-xo1.75,http://rpmdropbox.laptop.org/f18-xo1.75/ +add_excludes_to=fedora,fedora-updates,fedora-updates-testing + +[osk] + +[x11] + +[gnome] [sugar] favorites_view_add= @@ -51,7 +47,8 @@ favorites_view_add= tv.alterna.Clock, org.eq.FotoToon, org.sugarlabs.AbacusActivity, - org.sugarlabs.PortfolioActivity + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph favorites_view_del= org.laptop.sugar.ReadActivity, org.laptop.TamTamSynthLab @@ -65,7 +62,6 @@ protected_activities= org.laptop.RecordActivity [sugarlabs_activities] -sugar_version=0.92 experimental=1 activities=org.laptop.HelpActivity, org.laptop.AbiWordActivity, @@ -107,10 +103,12 @@ activities=org.laptop.HelpActivity, tv.alterna.Clock, com.laptop.Ruler, org.sugarlabs.HelloWorld, - org.laptop.Words + org.laptop.Words, + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph [sugar_activities_extra] -url_1=http://dev.laptop.org/~reuben/scratch-19.xo +url_1=http://wiki.laptop.org/images/8/86/Scratch-23.xo url_6=http://dev.laptop.org/~gonzalo/Biology-10.xol url_7=http://wiki.laptop.org/images/7/77/Wikibooks-8.xol url_8=http://wiki.laptop.org/images/5/5e/NatureImages-8.xol diff --git a/examples/f14-xo1.ini b/examples/f18-xo1.ini index c291469..adb3c63 100644 --- a/examples/f14-xo1.ini +++ b/examples/f18-xo1.ini @@ -1,42 +1,40 @@ [global] -fedora_release=14 -olpc_version_major=11 -olpc_version_minor=3 +fedora_release=18 +fedora_arch=i386 +olpc_version_major=0 +olpc_version_minor=0 olpc_version_release=0 target_platform=XO-1 -langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de -modules= - base, - xo1, - buildnr_from_file, - yumcfg, - ubifs_image, - repos, - x11, - sugar, - sugarlabs_activities, - sugar_activities_extra, - gnome +langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de,hy + +[base] + +[xo1] + +[jffs2_image] [repos] -fedora_arch=i386 fedora=fedora,fedora-updates,fedora-updates-testing -olpc_publicrpms_1=1,f14 -olpc_publicrpms_2=1,f14-xo1 +olpc_publicrpms_1=1,f18 +olpc_publicrpms_2=1,f18-xo1 add_excludes_to=fedora,fedora-updates,fedora-updates-testing [yumcfg] -addrepo_1=1,olpc-f14,http://rpmdropbox.laptop.org/f14/ -addrepo_2=1,olpc-f14-xo1,http://rpmdropbox.laptop.org/f14-xo1/ -force_enable=fedora-updates-testing +addrepo_1=1,olpc-f18,http://rpmdropbox.laptop.org/f18/ +addrepo_2=1,olpc-f18-xo1,http://rpmdropbox.laptop.org/f18-xo1/ add_excludes_to=fedora,fedora-updates,fedora-updates-testing +[x11] + +[gnome] + [sugar] favorites_view_add= tv.alterna.Clock, org.eq.FotoToon, org.sugarlabs.AbacusActivity, - org.sugarlabs.PortfolioActivity + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph favorites_view_del= org.laptop.sugar.ReadActivity, org.laptop.TamTamSynthLab @@ -50,7 +48,6 @@ protected_activities= org.laptop.RecordActivity [sugarlabs_activities] -sugar_version=0.92 experimental=1 activities=org.laptop.AbiWordActivity, org.laptop.Oficina, @@ -83,10 +80,11 @@ activities=org.laptop.AbiWordActivity, tv.alterna.Clock, com.laptop.Ruler, org.sugarlabs.HelloWorld, - org.sugarlabs.PortfolioActivity + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph [sugar_activities_extra] -url_1=http://dev.laptop.org/~reuben/scratch-19.xo +url_1=http://wiki.laptop.org/images/8/86/Scratch-23.xo url_6=http://dev.laptop.org/~gonzalo/Biology-10.xol url_7=http://wiki.laptop.org/images/7/77/Wikibooks-8.xol url_8=http://wiki.laptop.org/images/5/5e/NatureImages-8.xol diff --git a/examples/f14-xo1.75.ini b/examples/f18-xo4.ini index 1ad1344..62fc8f6 100644 --- a/examples/f14-xo1.75.ini +++ b/examples/f18-xo4.ini @@ -1,38 +1,34 @@ [global] -fedora_release=14 -olpc_version_major=11 -olpc_version_minor=3 +fedora_release=18 +fedora_arch=armhfp +olpc_version_major=0 +olpc_version_minor=0 olpc_version_release=0 -target_platform=XO-1.75 -langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de -modules= - base, - xo1_75, - buildnr_from_file, - yumcfg, - sd_card_image, - repos, - x11, - sugar, - sugarlabs_activities, - sugar_activities_extra, - gnome +target_platform=XO-4 +langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de,hy + +[base] + +[xo4] [sd_card_image] -; 4GB image -size_1=3865470566,zd4 [repos] -fedora_arch=arm -fedora=fedora,fedora-updates -olpc_publicrpms_1=1,f14 -olpc_publicrpms_2=1,f14-xo1.75 -add_excludes_to=fedora,fedora-updates +fedora=fedora,fedora-updates-testing +olpc_publicrpms_1=1,f18 +olpc_publicrpms_2=1,f18-xo4 +add_excludes_to=fedora,fedora-updates-testing [yumcfg] -addrepo_1=1,olpc-f14,http://rpmdropbox.laptop.org/f14/ -addrepo_2=1,olpc-f14-xo1.75,http://rpmdropbox.laptop.org/f14-xo1.75/ -add_excludes_to=fedora,fedora-updates +addrepo_1=1,olpc-f18,http://rpmdropbox.laptop.org/f18/ +addrepo_2=1,olpc-f18-xo4,http://rpmdropbox.laptop.org/f18-xo4/ +add_excludes_to=fedora,fedora-updates,fedora-updates-testing + +[osk] + +[x11] + +[gnome] [sugar] favorites_view_add= @@ -51,7 +47,8 @@ favorites_view_add= tv.alterna.Clock, org.eq.FotoToon, org.sugarlabs.AbacusActivity, - org.sugarlabs.PortfolioActivity + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph favorites_view_del= org.laptop.sugar.ReadActivity, org.laptop.TamTamSynthLab @@ -65,7 +62,6 @@ protected_activities= org.laptop.RecordActivity [sugarlabs_activities] -sugar_version=0.92 experimental=1 activities=org.laptop.HelpActivity, org.laptop.AbiWordActivity, @@ -107,10 +103,12 @@ activities=org.laptop.HelpActivity, tv.alterna.Clock, com.laptop.Ruler, org.sugarlabs.HelloWorld, - org.laptop.Words + org.laptop.Words, + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph [sugar_activities_extra] -url_1=http://dev.laptop.org/~reuben/scratch-19.xo +url_1=http://wiki.laptop.org/images/8/86/Scratch-23.xo url_6=http://dev.laptop.org/~gonzalo/Biology-10.xol url_7=http://wiki.laptop.org/images/7/77/Wikibooks-8.xol url_8=http://wiki.laptop.org/images/5/5e/NatureImages-8.xol @@ -123,4 +121,3 @@ url_14=http://dev.laptop.org/~sj/WorldDigitalLibrary-5.xol [buildnr_from_file] path=latestbuild - diff --git a/examples/olpc-os-11.3.0-xo1.5.ini b/examples/olpc-os-13.1.0-xo1.5.ini index b1a223b..1ba43ce 100644 --- a/examples/olpc-os-11.3.0-xo1.5.ini +++ b/examples/olpc-os-13.1.0-xo1.5.ini @@ -1,45 +1,33 @@ [global] -suggested_oob_version=4.0 -fedora_release=14 -olpc_version_major=11 -olpc_version_minor=3 +fedora_release=18 +fedora_arch=i386 +olpc_version_major=13 +olpc_version_minor=1 olpc_version_release=0 target_platform=XO-1.5 -langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de -modules= - base, - xo1_5, - buildnr_from_file, - yumcfg, - sd_card_image, - usb_update, - repos, - x11, - sugar, - sugar_activity_group, - gnome +langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de,hy + +[base] + +[xo1_5] [sd_card_image] -; 8GB image -size_3=7730941132,zd8 -; 4GB image -size_1=3865470566,zd4 -; 2GB image -size_2=1932735283,zd2 [repos] -fedora_arch=i386 -olpc_frozen_1=0,koji.dist-f14-i686 -olpc_frozen_2=0,koji.dist-f14-i686-updates-11.3.0 -olpc_frozen_3=1,local.11.3.0 -olpc_frozen_4=1,local.11.3.0-xo1.5 -add_excludes_to=koji.dist-f14-i686,koji.dist-f14-i686-updates-11.3.0 +fedora=fedora,fedora-updates,fedora-updates-testing +olpc_publicrpms_1=1,f18 +olpc_publicrpms_2=1,f18-xo1.5 +add_excludes_to=fedora,fedora-updates,fedora-updates-testing [yumcfg] -addrepo_1=1,olpc-f14,http://rpmdropbox.laptop.org/f14/ -addrepo_2=1,olpc-f14-xo1.5,http://rpmdropbox.laptop.org/f14-xo1.5/ +addrepo_1=1,olpc-f18,http://rpmdropbox.laptop.org/f18/ +addrepo_2=1,olpc-f18-xo1.5,http://rpmdropbox.laptop.org/f18-xo1.5/ add_excludes_to=fedora,fedora-updates,fedora-updates-testing +[x11] + +[gnome] + [sugar] favorites_view_add= org.sugarlabs.InfoSlicer, @@ -57,7 +45,8 @@ favorites_view_add= tv.alterna.Clock, org.eq.FotoToon, org.sugarlabs.AbacusActivity, - org.sugarlabs.PortfolioActivity + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph favorites_view_del= org.laptop.sugar.ReadActivity, org.laptop.TamTamSynthLab @@ -75,4 +64,3 @@ url=http://wiki.laptop.org/go/Activities/G1G1 [buildnr_from_file] path=latestbuild - diff --git a/examples/olpc-os-11.3.0-xo1.75.ini b/examples/olpc-os-13.1.0-xo1.75.ini index cb3a5b7..3cfe750 100644 --- a/examples/olpc-os-11.3.0-xo1.75.ini +++ b/examples/olpc-os-13.1.0-xo1.75.ini @@ -1,42 +1,34 @@ [global] -suggested_oob_version=4.0 -fedora_release=14 -olpc_version_major=11 -olpc_version_minor=3 +fedora_release=18 +fedora_arch=armhfp +olpc_version_major=13 +olpc_version_minor=1 olpc_version_release=0 target_platform=XO-1.75 -langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de -modules= - base, - xo1_75, - buildnr_from_file, - yumcfg, - sd_card_image, - usb_update, - repos, - x11, - sugar, - sugar_activity_group, - gnome +langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de,hy + +[base] + +[xo1_75] [sd_card_image] -; 4GB image -size_1=3865470566,zd4 -; 8GB image -size_2=7730941132,zd8 [repos] -fedora_arch=arm -olpc_frozen_1=0,koji.dist-f14-armv5tel -olpc_frozen_2=0,koji.dist-f14-armv5tel-updates-11.3.0 -olpc_frozen_3=1,local.11.3.0 -olpc_frozen_4=1,local.11.3.0-xo1.75 -add_excludes_to=koji.dist-f14-armv5tel,koji.dist-f14-armv5tel-updates-11.3.0 +fedora=fedora,fedora-updates-testing +olpc_publicrpms_1=1,f18 +olpc_publicrpms_2=1,f18-xo1.75 +add_excludes_to=fedora,fedora-updates-testing [yumcfg] -addrepo_1=1,olpc-f14,http://rpmdropbox.laptop.org/f14/ -addrepo_2=1,olpc-f14-xo1.75,http://rpmdropbox.laptop.org/f14-xo1.75/ -add_excludes_to=fedora,fedora-updates +addrepo_1=1,olpc-f18,http://rpmdropbox.laptop.org/f18/ +addrepo_2=1,olpc-f18-xo1.75,http://rpmdropbox.laptop.org/f18-xo1.75/ +add_excludes_to=fedora,fedora-updates,fedora-updates-testing + +[osk] + +[x11] + +[gnome] [sugar] favorites_view_add= @@ -55,7 +47,8 @@ favorites_view_add= tv.alterna.Clock, org.eq.FotoToon, org.sugarlabs.AbacusActivity, - org.sugarlabs.PortfolioActivity + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph favorites_view_del= org.laptop.sugar.ReadActivity, org.laptop.TamTamSynthLab @@ -73,4 +66,3 @@ url=http://wiki.laptop.org/go/Activities/G1G1 [buildnr_from_file] path=latestbuild - diff --git a/examples/olpc-os-11.3.0-xo1.ini b/examples/olpc-os-13.1.0-xo1.ini index f990bfd..bd7a7a5 100644 --- a/examples/olpc-os-11.3.0-xo1.ini +++ b/examples/olpc-os-13.1.0-xo1.ini @@ -1,44 +1,40 @@ [global] -suggested_oob_version=4.0 -fedora_release=14 -olpc_version_major=11 -olpc_version_minor=3 +fedora_release=18 +fedora_arch=i386 +olpc_version_major=13 +olpc_version_minor=1 olpc_version_release=0 target_platform=XO-1 -langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de -modules= - base, - xo1, - buildnr_from_file, - yumcfg, - jffs2_image, - usb_update, - repos, - x11, - powerd, - sugar, - sugar_activity_group, - gnome +langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de,hy + +[base] + +[xo1] + +[jffs2_image] [repos] -fedora_arch=i386 -olpc_frozen_1=0,koji.dist-f14-i686 -olpc_frozen_2=0,koji.dist-f14-i686-updates-11.3.0 -olpc_frozen_3=1,local.11.3.0 -olpc_frozen_4=1,local.11.3.0-xo1 -add_excludes_to=koji.dist-f14-i686,koji.dist-f14-i686-updates-11.3.0 +fedora=fedora,fedora-updates,fedora-updates-testing +olpc_publicrpms_1=1,f18 +olpc_publicrpms_2=1,f18-xo1 +add_excludes_to=fedora,fedora-updates,fedora-updates-testing [yumcfg] -addrepo_1=1,olpc-f14,http://rpmdropbox.laptop.org/f14/ -addrepo_2=1,olpc-f14-xo1,http://rpmdropbox.laptop.org/f14-xo1/ +addrepo_1=1,olpc-f18,http://rpmdropbox.laptop.org/f18/ +addrepo_2=1,olpc-f18-xo1,http://rpmdropbox.laptop.org/f18-xo1/ add_excludes_to=fedora,fedora-updates,fedora-updates-testing +[x11] + +[gnome] + [sugar] favorites_view_add= tv.alterna.Clock, org.eq.FotoToon, org.sugarlabs.AbacusActivity, - org.sugarlabs.PortfolioActivity + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph favorites_view_del= org.laptop.sugar.ReadActivity, org.laptop.TamTamSynthLab @@ -54,10 +50,9 @@ protected_activities= [sugar_activity_group] url=http://wiki.laptop.org/go/Activities/G1G1Lite -[buildnr_from_file] -path=latestbuild - ; still too many open blockers for XO-1 idle suspend to work well [powerd] enable_idle_suspend=0 +[buildnr_from_file] +path=latestbuild diff --git a/examples/olpc-os-11.3.0-xo1.5.ini b/examples/olpc-os-13.1.0-xo4.ini index b1a223b..705520c 100644 --- a/examples/olpc-os-11.3.0-xo1.5.ini +++ b/examples/olpc-os-13.1.0-xo4.ini @@ -1,45 +1,35 @@ [global] -suggested_oob_version=4.0 -fedora_release=14 -olpc_version_major=11 -olpc_version_minor=3 +fedora_release=18 +fedora_arch=armhfp +olpc_version_major=13 +olpc_version_minor=1 olpc_version_release=0 -target_platform=XO-1.5 -langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de -modules= - base, - xo1_5, - buildnr_from_file, - yumcfg, - sd_card_image, - usb_update, - repos, - x11, - sugar, - sugar_activity_group, - gnome +target_platform=XO-4 +langs=en_US,en_AU,es,ar,pt,pt_BR,fr,ht,mn,mr_IN,am_ET,km_KH,ne_NP,ur_PK,rw,ps,fa_AF,si,zh_CN,de,hy + +[base] + +[xo4] [sd_card_image] -; 8GB image -size_3=7730941132,zd8 -; 4GB image -size_1=3865470566,zd4 -; 2GB image -size_2=1932735283,zd2 [repos] -fedora_arch=i386 -olpc_frozen_1=0,koji.dist-f14-i686 -olpc_frozen_2=0,koji.dist-f14-i686-updates-11.3.0 -olpc_frozen_3=1,local.11.3.0 -olpc_frozen_4=1,local.11.3.0-xo1.5 -add_excludes_to=koji.dist-f14-i686,koji.dist-f14-i686-updates-11.3.0 +fedora=fedora,fedora-updates-testing +olpc_publicrpms_1=1,f18 +olpc_publicrpms_2=1,f18-xo4 +add_excludes_to=fedora,fedora-updates-testing [yumcfg] -addrepo_1=1,olpc-f14,http://rpmdropbox.laptop.org/f14/ -addrepo_2=1,olpc-f14-xo1.5,http://rpmdropbox.laptop.org/f14-xo1.5/ +addrepo_1=1,olpc-f18,http://rpmdropbox.laptop.org/f18/ +addrepo_2=1,olpc-f18-xo4,http://rpmdropbox.laptop.org/f18-xo4/ add_excludes_to=fedora,fedora-updates,fedora-updates-testing +[osk] + +[x11] + +[gnome] + [sugar] favorites_view_add= org.sugarlabs.InfoSlicer, @@ -57,7 +47,8 @@ favorites_view_add= tv.alterna.Clock, org.eq.FotoToon, org.sugarlabs.AbacusActivity, - org.sugarlabs.PortfolioActivity + org.sugarlabs.PortfolioActivity, + org.sugarlabs.SimpleGraph favorites_view_del= org.laptop.sugar.ReadActivity, org.laptop.TamTamSynthLab @@ -75,4 +66,3 @@ url=http://wiki.laptop.org/go/Activities/G1G1 [buildnr_from_file] path=latestbuild - diff --git a/lib/ooblib.py b/lib/ooblib.py index a746c94..dc3fba6 100644 --- a/lib/ooblib.py +++ b/lib/ooblib.py @@ -2,7 +2,9 @@ # Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. import os +import sys import shutil +import hashlib import urllib2 from xml.etree.ElementTree import ElementTree @@ -17,6 +19,8 @@ fsmount = os.environ['OOB__fsmount'] METADATA_NS = "http://linux.duke.edu/metadata/common" +cacheonly = 'OOB__cacheonly' in os.environ + def read_config(module, option): vname = "CFG_%s__%s" % (module, option) if not vname in os.environ: @@ -35,27 +39,38 @@ def read_buildnr(): return "0" return open(buildnr_path, "r").readline().strip() +def read_laptop_model_number(): + path = os.path.join(intermediatesdir, 'laptop_model_number') + if not os.path.isfile(path): + return "0" + return open(path, "r").readline().strip() + def image_name(): - name_tmpl = read_config('global', 'image_name') - return name_tmpl % int(read_buildnr()) + major_ver = read_config('global', 'olpc_version_major') + minor_ver = read_config('global', 'olpc_version_minor') + cust_tag = read_config('global', 'customization_tag') + buildnr = int(read_buildnr()) + modelnr = read_laptop_model_number() + + return "%s%s%03d%s%s" % (major_ver, minor_ver, buildnr, cust_tag, modelnr) def arch_matches(myarch, arch): # figure out if a package under 'arch' is suitable for 'myarch' - # myarch is either 'i386' or 'arm' + # myarch is either 'i386', 'arm' or 'armhfp' # but 'arch' can be i386, i586, i686, armv5tel, armv7hl, and so on # noarch is always suitable if arch == 'noarch': return True - if myarch == 'arm': + if myarch.startswith('arm'): return arch.startswith('arm') elif myarch == 'i386': return arch in ['i386', 'i486', 'i586', 'i686'] else: return False -def add_packages_from_xml(fd, pkglist, myarch=None): +def add_packages_from_xml(fd, pkglist, myarch): et = ElementTree(file=fd) root = et.getroot() for i in root.getchildren(): @@ -88,7 +103,7 @@ def get_repomd(baseurl): url = "%s/repodata/repomd.xml" % baseurl try: - fd = urllib2.urlopen(url) + fd = cachedurlopen(url) et = ElementTree(file=fd) root = et.getroot() # iterate over data tags @@ -96,7 +111,7 @@ def get_repomd(baseurl): type = data.attrib['type'] location = data.find('{http://linux.duke.edu/metadata/repo}location') md[type] = location.attrib['href'] - except: + except urllib2.HTTPError: pass return md @@ -117,3 +132,31 @@ def install_sugar_bundle(path): os.makedirs(bundlesdir) ln_or_cp(path, bundlesdir) +""" A wrapper around urllib2.urlopen() that stores responses in + cache. When cacheonly=True, it works offline, never hitting + the network. +""" +def cachedurlopen(url): + class CachedURLException(Exception): + def __init__(self, value): + self.value=value + + cachedfpath = os.path.join(cachedir, 'simplecache', hashlib.sha1(url).hexdigest()) + if cacheonly: + if os.path.exists(cachedfpath): + return open(cachedfpath) + else: + print >>sys.stderr, "ERROR: No cached file for %s" % url + raise CachedURLException("No cached file for %s" % url) + + ourcachedir=os.path.join(cachedir, 'simplecache') + if not os.path.exists(ourcachedir): + os.makedirs(ourcachedir) + + urlfd = urllib2.urlopen(url) + fd = open(cachedfpath, 'w') + fd.write(urlfd.read()) + urlfd.close() + fd.close() + + return open(cachedfpath, 'r') diff --git a/lib/shlib.sh b/lib/shlib.sh index 5075154..4b3c476 100644 --- a/lib/shlib.sh +++ b/lib/shlib.sh @@ -7,16 +7,34 @@ libdir=$OOB__libdir bindir=$OOB__bindir builddir=$OOB__builddir cachedir=$OOB__cachedir +cacheonly=$OOB__cacheonly intermediatesdir=$OOB__intermediatesdir +shareddir=$OOB__shareddir outputdir=$OOB__outputdir statedir=$OOB__statedir fsmount=$OOB__fsmount +LAPTOP_MODEL_NUMBER=$shareddir/laptop_model_number + read_config() { local vname="CFG_$1__$2" echo ${!vname} } +find_option_values() { + local out=$1 + local module=$2 + local option=$3 + local prefix=CFG_${module}__${option} + + while IFS= read -r -d '' line; do + local name=${line%%=*} + local value=${line#*=} + [[ $name == $prefix || $name == ${prefix}_* ]] || continue + eval "$out+=('$value')" + done < <(env --null) +} + read_buildnr() { local buildnr_path=$intermediatesdir/buildnr if [[ -e $buildnr_path ]]; then @@ -26,9 +44,29 @@ read_buildnr() { fi } +set_laptop_model_number() +{ + echo $1 > $LAPTOP_MODEL_NUMBER +} + +read_laptop_model_number() +{ + if [[ -e $LAPTOP_MODEL_NUMBER ]]; then + echo "$(<$LAPTOP_MODEL_NUMBER)" + else + echo "0" + fi +} + image_name() { - local name_tmpl=$(read_config global image_name) - printf $name_tmpl $(read_buildnr) + local major_ver=$(read_config global olpc_version_major) + local minor_ver=$(read_config global olpc_version_minor) + local cust_tag=$(read_config global customization_tag) + local buildnr=$(read_buildnr) + local modelnr=$(read_laptop_model_number) + + buildnr=$(printf %03d "$buildnr") + echo "${major_ver: -1}${minor_ver}${buildnr}${cust_tag}${modelnr}" } # hard link a file, but fall-back on copy if a device boundary is being crossed @@ -48,4 +86,3 @@ install_sugar_bundle() { mkdir -p "$intermediatesdir/shared/sugar-bundles" ln_or_cp "$1" "$intermediatesdir/shared/sugar-bundles" } - diff --git a/modules/adobe_flash/README b/modules/adobe_flash/README index 4ce60e8..46750f6 100644 --- a/modules/adobe_flash/README +++ b/modules/adobe_flash/README @@ -1,6 +1,4 @@ This module installs Adobe Flash in the build. -There is no configuration, simply include this module in your configuration. - ***** WARNING ***** @@ -11,14 +9,29 @@ unless you have received special permission from Adobe. You can request such permission on the Adobe website. +For platforms where Adobe provides a Flash RPM package (x86, at the time of +writing), there is no configuration, simply include this module in your +configuration. + +For other platforms (e.g. ARM), you must specify the local filesystem path +to libflashplayer.so which you have obtained for your platform (ask OLPC for +info), as follows: + +[adobe_flash] +plugin_path=/path/to/libflashplayer.so + -While Flash is available as a standard Fedora RPM distributed by Adobe, it -breaks the rules of packaging and conditionally installs files based on the -package set present on the system at time of installation -- it only installs -the Mozilla plugin if Mozilla is installed prior to the installation of Flash. + + +== Notes on the Adobe Flash RPM == + +The standard Fedora RPM distributed by Adobe breaks the rules of packaging and +conditionally installs files based on the package set present on the system at +time of installation -- it only installs the plugin if the web browser is +installed prior to the installation of Flash. For this reason, if you simply add the Flash package as an extra package in -the build, it is possible (and likely?) to be installed before Mozilla, +the build, it is possible (and likely?) to be installed before the browser, meaning that Flash doesn't actually work in your resultant image, even though the RPM was included. @@ -26,4 +39,3 @@ The workaround is to use this module, which adds the Adobe repository to the build and yum repository configuration, includes the package in the build, and includes a small amount of hackery to make sure that the plugin installation is performed after installation of all other packages. - diff --git a/modules/adobe_flash/ksmain.50.adobe.inc b/modules/adobe_flash/ksmain.50.adobe.inc deleted file mode 100644 index 199e175..0000000 --- a/modules/adobe_flash/ksmain.50.adobe.inc +++ /dev/null @@ -1 +0,0 @@ -repo --name=adobe --baseurl=http://linuxdownload.adobe.com/linux/i386/ diff --git a/modules/adobe_flash/ksmain.50.adobe.sh b/modules/adobe_flash/ksmain.50.adobe.sh new file mode 100644 index 0000000..3cf38ea --- /dev/null +++ b/modules/adobe_flash/ksmain.50.adobe.sh @@ -0,0 +1,11 @@ +# Copyright (C) 2012 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib + +# Only include the repo when a local plugin hasn't been provided + +path=$(read_config adobe_flash plugin_path) +[ -n "$path" ] && exit 0 + +echo "repo --name=adobe --baseurl=http://linuxdownload.adobe.com/linux/i386/" diff --git a/modules/adobe_flash/kspkglist.50.adobeflash.inc b/modules/adobe_flash/kspkglist.50.adobeflash.inc deleted file mode 100644 index 739a7c1..0000000 --- a/modules/adobe_flash/kspkglist.50.adobeflash.inc +++ /dev/null @@ -1,2 +0,0 @@ -flash-plugin - diff --git a/modules/adobe_flash/kspkglist.50.adobeflash.sh b/modules/adobe_flash/kspkglist.50.adobeflash.sh new file mode 100644 index 0000000..ed4aa90 --- /dev/null +++ b/modules/adobe_flash/kspkglist.50.adobeflash.sh @@ -0,0 +1,10 @@ +# Copyright (C) 2012 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib + +# Only install the package when a local plugin hasn't been provided +path=$(read_config adobe_flash plugin_path) +[ -n "$path" ] && exit 0 + +echo "flash-plugin" diff --git a/modules/adobe_flash/kspkglist.60.adobeflash.inc b/modules/adobe_flash/kspkglist.60.adobeflash.inc new file mode 100644 index 0000000..40c8a62 --- /dev/null +++ b/modules/adobe_flash/kspkglist.60.adobeflash.inc @@ -0,0 +1,4 @@ +# Must be run after any modules that install gnash-plugin (gnome, sugar) +-gnash-plugin + +nspluginwrapper diff --git a/modules/adobe_flash/kspost.50.adoberepo.inc b/modules/adobe_flash/kspost.50.adoberepo.inc deleted file mode 100644 index b3e9161..0000000 --- a/modules/adobe_flash/kspost.50.adoberepo.inc +++ /dev/null @@ -1,11 +0,0 @@ -# Install yum repo entry for Adobe repo - -cat <<EOF >/etc/yum.repos.d/adobe-linux-i386.repo -[adobe-linux-i386] -name=Adobe Systems Incorporated -baseurl=http://linuxdownload.adobe.com/linux/i386/ -enabled=1 -gpgcheck=1 -gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-adobe-linux -EOF - diff --git a/modules/adobe_flash/kspost.50.adoberepo.nochroot.inc b/modules/adobe_flash/kspost.50.adoberepo.nochroot.inc new file mode 100644 index 0000000..a0a1b42 --- /dev/null +++ b/modules/adobe_flash/kspost.50.adoberepo.nochroot.inc @@ -0,0 +1,16 @@ +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib + +# Install yum repo entry for Adobe repo when we get the package from there +path=$(read_config adobe_flash plugin_path) +[ -n "$path" ] && exit 0 + +cat <<EOF >$INSTALL_ROOT/etc/yum.repos.d/adobe-linux-i386.repo +[adobe-linux-i386] +name=Adobe Systems Incorporated +baseurl=http://linuxdownload.adobe.com/linux/i386/ +enabled=1 +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-adobe-linux +EOF diff --git a/modules/adobe_flash/kspost.50.flashinstall.inc b/modules/adobe_flash/kspost.50.flashinstall.inc deleted file mode 100644 index 652f097..0000000 --- a/modules/adobe_flash/kspost.50.flashinstall.inc +++ /dev/null @@ -1,4 +0,0 @@ -# Run Adobe install script (basically the point of this module) -# see README for an explanation of why this is necessary -/usr/lib/flash-plugin/setup - diff --git a/modules/adobe_flash/kspost.50.flashinstall.nochroot.inc b/modules/adobe_flash/kspost.50.flashinstall.nochroot.inc new file mode 100644 index 0000000..c265ebe --- /dev/null +++ b/modules/adobe_flash/kspost.50.flashinstall.nochroot.inc @@ -0,0 +1,10 @@ +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib + +# Install locally-provided flash plugin +path=$(read_config adobe_flash plugin_path) +[ -n "$path" ] || exit 0 + +mkdir -p $INSTALL_ROOT/usr/lib/mozilla/plugins +cp -v $path $INSTALL_ROOT/usr/lib/mozilla/plugins/libflashplayer.so diff --git a/modules/adobe_flash/kspost.51.flashinstall.inc b/modules/adobe_flash/kspost.51.flashinstall.inc new file mode 100644 index 0000000..8578edd --- /dev/null +++ b/modules/adobe_flash/kspost.51.flashinstall.inc @@ -0,0 +1,18 @@ +# Run Adobe install script (basically the point of this module) +# see README for an explanation of why this is necessary +[ -e /usr/lib/flash-plugin/setup ] && /usr/lib/flash-plugin/setup 32 + +# nspluginwrapper is needed at this time, because libflashplayer links +# against GTK2 but our browser (Browse/Epiphany) is GTK3. +# nspluginwrapper provides a process separation model that avoids fatally +# mixing GTK2/GTK3 symbols in the same process. +# +# Moving to WebKit2 will solve this problem, because it moves plugins into +# their own process. When we move to WebKit2 we will be able to drop +# nspluginwrapper. +# +# Delete all already-wrapped plugins, and only wrap libflashplayer +rm -f /usr/lib/mozilla/plugins-wrapped/nswrapper*.so +/usr/lib/nspluginwrapper/npconfig -n -p nswrapper_32_32 \ + -d /usr/lib/mozilla/plugins-wrapped \ + -i /usr/lib/mozilla/plugins/libflashplayer.so diff --git a/modules/base/README b/modules/base/README index b8b2fe9..c7ad73a 100644 --- a/modules/base/README +++ b/modules/base/README @@ -43,3 +43,26 @@ Set the default timezone for the build. This can be later overridden by the user in the Sugar control panel. The value should be an entry from /usr/share/zoneinfo e.g. America/Managua +- default_language (default unset) +Override the default language used in the build. Normally, the language +is automatically detected from the manufacturing data of the laptop on first +boot. Only set this if you know of a good reason that you want to override +the factory-programmed default. + +- default_kbd_model (default unset) +Override the default XKB keyboard model used in the build. Normally, keyboard +settings are automatically detected from the manufacturing data of the laptop +on first boot. Only set this if you know of a good reason that you want to +override the factory-programmed default. + +- default_kbd_layout (default unset) +Override the default XKB keyboard layout used in the build. Normally, keyboard +settings are automatically detected from the manufacturing data of the laptop +on first boot. Only set this if you know of a good reason that you want to +override the factory-programmed default. + +- default_kbd_variant (default unset) +Override the default XKB keyboard variant used in the build. Normally, keyboard +settings are automatically detected from the manufacturing data of the laptop +on first boot. Only set this if you know of a good reason that you want to +override the factory-programmed default. diff --git a/modules/base/build.40.imagecreate.py b/modules/base/build.40.imagecreate.py index d23095a..b325041 100644 --- a/modules/base/build.40.imagecreate.py +++ b/modules/base/build.40.imagecreate.py @@ -23,14 +23,18 @@ def main(): make_iso = ooblib.read_config_bool('base', 'make_iso') if make_iso: print "Building ISO image..." - creator = imgcreate.LiveImageCreator(ks, name, name) + creator = imgcreate.LiveImageCreator(ks, name, name, + tmpdir=ooblib.builddir, + cacheonly=ooblib.cacheonly) compress = ooblib.read_config_bool('base', 'compress_iso') if compress is None: compress = False creator.skip_compression = not compress else: print "Building directly into FS image..." - creator = imgcreate.LoopImageCreator(ks, 'imgcreatefs', name) + creator = imgcreate.LoopImageCreator(ks, 'imgcreatefs', name, + tmpdir=ooblib.builddir, + cacheonly=ooblib.cacheonly) try: creator.mount(cachedir=cache_dir) diff --git a/modules/base/defaults.ini b/modules/base/defaults.ini index 9410d87..d078512 100644 --- a/modules/base/defaults.ini +++ b/modules/base/defaults.ini @@ -4,7 +4,7 @@ olpc_version_major=0 olpc_version_minor=0 olpc_version_release=0 target_platform=XO -image_name=os%%d +customization_tag=xx ; please don't set official=1 unless you really are OLPC ; we're just trying to reduce confusion by ensuring that builds that are made diff --git a/modules/base/ksmain.10.core.inc b/modules/base/ksmain.10.core.inc index 0e7c39e..2ecf5ea 100644 --- a/modules/base/ksmain.10.core.inc +++ b/modules/base/ksmain.10.core.inc @@ -4,6 +4,5 @@ auth --useshadow --enablemd5 selinux --disabled firewall --disabled xconfig --startxonboot -part / --size 4096 --fstype=ext3 -services --enabled=avahi-daemon,crond,messagebus,NetworkManager --disabled=dnsmasq,ip6tables,iptables,mdmonitor,netfs,network,sshd - +part / --size 4096 --fstype=ext4 +services --enabled=crond,olpc-dm,olpc-configure,olpc-boot-finish,plymouth-shutdown-wait,powerd,olpc-kbdshim,olpc-switchd,runin-check --disabled=dnsmasq,ip6tables,iptables,mdmonitor,netfs,network,sshd diff --git a/modules/base/kspkglist.10.core.inc b/modules/base/kspkglist.10.core.inc index 2fa23bc..a208eb8 100644 --- a/modules/base/kspkglist.10.core.inc +++ b/modules/base/kspkglist.10.core.inc @@ -16,6 +16,7 @@ rpm yum tree nano +less # basic debugging strace @@ -23,7 +24,7 @@ strace # OLPC technologies and customization packages olpc-utils olpc-netutils -olpc-bootanim +plymouth-theme-olpc PolicyKit-olpc ds-backup-client olpc-powerd diff --git a/modules/base/kspost.05.mount_shared.nochroot.sh b/modules/base/kspost.05.mount_shared.nochroot.sh index cad30f4..012b86e 100644 --- a/modules/base/kspost.05.mount_shared.nochroot.sh +++ b/modules/base/kspost.05.mount_shared.nochroot.sh @@ -3,9 +3,7 @@ . $OOB__shlib -# create a "shared" intermediates directory which is also available at -# /build_shared from inside the image -mkdir -p $intermediatesdir/shared +# share the intermediates/shared directory at /build_shared inside the +# image build environment. echo "mkdir -p \$INSTALL_ROOT/build_shared" -echo "mount --bind $intermediatesdir/shared \$INSTALL_ROOT/build_shared" - +echo "mount --bind $shareddir \$INSTALL_ROOT/build_shared" diff --git a/modules/base/kspost.10.core.inc b/modules/base/kspost.10.core.inc index 36f234d..6a26c7a 100644 --- a/modules/base/kspost.10.core.inc +++ b/modules/base/kspost.10.core.inc @@ -1,6 +1,4 @@ -# from the liveuser script -# and add /ofw -# and limit tmpfs mounts to 5% +# limit tmpfs mounts to 5% cat >> /etc/fstab <<EOF /tmp /tmp tmpfs rw,size=50m 0 0 vartmp /var/tmp tmpfs rw,size=50m 0 0 @@ -12,7 +10,7 @@ mkdir /bootpart # create olpc user # Provide access to ttyUSB nodes (#8434) -/usr/sbin/useradd -m -c "olpc user" -G audio,wheel,uucp,video,dialout olpc +/usr/sbin/useradd -m -c "olpc user" -G audio,wheel,uucp,video,dialout,lock olpc /usr/bin/passwd -d olpc # make sure to own home directory and relax permissions a little @@ -54,10 +52,10 @@ SYSFONT=sun12x22 __EOF__ # OLPC custom VT layout and serial console setup (#9517, #10354) -sed -i -e 's/mingetty/mingetty --loginpause --autologin root --noclear/' \ - /etc/init/tty.conf -sed -i -e 's:ACTIVE_CONSOLES=/dev/tty\[1-6\]:ACTIVE_CONSOLES=/dev/tty[1-3]:' \ - /etc/sysconfig/init +sed -i -e 's:/sbin/agetty.*:/sbin/agetty --login-pause --autologin root --noclear %I:' \ + /lib/systemd/system/getty\@.service +sed -i -e 's:/sbin/agetty.*:/sbin/agetty -L -l /bin/bash -w -n %I 115200 vt100:' \ + /lib/systemd/system/serial-getty\@.service # Enable tmpfs mounts dictated by rwtab (#9637) mkdir -p /security/state @@ -68,12 +66,22 @@ sed -i -e 's/TEMPORARY_STATE=no/TEMPORARY_STATE=yes/' \ # Remove resolv.conf from rwtab so that it can be updated atomically (#2748) sed -i -e "/resolv.conf/d" /etc/rwtab +# also remove /tmp, /var/log and /var/tmp from rwtab, since we put them in fstab +sed -i -e '/\t\/tmp/d' /etc/rwtab +sed -i -e '/\t\/var\/tmp/d' /etc/rwtab +sed -i -e '/\t\/var\/log/d' /etc/rwtab + +# remove entries from rwtab that we put it in statetab below +sed -i -e '/\t\/var\/lib\/random-seed/d' /etc/rwtab +sed -i -e '/\t\/var\/lib\/dbus/d' /etc/rwtab + # ensure temporary state directory doesn't get too fat (#9636) sed -i -e 's/RW_OPTIONS=/RW_OPTIONS="-o size=1M -o nr_inodes=1024"/' /etc/sysconfig/readonly-root # Things to store separately in persistent storage # This means these files can be writable at runtime without breaking the -# pristine-ness of /versions/pristine +# pristine-ness of /versions/pristine. It also means they are retained +# over upgrades. cat >/etc/statetab.d/olpc <<EOF /etc/ssh /etc/sysconfig/i18n @@ -81,17 +89,33 @@ cat >/etc/statetab.d/olpc <<EOF /etc/timezone /var/lib/dbus /var/lib/random-seed +/etc/NetworkManager/system-connections EOF +# make sure statetab is set up before recording a random seed during boot +# https://bugzilla.redhat.com/show_bug.cgi?id=808907 +sed -i -e '/Before=/ s/$/ systemd-random-seed-load.service/' /lib/systemd/system/fedora-readonly.service + +# systemd stuff that is not interesting for us +# random-seed-save: we are interested in saving a random seed, but +# systemd actually does that during boot at systemd-random-seed-load time. +# that is sufficient for our needs, and works around the shutdown issue +# described at https://bugzilla.redhat.com/show_bug.cgi?id=808907#c7 +for i in fedora-loadmodules mdmonitor-takeover systemd-readahead-collect \ + fedora-wait-storage fedora-storage-init fedora-storage-init-late \ + fedora-autorelabel fedora-autorelabel-mark systemd-random-seed-save; do + ln -s /dev/null /etc/systemd/system/$i.service +done + #prefdm tweaks -sed -i -e 's/respawn limit 10/respawn limit 3/' /etc/init/prefdm.conf +#sed -i -e 's/respawn limit 10/respawn limit 3/' /etc/init/prefdm.conf -cat >>/etc/init/prefdm.conf <<EOF +#cat >>/etc/init/prefdm.conf <<EOF # make sure dcon is unfrozen if something goes wrong. -post-stop script - echo 0 > /sys/devices/platform/dcon/freeze -end script -EOF +#post-stop script +# echo 0 > /sys/devices/platform/dcon/freeze +#end script +#EOF # OLPC CA certificate (#9624) # this is used by wget, but the Web activity uses cert8.db in its own @@ -156,12 +180,6 @@ rm -f /etc/avahi/etc/localtime # kill a load of non-interesting anacron tasks (#10247) chmod -x /etc/cron.daily/logrotate -chmod -x /etc/cron.weekly/99-raid-check - -# suppress generation of certain SSH host keys in the same way we did -# it on XO-1 builds, so as to reduce first boot time by several -# seconds (#9964) -echo "AUTOCREATE_SERVER_KEYS=RSAONLY" >> /etc/sysconfig/sshd # Fedora's initscripts packages writes /etc/adjtime without a 3rd line, # which makes hwclock assume that the hardware clock has local time. @@ -181,7 +199,52 @@ find / -xdev -type f -perm 000 -exec chmod 400 {} + # source code as of time of writing) are not utilised. find /var/lib/yum/yumdb -type f -name 'from_repo_revision' -delete -o -name 'from_repo_timestamp' -delete -# enable sysrq by default during development cycle -# possibly useful for debugging phantom hangs -sed -i -e 's/kernel.sysrq = 0/kernel.sysrq = 1/' /etc/sysctl.conf - +# enable sysrq by default, possibly useful for debugging phantom hangs +echo "kernel.sysrq = 1" > /usr/lib/sysctl.d/10-olpc.conf + +# disable NetworkManager's rh-ifcfg plugin (#9789) +# this ensures that network configs are stored in +# /etc/NetworkManager/system-connections, which is a path that we can safely +# put in statetab. (the rh-ifcfg path in /etc/sysconfig mixes code with data +# and is hence not appropriate to retain over upgrades) +sed -i -e 's/^plugins=ifcfg-rh$/plugins=keyfile/g' /etc/NetworkManager/NetworkManager.conf + +# set default plymouth theme +# we do this with plymouthd.defaults so that plymouth-set-default-theme +# could be run by the user at another point in the build process, ensuring +# that the user preference (if specified) sticks. +sed -i -e 's/Theme=.*/Theme=olpc/g' /usr/share/plymouth/plymouthd.defaults + +# disable plymouth-start service: we start plymouthd from the initramfs +# with some special settings +ln -s /dev/null /etc/systemd/system/plymouth-start.service + +# apply some special settings in the other plymouth service files until +# we have a better solution. +# https://bugs.freedesktop.org/show_bug.cgi?id=22239 +sed -i -e 's/plymouthd --mode=shutdown/plymouthd --mode=shutdown "--kernel-command-line=rhgb plymouth.ignore-serial-consoles"/g' /lib/systemd/system/plymouth-poweroff.service +sed -i -e 's/plymouthd --mode=shutdown/plymouthd --mode=shutdown "--kernel-command-line=rhgb plymouth.ignore-serial-consoles"/g' /lib/systemd/system/plymouth-halt.service +sed -i -e 's/plymouthd --mode=shutdown/plymouthd --mode=shutdown "--kernel-command-line=rhgb plymouth.ignore-serial-consoles"/g' /lib/systemd/system/plymouth-reboot.service + +# remove the boot-duration file since it gets changed during boot (#11862) +rm -f /var/lib/plymouth/boot-duration + +# call olpc-logrotate when log file hits 1mb (#10075) +sed -i -e 's,/var/log/messages,:omfile:$messages,' \ + -e '/$messages/ i$outchannel messages,/var/log/messages,1048576,/usr/sbin/olpc-logrotate' \ + /etc/rsyslog.conf + +# tweak upower behaviour, mostly to ignore lid events (#11815) +sed -i -e 's/EnableWattsUpPro=true/EnableWattsUpPro=false/' \ + -e 's/IgnoreLid=false/IgnoreLid=true/' \ + /etc/UPower/UPower.conf + +# Tracker has snuck in and is autostarted by default. +# I don't think we want this. +# https://bugzilla.redhat.com/show_bug.cgi?id=821952 +rm -f /etc/xdg/autostart/tracker*.desktop 2>/dev/null + +# wtmp updating is racy on shutdown (#11952) +# Disable it, it's not interesting for us +rm -f /var/log/wtmp +ln -s /dev/null /etc/systemd/system/systemd-update-utmp-shutdown.service diff --git a/modules/base/kspost.10.version_number.sh b/modules/base/kspost.10.version_number.sh index 8692b62..c3a37d9 100644 --- a/modules/base/kspost.10.version_number.sh +++ b/modules/base/kspost.10.version_number.sh @@ -21,6 +21,8 @@ if [[ "$official" != "1" ]]; then custbstr="$custinfo" fi +buildstr="$majver.$minver.$relver for ${platform}${custstr} (build $buildnr)" + cat <<EOF # needed for spin debranding echo "OLPC release $majver (based on Fedora $fver)" > /etc/fedora-release @@ -28,9 +30,9 @@ echo "OLPC release $majver (based on Fedora $fver)" > /etc/fedora-release # this is used by the activity updater echo "$majver.$minver.$relver" > /etc/olpc-release -sed -i -e "1s/.*/OLPC OS $majver.$minver.$relver for ${platform}${custstr} (build $buildnr)/" /etc/issue +sed -i -e "1s/.*/OLPC OS $buildstr/" /etc/issue cp /etc/issue /etc/issue.net -echo "${buildnr}${custbstr}" > /boot/olpc_build +echo "${buildstr}" > /boot/olpc_build EOF diff --git a/modules/base/kspost.50.lang_kbd_overrides.sh b/modules/base/kspost.50.lang_kbd_overrides.sh new file mode 100644 index 0000000..6e4263c --- /dev/null +++ b/modules/base/kspost.50.lang_kbd_overrides.sh @@ -0,0 +1,22 @@ +# Copyright (C) 2012 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib + +default_lang=$(read_config base default_language) +default_kbd_model=$(read_config base default_kbd_model) +default_kbd_variant=$(read_config base default_kbd_variant) +default_kbd_layout=$(read_config base default_kbd_layout) +[ -z "$default_lang" ] && [ -z "$default_kbd_model" ] && \ + [ -z "$default_kbd_variant" ] && [ -z "$default_kbd_layout" ] && \ + exit 0 + +echo "mkdir -p /etc/olpc-configure" +[ -n "$default_lang" ] && \ + echo "echo '$default_lang' > /etc/olpc-configure/default-language" +[ -n "$default_kbd_model" ] && \ + echo "echo '$default_kbd_model' > /etc/olpc-configure/default-kbd-model" +[ -n "$default_kbd_variant" ] && \ + echo "echo '$default_kbd_variant' > /etc/olpc-configure/default-kbd-variant" +[ -n "$default_kbd_layout" ] && \ + echo "echo '$default_kbd_layout' > /etc/olpc-configure/default-kbd-layout" diff --git a/modules/base/kspost.50.stripdebug.nochroot.inc b/modules/base/kspost.50.stripdebug.nochroot.inc new file mode 100644 index 0000000..cc1c36f --- /dev/null +++ b/modules/base/kspost.50.stripdebug.nochroot.inc @@ -0,0 +1,5 @@ +find $INSTALL_ROOT/usr/{sbin,bin,lib,libexec} -xdev -type f -and ! -name '*.ko' | while read file; do + ftype=$(file -b "$file") + [ "${ftype:0:4}" = "ELF " ] && strip -R .gnu_debugdata "$file" || : +done +exit 0 diff --git a/modules/base/kspost.50.zip_bootfiles.nochroot.inc b/modules/base/kspost.50.zip_bootfiles.nochroot.inc new file mode 100644 index 0000000..31cd84b --- /dev/null +++ b/modules/base/kspost.50.zip_bootfiles.nochroot.inc @@ -0,0 +1,76 @@ +. $OOB__shlib + +# Put the unsigned kernel/initramfs in zip files and remove the originals +# This avoids duplication for signed builds (where these zips will be signed +# later), where otherwise we would be shipped both signed and unsigned kernels +# and losing some disk space. + +suffix=$(read_laptop_model_number) + +# Create zip files +create_unsigned_zip() { + local infile=$1 + local tgt=${2}${suffix} + + cd $INSTALL_ROOT/boot + [ -e $1 ] || return + + cp $1 data.img + zip -j -n .img ${tgt}.zip data.img + rm -f data.img +} + +create_unsigned_zip vmlinuz runos +create_unsigned_zip initrd.img runrd +create_unsigned_zip actrd.img actrd + +# Remove original copies +remove_original() { + local name=$1 + + cd $INSTALL_ROOT/boot + [ -e "$name" ] || return + + if [ -L "$name" ]; then + dest=$(readlink $name) + rm -rf "$dest" + fi + + rm -f $name +} + +#remove_original vmlinuz +#remove_original actrd.img +#remove_original initrd.img + +# symlink actXX to runXX (or the other way) if any of them are missing +create_missing() { + local dest=${1}${suffix}.zip + local source=${2}${suffix}.zip + + [ -e $INSTALL_ROOT/boot/$dest ] && return 0 + ln -s $source $INSTALL_ROOT/boot/$dest +} +create_missing actos runos +create_missing actrd runrd +create_missing runos actos +create_missing runrd actrd + + +create_compat() { + local compat=${1}.zip + local dest=${1}${suffix}.zip + + [ -e $INSTALL_ROOT/boot/${dest} ] || return 0 + ln -s $dest $INSTALL_ROOT/boot/$compat +} + +# Some old, released firmware versions for XO-1 and XO-1.5 don't support the +# new "versioned" zip file naming scheme. Create symlinks to the old names +# for backwards compatibility. +if [ "$suffix" -lt 3 ]; then + create_compat actos + create_compat actrd + create_compat runos + create_compat runrd +fi diff --git a/modules/base/preimage.90.core.sh b/modules/base/preimage.90.core.sh index bc8ba2a..53f991c 100644 --- a/modules/base/preimage.90.core.sh +++ b/modules/base/preimage.90.core.sh @@ -121,7 +121,7 @@ if [ "$versioned_fs" = "1" ]; then done mkdir -p $fsmount/versions/pristine/$buildnr/{versions,home,security} - mkdir -p $fsmount/{sys,proc,ofw,dev} + mkdir -p $fsmount/{sys,proc,dev} echo "Generating contents manifest..." chroot $fsmount/versions/pristine/$buildnr /usr/sbin/olpc-contents-create -f /.xo-files -p /etc/passwd -g /etc/group / diff --git a/modules/base/prepare.05.selinux.sh b/modules/base/prepare.05.selinux.sh new file mode 100644 index 0000000..a49a037 --- /dev/null +++ b/modules/base/prepare.05.selinux.sh @@ -0,0 +1,25 @@ +# Copyright (C) 2012 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. +# +# SELinux causes problems when enabled, e.g. rpm %post scripts fail inside the +# install root. +# http://thread.gmane.org/gmane.linux.redhat.fedora.livecd/4922 +# +# If it is enforcing, set it into permissive mode. Anaconda does similarly: +# https://www.redhat.com/archives/anaconda-devel-list/2012-May/msg00315.html + +[ -x /usr/sbin/getenforce ] || exit 0 + +mode=$(getenforce) +[ "$mode" = "Enforcing" ] || exit 0 + +setenforce 0 +echo +echo "SELinux was found enabled on your system, in enforcing mode." +echo "SELinux is incompatible with olpc-os-builder." +echo +echo "It has been temporarily set to permissive mode to avoid this incompatibility." +echo "It will be re-enabled upon reboot, or alternatively you can re-enable " +echo "it yourself, after olpc-os-builder has completed." +echo +sleep 5 diff --git a/modules/bootanim/README b/modules/bootanim/README index 706baf5..9813709 100644 --- a/modules/bootanim/README +++ b/modules/bootanim/README @@ -1,28 +1,28 @@ -This module replaces the default OLPC boot animation images with your own. +This module allows customization of the OLPC boot animation. +There are two modes of customization available. -To use... +Firstly, you can add your own PNG image to the boot animation display. It +will be displayed at the bottom of the screen, center-aligned. Simply specify +the path to the file in the following manner: - - Install netpbm-progs +[bootanim] +custom_image=/path/to/custom/image - - Install the appropriate version of olpc-bootanim-tools from - http://xs-dev.laptop.org/~dsd/repos/ - - Download the relevant olpc-bootanim tarball from - http://dev.laptop.org/pub/source/olpc-bootanim/ - -- extract the images from the "images" subdirectory - - Prepare an images directory with your customized images -- the relevant - files are the frame*.png files and ul_warning.png . You must include them - all in your custom images directory. +Alternatively, if you wish to perform deeper customizations, you can include +your own plymouth theme and use it instead of the OLPC default. Plymouth is the +platform which the boot animation is built upon. It allows creation of boot +themes through a simple scripting language. +See the Plymouth theming guide (http://brej.org/blog/?p=158) for how to get +started. - - Add a section to your ini file: +If going down this route, you will first need to get your theme included +in the build image. You could package it in RPM format and use the +custom_packages module to include it. - [bootanim] - imgdir=/path/to/your/images-directory - - for example, if it is a 'bootanim' directory next to your - ini file, use - - [bootanim] - imgdir=%(oob_config_dir)s/bootanim +Then, simply specify the name of the theme in the configuration of this +module: +[bootanim] +theme=mytheme diff --git a/modules/bootanim/kspost.30.nochroot.bootanim.sh b/modules/bootanim/kspost.30.nochroot.bootanim.sh index 769392c..187eb19 100644 --- a/modules/bootanim/kspost.30.nochroot.bootanim.sh +++ b/modules/bootanim/kspost.30.nochroot.bootanim.sh @@ -3,12 +3,13 @@ . $OOB__shlib -cache=$cachedir/bootanim +custom_image=$(read_config bootanim custom_image) +theme=$(read_config bootanim theme) -STATIC_IMAGES="frame00.565 ul_warning.565" -FILES="$STATIC_IMAGES deltas" +if [ -n "$custom_image" ]; then + echo "cp $custom_image \$INSTALL_ROOT/usr/share/plymouth/themes/olpc/custom.png" +fi -for f in $FILES; do - echo "cp $cache/$f \$INSTALL_ROOT/usr/share/boot-anim/" -done -echo 'chmod 644 $INSTALL_ROOT/usr/share/boot-anim/*' +if [ -n "$theme" ]; then + echo "/usr/sbin/plymouth-set-default-theme $theme" +fi diff --git a/modules/bootanim/prepare.90.bootanim.sh b/modules/bootanim/prepare.90.bootanim.sh deleted file mode 100644 index ae651be..0000000 --- a/modules/bootanim/prepare.90.bootanim.sh +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (C) 2011 One Laptop Per Child -# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. - -. $OOB__shlib - -imgdir=$(read_config bootanim imgdir) -cache=$cachedir/bootanim -cacheframes=$cachedir/bootanim-frames - -STATIC_IMAGES="frame00.png ul_warning.png" -FRAME_IMAGES="frame00.png frame01.png frame02.png frame03.png - frame04.png frame05.png frame06.png frame07.png frame08.png frame09.png - frame10.png frame11.png frame12.png frame13.png frame14.png frame15.png - frame16.png frame17.png frame18.png frame19.png frame20.png frame21.png - frame22.png frame23.png frame24.png frame25.png ul_warning.png" - -if [ -n "$imgdir" -a -e "$imgdir" ]; then - if [ ! -x '/usr/bin/ppmto565.py' -o ! -x '/usr/bin/calcdelta' ]; then - echo Please install olpc-bootanim-tools >&2 - exit 1 - fi - if [ ! -x '/usr/bin/pngtopnm' ]; then - echo Please install netpbm-progs >&2 - exit 1 - fi - mkdir -p "$cache" - mkdir -p "$cacheframes" - for img in $STATIC_IMAGES; do - src=$imgdir/$img - target=$cache/${img%.*}.565 - - # like make - if [ ! -e "$target" -o "$src" -nt "$target" ];then - echo "Processing $src" - pngtopnm "$src" | ppmto565.py -o "$target.tmp" - mv "$target.tmp" "$target" - fi - done - - rebuilddelta=0 - for img in $FRAME_IMAGES; do - src=$imgdir/$img - target=$cacheframes/${img%.*}.565 - - # like make - if [ ! -e "$target" -o "$src" -nt "$target" ];then - echo "Processing $src" - pngtopnm "$src" | ppmto565.py -o "$target.tmp" - mv "$target.tmp" "$target" - rebuilddelta=1 - fi - done - if [ "$rebuilddelta" == 1 -o ! -e "$cache/deltas" ];then - echo "Creating delta sequence" - # unfortunately, - tmpdir="/tmp/oob_bootanim.$$" - mkdir -p "$tmpdir" - pushd "$tmpdir" - for img in $FRAME_IMAGES; do - echo $cacheframes/${img%.*}.565 >> frames - done - # calcdelta reads a 'frames' file listing - # the files to process - echo calcdelta frames - calcdelta frames - mv deltas $cache/ - popd - rm -fr "$tmpdir" - fi -fi diff --git a/modules/custom_packages/README b/modules/custom_packages/README index d7feb96..f32be42 100644 --- a/modules/custom_packages/README +++ b/modules/custom_packages/README @@ -1,9 +1,15 @@ This module allows you to specify a comma-separated list of packages to add -to the build, from the repositories already configured (usually through the -repos module). +or remove from the build, from the repositories already configured (usually +through the repos module). + +Options must be named "add_packages" or "del_packages", or you may also +use option names prefixed with "add_packages_" and "del_packages_". + Example: [custom_packages] -add_packages=tomboy,gnucash,pidgin +add_packages=tomboy,gnucash +add_packages_extras=pidgin +del_packages=totem diff --git a/modules/custom_packages/kspkglist.70.extras.sh b/modules/custom_packages/kspkglist.70.extras.sh index a804e09..9aff5f1 100644 --- a/modules/custom_packages/kspkglist.70.extras.sh +++ b/modules/custom_packages/kspkglist.70.extras.sh @@ -3,24 +3,22 @@ . $OOB__shlib -add=$(read_config custom_packages add_packages) -del=$(read_config custom_packages del_packages) - -if [[ -n "$add" ]]; then +find_option_values pkgs_add custom_packages add_packages +for pkgs in "${pkgs_add[@]}"; do oIFS=$IFS IFS=$'\n\t, ' - for pkg in $add; do + for pkg in $pkgs; do echo "$pkg" done IFS=$oIFS -fi +done -if [[ -n "$del" ]]; then +find_option_values pkgs_del custom_packages del_packages +for pkgs in "${pkgs_del[@]}"; do oIFS=$IFS IFS=$'\n\t, ' - for pkg in $del; do + for pkg in $pkgs; do echo "-$pkg" done IFS=$oIFS -fi - +done diff --git a/modules/custom_scripts/kspost.75.nochroot.custom_scripts.sh b/modules/custom_scripts/kspost.80.nochroot.custom_scripts.sh index a9b81a0..d5559f6 100644 --- a/modules/custom_scripts/kspost.75.nochroot.custom_scripts.sh +++ b/modules/custom_scripts/kspost.80.nochroot.custom_scripts.sh @@ -3,14 +3,9 @@ . $OOB__shlib -oIFS=$IFS -IFS=$'\n' -for line in $(env); do - [[ "${line:0:34}" == "CFG_custom_scripts__custom_script_" ]] || continue - script=${line#*=} +find_option_values scripts custom_scripts custom_script +for script in "${scripts[@]}"; do echo "echo 'Executing custom script $script'" echo "export oob_config_dir=\"$oob_config_dir\"" echo "[ -x \"$script\" ] && \"$script\" || bash \"$script\"" done -IFS=$oIFS - diff --git a/modules/gnome/kspkglist.50.gnome.inc b/modules/gnome/kspkglist.50.gnome.inc index 0c732fd..000fbbc 100644 --- a/modules/gnome/kspkglist.50.gnome.inc +++ b/modules/gnome/kspkglist.50.gnome.inc @@ -4,6 +4,7 @@ gnome-desktop gnome-panel gnome-session gnome-terminal +gnome-settings-daemon metacity nautilus @@ -15,13 +16,8 @@ olpc-switch-desktop PolicyKit-gnome notification-daemon -# battery applet -batti - # internet -xulrunner -firefox -empathy +epiphany # office abiword @@ -36,13 +32,13 @@ gimp # audio & video audacity totem -totem-gstreamer totem-mozplugin # more desktop stuff file-roller gedit gnash-plugin -NetworkManager-gnome +network-manager-applet +nm-connection-editor xdg-user-dirs-gtk diff --git a/modules/gnome/kspost.50.batti.inc b/modules/gnome/kspost.50.batti.inc deleted file mode 100644 index 5f18566..0000000 --- a/modules/gnome/kspost.50.batti.inc +++ /dev/null @@ -1,3 +0,0 @@ -# make batti start automatically (#10436) -mv /usr/share/applications/batti.desktop /etc/xdg/autostart - diff --git a/modules/gnome/kspost.50.gconf.inc b/modules/gnome/kspost.50.gconf.inc deleted file mode 100644 index 9a706ee..0000000 --- a/modules/gnome/kspost.50.gconf.inc +++ /dev/null @@ -1,32 +0,0 @@ -# Set default fonts: We use smaller fonts on the XO - -# Application font -gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type string --set /desktop/gnome/interface/font_name "Sans 7" - -# Document font -gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type string --set /desktop/gnome/interface/document_font_name "Sans 7" - -# Desktop font -gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type string --set /apps/nautilus/preferences/desktop_font "Sans 7" - -# Window title font -gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type string --set /apps/metacity/general/titlebar_font "Sans Bold 7" - -# Monospace Font -gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type string --set /desktop/gnome/interface/monospace_font_name "Monospace 7" - -# make GNOME mouse cursor bigger -gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type int --set /desktop/gnome/peripherals/mouse/cursor_size 48 - -# disable screensaver locking -gconftool-2 --direct --config-source=xml:readwrite:/etc/gconf/gconf.xml.defaults -s -t bool /apps/gnome-screensaver/lock_enabled false - -# disable annoying pop-ups from IM settings daemon (we use our own IM settings mechanism for now) -gconftool-2 --direct --config-source=xml:readwrite:/etc/gconf/gconf.xml.defaults -s -t bool /apps/imsettings-applet/notify_on_bubble false - -# Set Nautilus to browser mode by default -gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type bool --set /apps/nautilus/preferences/always_use_browser true - -# Remove email-launcher icon from panel -gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type list --list-type string --set /apps/panel/general/object_id_list [menu_bar,web_launcher] - diff --git a/modules/jffs2_image/kspost.50.jffs2.inc b/modules/jffs2_image/kspost.50.jffs2.inc index 4b678ba..63f89d3 100644 --- a/modules/jffs2_image/kspost.50.jffs2.inc +++ b/modules/jffs2_image/kspost.50.jffs2.inc @@ -1,4 +1,4 @@ # permanently set %__dbi_cdb rpm macro to work around jffs2's lack of writeable mmap() mkdir -p /etc/rpm -echo "%__dbi_cdb create private nommap" > /etc/rpm/macros.rpmdb +echo "%_dbi_config nommap" > /etc/rpm/macros.rpmdb diff --git a/modules/oats_cfg/README b/modules/oats_cfg/README index 50bc2ef..6a10b83 100644 --- a/modules/oats_cfg/README +++ b/modules/oats_cfg/README @@ -11,6 +11,11 @@ to override this behaviour, the school server will not be tried. Useful in deployments with good connectivity where antitheft is controlled in a central location (as opposed to the specific school). +ignore_signature: by default, the OATS client will expect the server's response to be signed, and it will verify the signature. Set this to 1 to ignore all +signatures (and also accept messages with no signature). Useful for +deployments that have not implemented OLPC's security system, but still wish +to take advantage of other OATS features. + stream: the update stream - this is helpful when deploying different OS images that query the same update server. @@ -18,5 +23,6 @@ Example configuration: [oats_cfg] server=my-oats-server.mydeployment.com ignore_xs=1 +ignore_signature=1 stream=xo15hs diff --git a/modules/oats_cfg/kspost.50.oats_cfg.sh b/modules/oats_cfg/kspost.50.oats_cfg.sh index 32989d2..49bae4c 100644 --- a/modules/oats_cfg/kspost.50.oats_cfg.sh +++ b/modules/oats_cfg/kspost.50.oats_cfg.sh @@ -5,12 +5,15 @@ server=$(read_config oats_cfg server) ignore_xs=$(read_config oats_cfg ignore_xs) +ignore_sig=$(read_config oats_cfg ignore_signature) stream=$(read_config oats_cfg stream) if [ "$ignore_xs" = "1" ]; then echo "touch /etc/oats-ignore-xs" fi +[ "$ignore_sig" = "1" ] && echo "touch /etc/oats-ignore-signature" + if [ -n "$server" ]; then echo "echo '$server' > /etc/oats-server" fi @@ -18,4 +21,3 @@ fi if [ -n "$stream" ]; then echo "echo '$stream' > /etc/update-stream" fi - diff --git a/modules/osk/README b/modules/osk/README new file mode 100644 index 0000000..d1054b3 --- /dev/null +++ b/modules/osk/README @@ -0,0 +1,9 @@ +Include this module in your build if you want to enable the on-screen keyboard. + +The keyboard language can be changed with a horizontal swipe on the +touchscreen. By default, this scrolls through a long list of languages. +If you wish to configure this list to just cycle through a few keyboard +of relevance to your deployment, use the 'languages' option, e.g.: + +[osk] +languages=en_gb,de,es diff --git a/modules/osk/kspkglist.50.osk.inc b/modules/osk/kspkglist.50.osk.inc new file mode 100644 index 0000000..6e22b2c --- /dev/null +++ b/modules/osk/kspkglist.50.osk.inc @@ -0,0 +1,3 @@ +maliit-plugins +maliit-framework-gtk2 +maliit-framework-gtk3 diff --git a/modules/osk/kspost.50.osk-config.sh b/modules/osk/kspost.50.osk-config.sh new file mode 100644 index 0000000..a3780a2 --- /dev/null +++ b/modules/osk/kspost.50.osk-config.sh @@ -0,0 +1,20 @@ +# Copyright (C) 2010 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib + +langs=$(read_config osk languages) + +[ -z "$langs" ] && exit 0 + +oIFS=$IFS +IFS=$'\n\t, ' +for lang in $langs; do + output+=", libmaliit-keyboard-plugin.so:${lang}" +done +IFS=$oIFS + +output="${output:2}" +echo 'mkdir -p /etc/xdg/maliit.org' +echo 'echo "[maliit]" > /etc/xdg/maliit.org/server.conf' +echo "echo 'onscreen\\enabled=${output}' >> /etc/xdg/maliit.org/server.conf" diff --git a/modules/repos/README b/modules/repos/README index c69ef14..ada9dd7 100644 --- a/modules/repos/README +++ b/modules/repos/README @@ -8,20 +8,15 @@ release repository (and perhaps update) or equivalent is enabled. Everything is done through the configuration. -Firstly, the 'fedora' and 'fedora_arch' options: +Firstly, the 'fedora' option: [repos] -fedora_arch=i386 fedora=fedora,fedora_updates,fedora_updates_testing This is a comma-separated list of official Fedora repositories to enable for the build. The 4 possible options are fedora, fedora_updates, fedora_updates_testing and rawhide. -If using the fedora option, the fedora_arch option must be specified too. -This specifies the processor architecture to use for Fedora package selection. -See http://mirrors.fedoraproject.org/ for the available values. - A Fedora mirror is normally automatically selected by yum through Fedora's mirrorlist mechanism. If you wish to override the mirror selection choice, you can either add the repos as custom repos (see below), or you can use @@ -29,7 +24,6 @@ you can either add the repos as custom repos (see below), or you can use [repos] fedora=fedora,fedora_updates -fedora_arch=i386 url_fedora_updates=http://www.mirrorservice.org/sites/download.fedora.redhat.com/pub/fedora/linux/updates/16/i386/ url_fedora=http://www.mirrorservice.org/sites/download.fedora.redhat.com/pub/fedora/linux/development/16/i386/os/ @@ -96,11 +90,11 @@ For example, this is useful to specify that packages in OLPC's "override" repos take precedence over the official Fedora repos, even if the Fedora repo contains a newer version of a particular package. -If the fedora_arch option was present, the exclude list is generated in a -manner that takes arch considerations into account. For example, -if fedora_arch=i386 but there is an ARM package in a repository that -conributes to the exclude list, the package will *not* be added to the list -(since it is not suitable for your architecture). +The exclude list is generated in a manner that takes arch considerations into +account. For example, if the global fedora_arch setting is 'i386' but there is +an ARM package in a repository that contributes to the exclude list, +the package will *not* be added to the list (since it is not suitable for your +architecture). The add_excludes_to option value is a comma-separated list of repository names where the exclude list should be applied. The names are the same diff --git a/modules/repos/ksmain.50.repos.py b/modules/repos/ksmain.50.repos.py index c6b3872..bde0b09 100644 --- a/modules/repos/ksmain.50.repos.py +++ b/modules/repos/ksmain.50.repos.py @@ -4,7 +4,6 @@ import os import sys import ooblib -import urllib2 from gzip import GzipFile from StringIO import StringIO @@ -12,10 +11,7 @@ excludepkgs = set() addexcludes = ooblib.read_config('repos', 'add_excludes_to') fedora = ooblib.read_config('repos', 'fedora') fver = ooblib.read_config('global', 'fedora_release').strip() -farch = ooblib.read_config('repos', 'fedora_arch') - -if farch: - farch = farch.strip() +farch = ooblib.read_config('global', 'fedora_arch').strip() def add_to_excludes(baseurl, addexcludes): print >>sys.stderr, "Reading repository information for", baseurl @@ -23,7 +19,7 @@ def add_to_excludes(baseurl, addexcludes): url = baseurl + '/' + repomd['primary'] print >>sys.stderr, "Reading package information from", url - fd = urllib2.urlopen(url) + fd = ooblib.cachedurlopen(url) data = fd.read() fd.close() fd = GzipFile(fileobj=StringIO(data)) diff --git a/modules/sd_card_image/README b/modules/sd_card_image/README index 0deda30..aa1bde8 100644 --- a/modules/sd_card_image/README +++ b/modules/sd_card_image/README @@ -5,13 +5,22 @@ These images are in the "ZD" format, suitable for flashing via OpenFirmware's fs-update command. Corresponding .zsp files are produced too. To disable .zd/.zsp creation, set the make_zd option to 0 (default is 1). -The SD card sizes must be specified, in bytes. This module can create -filesystems for multiple SD card capacities. Simply provide a list of -uniquely-named options that start with "size_", one for each SD card size. - -The value for each of these options is the disk size (in bytes), optionally -followed by a comma and a custom extension. There can only be one un-named -entry, which will default to the extension "zd". +By default, a single disk image is produced, with it's size automatically +calculated based on the size of the data included in the image, plus a small +amount of free space. The system will resize the partition and filesystem to +fill the media during first boot. Therefore, other than loading the module, +no configuration is usually necessary. + +If you wish to create multiple images, or if you wish to specify a size, +you can specify some uniquely-named options starting with "size_". (This +will disable the default creation of an automatic-sized image as described +above.) + +The value for each of these options is the disk size, optionally followed by +a comma and a custom extension. There can only be one un-named entry, which +will default to the extension "zd". The disk size is specified in bytes, +but the special size "auto" will result in the disk size being calculated +automatically as described above. For example: [sd_card_image] @@ -51,4 +60,3 @@ The raw image file is archived in tar (in sparse mode) and then compressed with gzip. Tar preserves the sparseness of the file (the fact that some part of the image is made up of unallocated disk blocks). To disable this archiving/compression, set the compress_disk_image option to 0 (default is 1). - diff --git a/modules/sd_card_image/image.50.makefs.sh b/modules/sd_card_image/image.50.makefs.sh index c107ba9..b259409 100644 --- a/modules/sd_card_image/image.50.makefs.sh +++ b/modules/sd_card_image/image.50.makefs.sh @@ -1,10 +1,11 @@ -# Copyright (C) 2009 One Laptop Per Child +# Copyright (C) 2009 One Laptop per Child # Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. . $OOB__shlib versioned_fs=$(read_config base versioned_fs) buildnr=$(read_buildnr) BLOCK_SIZE=512 +ROOT_PARTITION_START_BLOCK=139264 NUM_HEADS=16 NUM_SECTORS_PER_TRACK=62 @@ -18,13 +19,49 @@ umount $ROOT &>/dev/null || : mkdir -p $BOOT mkdir -p $ROOT +# Automatically determine a size for the output disk image (including root +# and boot partitions). +# +# This is calculated by examining how much space was used in the intermediate +# filesystem image, and by adding a small amount of free space for safety. +auto_size() +{ + local rawfs=$intermediatesdir/rawfs.img + local edump=$(dumpe2fs "$rawfs") + local bsize=$(echo "$edump" | grep "^Block size:") + local bcount=$(echo "$edump" | grep "^Block count:") + local freeblocks=$(echo "$edump" | grep "^Free blocks:") + + # Remove textual labels, we just want the numbers + bsize="${bsize##* }" + bcount="${bcount##* }" + freeblocks="${freeblocks##* }" + + local usedblocks=$(( bcount - freeblocks )) + local usedsize=$(( usedblocks * bsize )) + + # In my testing, the new image has about 100mb free even when we try + # to match the size exactly. So we use the exact size; if we find that + # we need to add some 'safety' space later, we can add it. + #local newsize=$(( usedsize + (20*1024*1024) )) + local newsize=$usedsize + + # Increase by size of boot partition + (( newsize += $ROOT_PARTITION_START_BLOCK * $BLOCK_SIZE )) + + echo $newsize +} make_image() { - local vals=$1 - local disk_size=${vals%,*} - local ext= - expr index "$vals" ',' &>/dev/null && ext=${vals#*,} + local disk_size=$1 + local ext=$2 + [ -z "$ext" ] && ext="zd" + + if [ "$disk_size" = "auto" ]; then + disk_size=$(auto_size) + fi + echo "Making image of size $disk_size" echo "Create disk and partitions..." @@ -32,43 +69,37 @@ make_image() local num_blocks=$(($disk_size / $BLOCK_SIZE)) local num_cylinders=$(($num_blocks / $NUM_HEADS / $NUM_SECTORS_PER_TRACK)) local image_size=$(($num_cylinders * $NUM_HEADS * $NUM_SECTORS_PER_TRACK * $BLOCK_SIZE)) - local os_part1_begin=$(($NUM_SECTORS_PER_TRACK * $BLOCK_SIZE)) - [ -z "$ext" ] && ext="zd" local img=$intermediatesdir/$(image_name).$ext.disk.img - dd if=/dev/urandom of=$img.fill bs=4096 count=1 2>/dev/null - rm -f $img.fill.2mb - for x in $(seq 512); do cat $img.fill >> $img.fill.2mb; done - local n=$(($image_size / (1048576 * 2) + 1)) - rm -f $img - dd if=/dev/zero of=$img bs=1M count=1 2>/dev/null - for x in $(seq $n); do cat $img.fill.2mb >> $img; done - truncate --size=$image_size $img - rm -f $img.fill.2mb + dd if=/dev/zero of=$img bs=$BLOCK_SIZE count=0 seek=$(($image_size / $BLOCK_SIZE)) /sbin/sfdisk -S 32 -H 32 --force -uS $img <<EOF 8192,131072,83,* -139264,,, +$ROOT_PARTITION_START_BLOCK,,, EOF - # sfdisk output truncates paths that are too long - pushd $intermediatesdir - local img_sectors=$(sfdisk -uS -l $(basename $img) | grep img2 | awk '{print $4}') - popd - echo "(1 losetup error is normal here)" - losetup -d /dev/loop6 || : - losetup -o $((8192 * $BLOCK_SIZE)) --sizelimit $((131072 * $BLOCK_SIZE)) /dev/loop6 $img - echo "(1 losetup error is normal here)" - losetup -d /dev/loop7 || : - losetup -o $(((8192 + 131072) * $BLOCK_SIZE)) --sizelimit $(($img_sectors * $BLOCK_SIZE)) /dev/loop7 $img + + disk_loop=$(losetup --show --find --partscan $img) + boot_loop="${disk_loop}p1" + root_loop="${disk_loop}p2" + + # Work around occasional failure for loop partitions to appear + # http://marc.info/?l=linux-kernel&m=134271282127702&w=2 + local i=0 + while ! [ -e "$boot_loop" ]; do + partx -a -v $disk_loop + sleep 1 + (( ++i )) + [ $i -ge 10 ] && break + done echo "Create filesystems..." - mke2fs -O dir_index,^resize_inode -L Boot -F /dev/loop6 - mount /dev/loop6 $BOOT + mke2fs -O dir_index,^resize_inode -L Boot -F $boot_loop + mount $boot_loop $BOOT - mkfs.ext4 -O dir_index,^huge_file -E resize=8G -m1 -L OLPCRoot /dev/loop7 - tune2fs -o journal_data_ordered /dev/loop7 - mount /dev/loop7 $ROOT + mkfs.ext4 -O dir_index,^huge_file -E resize=8G -m1 -L OLPCRoot $root_loop + tune2fs -o journal_data_ordered $root_loop + mount $root_loop $ROOT echo "Copy in root filesystem..." cp -a $fsmount/* $ROOT @@ -101,19 +132,19 @@ EOF umount $ROOT umount $BOOT - losetup -d /dev/loop6 || : - losetup -d /dev/loop7 || : + losetup -d $disk_loop || : # FIXME: any value to running e2fsck now? maybe with -D ? } -oIFS=$IFS -IFS=$'\n' -for line in $(env); do - [[ "${line:0:24}" == "CFG_sd_card_image__size_" ]] || continue - val=${line#*=} - make_image $val +find_option_values sizes sd_card_image size +for val in "${sizes[@]}"; do + disk_size=${val%,*} + ext= + expr index "$vals" ',' &>/dev/null && ext=${vals#*,} + make_image $disk_size $ext done -IFS=$oIFS +# If no sizes were specified, create an image with automatic size. +[[ ${#sizes[@]} == 0 ]] && make_image auto diff --git a/modules/sd_card_image/postimage.50.makezd.sh b/modules/sd_card_image/postimage.50.makezd.sh index c427626..50be9a0 100644 --- a/modules/sd_card_image/postimage.50.makezd.sh +++ b/modules/sd_card_image/postimage.50.makezd.sh @@ -5,25 +5,19 @@ compress=$(read_config sd_card_image compress_disk_image) keep_img=$(read_config sd_card_image keep_disk_image) make_zd=$(read_config sd_card_image make_zd) +osname=$(image_name) -oIFS=$IFS -IFS=$'\n' -for line in $(env); do - [[ "${line:0:24}" == "CFG_sd_card_image__size_" ]] || continue - vals=${line#*=} - disk_size=${vals%,*} - ext= - expr index "$vals" ',' &>/dev/null && ext=${vals#*,} +function make_zd() { + local ext=$1 [ -z "$ext" ] && ext="zd" - osname=$(image_name) - output_name=$osname.$ext - diskimg=$intermediatesdir/$output_name.disk.img - output=$outputdir/$output_name + + local output_name=$osname.$ext + local diskimg=$intermediatesdir/$output_name.disk.img + local output=$outputdir/$output_name if [[ "$make_zd" == 1 ]]; then echo "Making ZD image for $output_name..." $bindir/zhashfs 0x20000 sha256 $diskimg $output.zsp $output - rm -f $diskimg.fill echo "Creating MD5sum of $output_name..." pushd $outputdir >/dev/null @@ -40,5 +34,16 @@ for line in $(env); do mv $diskimg $outputdir fi fi + +} + +find_option_values sizes sd_card_image size +for vals in "${sizes[@]}"; do + disk_size=${vals%,*} + ext= + expr index "$vals" ',' &>/dev/null && ext=${vals#*,} + make_zd $ext done -IFS=$oIFS + +# When no size options were specified, we make a default image. +[[ ${#sizes[@]} == 0 ]] && make_zd diff --git a/modules/signing/README b/modules/signing/README index eb04a5d..ce03f42 100644 --- a/modules/signing/README +++ b/modules/signing/README @@ -134,7 +134,8 @@ file for every outputted .zsp file: [signing] make_zsp_fs_zip=1 -A file named os31.2gb.zsp will result in os31.2gb.fs.zip being generated. +A file named os31.2gb.zsp will result in os31.2gb.fs1.zip being generated +(the '1' in 'fs1' indicates XO-1.5). For XO-1, bios-crypto is required. JFFS2 images (.img) are signed as follows: @@ -142,14 +143,14 @@ For XO-1, bios-crypto is required. JFFS2 images (.img) are signed as follows: bios_crypto_path=/home/myuser/bios-crypto make_img_fs_zip=1 -All output jffs2 .img files will be signed into (e.g.) os52.fs.zip. +All output jffs2 .img files will be signed into (e.g.) os52.fs0.zip. And XO-1 UBIFS images (.onu alongside .uim) are signed as follows: [signing] bios_crypto_path=/home/myuser/bios-crypto make_onu_fs_zip=1 -All output ubifs .onu files will be signed into (e.g.) os52.onu.fs.zip. +All output ubifs .onu files will be signed into (e.g.) os52.onu.fs0.zip. In all cases, these fs.zip output files are unsigned and must be externally diff --git a/modules/signing/finalize.50.makefszip_img.sh b/modules/signing/finalize.50.makefszip_img.sh index 20c59d6..42fc797 100644 --- a/modules/signing/finalize.50.makefszip_img.sh +++ b/modules/signing/finalize.50.makefszip_img.sh @@ -31,7 +31,8 @@ make_unsigned_img() make_signed_img() { echo "Generating signed fs.zip for $(basename $1)..." - local outfile=$outputdir/$(basename $1).fs.zip + local fszip=fs$(read_laptop_model_number).zip + local outfile=$outputdir/$(basename $1).$fszip pushd $bios_crypto/build ./make-fs.sh --signingkey $skey $1 mv fs.zip $outfile diff --git a/modules/signing/finalize.50.makefszip_onu.sh b/modules/signing/finalize.50.makefszip_onu.sh index f6f172a..12909f7 100644 --- a/modules/signing/finalize.50.makefszip_onu.sh +++ b/modules/signing/finalize.50.makefszip_onu.sh @@ -14,7 +14,8 @@ skey=$(read_config signing skey) shopt -s nullglob for i in $outputdir/*.onu; do bname=$(basename $i) - outfile=$outputdir/$bname.fs.zip + fszip=fs$(read_laptop_model_number).zip + outfile=$outputdir/$bname.$fszip zipfiles="$intermediatesdir/version.txt $intermediatesdir/data.img" cp "$i" "$intermediatesdir"/data.img diff --git a/modules/signing/finalize.50.makefszip_zsp.sh b/modules/signing/finalize.50.makefszip_zsp.sh index 4be4c38..98dd821 100644 --- a/modules/signing/finalize.50.makefszip_zsp.sh +++ b/modules/signing/finalize.50.makefszip_zsp.sh @@ -14,13 +14,14 @@ make_unsigned_zsp() { local bname=$(basename $1) local bname_noext=$(basename $1 .zsp) + local fszip=fs$(read_laptop_model_number).zip echo "Generating unsigned fs.zip for $bname..." echo "$bname_noext" > $intermediatesdir/version.txt cp $i $intermediatesdir/data.img - zip -j -n .img:.txt $outputdir/$bname.fs.zip \ + zip -j -n .img:.txt $outputdir/$bname.$fszip \ $intermediatesdir/data.img $intermediatesdir/version.txt rm -f $intermediatesdir/{data.img,version.txt} } @@ -28,7 +29,8 @@ make_unsigned_zsp() make_signed_zsp() { echo "Generating signed fs.zip for $(basename $1)..." - local outfile=$outputdir/$(basename $1).fs.zip + local fszip=fs$(read_laptop_model_number).zip + local outfile=$outputdir/$(basename $1).$fszip pushd $bios_crypto/build rm -rf fs.zip ./sign-zsp.sh $skey $1 diff --git a/modules/signing/preimage.10.extract.sh b/modules/signing/preimage.10.extract.sh index 5a7a471..01f3753 100644 --- a/modules/signing/preimage.10.extract.sh +++ b/modules/signing/preimage.10.extract.sh @@ -4,6 +4,8 @@ # this must be run before the base module creates versioned fs layout . $OOB__shlib +shopt -s nullglob + enabled=$(read_config signing extract) [[ "$enabled" == "1" ]] || exit 0 @@ -14,31 +16,21 @@ mkdir -p $tgt found=0 echo "Extracting content for signing..." -if [ -e "$fsmount/boot/bootfw.zip" ]; then - cp $fsmount/boot/bootfw.zip $tgt - found=1 -fi - -if [ -e "$fsmount/boot/vmlinuz" ]; then - cp $fsmount/boot/vmlinuz $tgt/data.img - zip -j -n .img $tgt/runos.zip $tgt/data.img - rm -f $tgt/data.img - found=1 -fi - -if [ -e "$fsmount/boot/initrd.img" ]; then - cp $fsmount/boot/initrd.img $tgt/data.img - zip -j -n .img $tgt/runrd.zip $tgt/data.img - rm -f $tgt/data.img - found=1 -elif [ -e "$fsmount/boot/olpcrd.img" ]; then - cp $fsmount/boot/olpcrd.img $tgt/data.img - zip -j -n .img $tgt/runrd.zip $tgt/data.img - rm -f $tgt/data.img - found=1 -fi +copy_out_file() { + local name=$1 + for path in "$fsmount"/boot/${name}*.zip; do + [ -f "$path" ] || continue + cp $path $tgt + found=1 + done +} + +copy_out bootfw +copy_out runos +copy_out runrd +copy_out actos +copy_out actrd [ "$found" == "1" ] || exit 0 zip -j $outzip $tgt/* - diff --git a/modules/signing/preimage.40.sign-firmware.sh b/modules/signing/preimage.40.sign-firmware.sh index 1f8093e..8789558 100644 --- a/modules/signing/preimage.40.sign-firmware.sh +++ b/modules/signing/preimage.40.sign-firmware.sh @@ -8,13 +8,14 @@ wkey=$(read_config signing wkey) bios_crypto=$(read_config signing bios_crypto_path) [ -n "$bios_crypto" -a -d "$bios_crypto" ] || exit 0 -[ -e $fsmount/boot/bootfw.zip ] || exit 0 +bootfw=$(find $fsmount/boot -type f -name 'bootfw*.zip' -print -quit) +[ -n "$bootfw" ] || exit 0 echo "Signing firmware..." fwtmp=$intermediatesdir/fw-for-signing mkdir -p $fwtmp -unzip -d $fwtmp $fsmount/boot/bootfw.zip +unzip -d $fwtmp $bootfw mv $fwtmp/data.img $intermediatesdir/fw.rom outzip=$intermediatesdir/bootfw.zip @@ -22,5 +23,4 @@ rm -f $outzip pushd $bios_crypto/build ./sign-fw.sh $wkey $intermediatesdir/fw.rom $outzip popd -mv $outzip $fsmount/boot/ - +mv $outzip $bootfw diff --git a/modules/signing/preimage.40.sign-os.sh b/modules/signing/preimage.40.sign-os.sh index 19ddc3b..0adba39 100644 --- a/modules/signing/preimage.40.sign-os.sh +++ b/modules/signing/preimage.40.sign-os.sh @@ -8,29 +8,23 @@ okey=$(read_config signing okey) bios_crypto=$(read_config signing bios_crypto_path) [ -n "$bios_crypto" -a -d "$bios_crypto" ] || exit 0 -if [ -e "$fsmount/boot/vmlinuz" ]; then - echo "Signing kernel..." - pushd $bios_crypto/build - ./sign-os.sh $okey $fsmount/boot/vmlinuz $fsmount/boot/runos.zip - popd - [ -e $fsmount/boot/actos.zip ] || ln -s runos.zip $fsmount/boot/actos.zip -fi +sign_os() { + local path=$(find ${fsmount}/boot -type f -name "${1}*.zip" -print -quit) + [ -z "$path" ] && return -if [ -e "$fsmount/boot/initrd.img" ]; then - echo "Signing initramfs..." pushd $bios_crypto/build - ./sign-os.sh $okey $fsmount/boot/initrd.img $fsmount/boot/runrd.zip - popd -fi + unzip "$path" + mv data.img tmp.img -if [ -e "$fsmount/boot/actrd.img" ]; then - echo "Signing activation initramfs..." - pushd $bios_crypto/build - $bios_crypto/build/sign-os.sh $okey $fsmount/boot/actrd.img $fsmount/boot/actrd.zip - popd -fi + rm -f $path + ./sign-os.sh $okey tmp.img $path -# If no separate activation initramfs was provided, assume that the regular -# initramfs also handles activation. -[ -e $fsmount/boot/actrd.zip ] || ln -s runrd.zip $fsmount/boot/actrd.zip + rm -f tmp.img + popd +} +echo "Signing initramfs/kernel..." +sign_os runos +sign_os actos +sign_os runrd +sign_os actrd diff --git a/modules/signing/preimage.50.addsignedcontent.sh b/modules/signing/preimage.50.addsignedcontent.sh index c110329..f3106c2 100644 --- a/modules/signing/preimage.50.addsignedcontent.sh +++ b/modules/signing/preimage.50.addsignedcontent.sh @@ -2,6 +2,7 @@ # Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. . $OOB__shlib +shopt -s nullglob content=$(read_config signing add_signed_content) [ -n "$content" ] || exit 0 @@ -11,15 +12,11 @@ signdir=$intermediatesdir/signed-content rm -rf $signdir mkdir -p $signdir unzip $content -d $signdir -for sfile in bootfw.zip runos.zip runrd.zip actos.zip actrd.zip; do - [ -e $signdir/$sfile ] && cp $signdir/$sfile $fsmount/boot/$sfile + +pushd $signdir +for sfile in bootfw*.zip runos*.zip runrd*.zip actos*.zip actrd*.zip; do + cp --remove-destination $sfile $fsmount/boot/$sfile done +popd rm -rf $signdir - -# symlink actXX to runXX (or the other way) if any of them are missing -[ -e $fsmount/boot/actos.zip ] || ln -s runos.zip $fsmount/boot/actos.zip -[ -e $fsmount/boot/actrd.zip ] || ln -s runrd.zip $fsmount/boot/actrd.zip -[ -e $fsmount/boot/runos.zip ] || ln -s actos.zip $fsmount/boot/runos.zip -[ -e $fsmount/boot/runrd.zip ] || ln -s actrd.zip $fsmount/boot/runrd.zip - diff --git a/modules/sugar/kspkglist.50.sugar.inc b/modules/sugar/kspkglist.50.sugar.inc index d7d09a2..6be371f 100644 --- a/modules/sugar/kspkglist.50.sugar.inc +++ b/modules/sugar/kspkglist.50.sugar.inc @@ -1,12 +1,20 @@ # sugar desktop sugar +sugar-base +sugar-toolkit +sugar-toolkit-gtk3 + +# sugar control panels +sugar-cp-datetime +sugar-cp-frame +sugar-cp-language +sugar-cp-modemconfiguration +sugar-cp-network +sugar-cp-power # additional sugar packages libxml2-python -hulahop -pyabiword -gnome-python2-evince -udisks +webkitgtk3 espeak etoys evince-djvu @@ -19,19 +27,22 @@ csound-python pygame python-alsaaudio squeak-vm +python-cjson + # Browse -gnome-python2-gnome gnash-plugin totem-mozplugin + # Terminal vte + # dependencies for Epub support in Read -pywebkitgtk python-BeautifulSoup -python-lxml olpc-library + # for Tuxmath activity SDL_Pango + # for Physics pybox2d diff --git a/modules/sugar/kspost.80.install_bundles.inc b/modules/sugar/kspost.75.install_bundles.inc index 753c005..d351d3b 100644 --- a/modules/sugar/kspost.80.install_bundles.inc +++ b/modules/sugar/kspost.75.install_bundles.inc @@ -1,12 +1,14 @@ mkdir -p /home/olpc/{Activities,Library} chown olpc:olpc /home/olpc/{Activities,Library} +shopt -s nullglob for i in /build_shared/sugar-bundles/*; do if [ "${i:(-4)}" == ".xol" ]; then /usr/bin/unzip -d /home/olpc/Library -q $i else - /bin/su -c "/usr/bin/sugar-install-bundle $i" olpc + /bin/su -c "/usr/bin/sugar-install-bundle $i" - olpc fi done +shopt -u nullglob chown -R olpc:olpc /home/olpc/{Activities,Library} diff --git a/modules/sugar/kspost.90.nochroot.shrink_activities.inc b/modules/sugar/kspost.90.nochroot.shrink_activities.inc new file mode 100644 index 0000000..608c084 --- /dev/null +++ b/modules/sugar/kspost.90.nochroot.shrink_activities.inc @@ -0,0 +1 @@ +/usr/sbin/hardlink -v $INSTALL_ROOT/home/olpc/Activities diff --git a/modules/sugar_activities_extra/README b/modules/sugar_activities_extra/README index a66948a..a4288ed 100644 --- a/modules/sugar_activities_extra/README +++ b/modules/sugar_activities_extra/README @@ -1,9 +1,11 @@ This module installs sugar activities (.xo) and content bundles (.xol) from -a local directory. You must configure this directory. +zero or more local directories. You must configure these directories with +uniquely named options as follows: Example: [sugar_activities_extra] -local_dir=/path/to/my/activity/collection +local_dir_1=/path/to/my/activity/collection +local_dir_2=/path/to/another/activity/collection It can install activities from remote URLs too, with uniquely named options @@ -12,4 +14,3 @@ beginning with "url_", e.g.: [sugar_activities_extra] url_1=http://foo.com/MyActivity-1.xo url_2=http://foo.com/MyContent-3.xol - diff --git a/modules/sugar_activities_extra/kspost.60.nochroot.activities.sh b/modules/sugar_activities_extra/kspost.60.nochroot.activities.sh index e9d3b50..ff599ec 100644 --- a/modules/sugar_activities_extra/kspost.60.nochroot.activities.sh +++ b/modules/sugar_activities_extra/kspost.60.nochroot.activities.sh @@ -5,22 +5,18 @@ cache=$cachedir/activities -oIFS=$IFS -IFS=$'\n' -for line in $(env); do - [[ "${line:0:32}" == "CFG_sugar_activities_extra__url_" ]] || continue - aurl=${line#*=} +find_option_values urls sugar_activities_extra url +for aurl in "${urls[@]}"; do echo "Downloading from $aurl ..." >&2 - wget --no-verbose --inet4-only -P $cache -N "$aurl" - + [ -z "${OOB__cacheonly}" ] && \ + wget --no-verbose --inet4-only -P $cache -N "$aurl" install_sugar_bundle $cache/$(basename "$aurl") done -IFS=$oIFS -actpath=$(read_config sugar_activities_extra local_dir) -if [ -n "$actpath" -a -d "$actpath" ]; then +find_option_values dirs sugar_activities_extra local_dir +for actpath in "${dirs[@]}"; do + [ -n "$actpath" -a -d "$actpath" ] || continue for i in "$actpath"/*; do install_sugar_bundle $i done -fi - +done diff --git a/modules/sugar_activity_group/kspost.60.nochroot.activities.py b/modules/sugar_activity_group/kspost.60.nochroot.activities.py index f77a9e1..594d951 100644 --- a/modules/sugar_activity_group/kspost.60.nochroot.activities.py +++ b/modules/sugar_activity_group/kspost.60.nochroot.activities.py @@ -9,6 +9,8 @@ import os.path import urllib import urllib2 import urlparse +import time +import pickle from bitfrost.update import microformat @@ -34,48 +36,94 @@ if install_activities: for suffix in suffixes: if len(suffix) > 0: grpurl = urlparse.urljoin(baseurl + "/", urllib.quote(suffix)) + grpurlcache = os.path.join(cache, os.path.basename(baseurl) + + '-' + suffix + ".html") else: grpurl = baseurl - - print >>sys.stderr, "Trying group URL", grpurl - try: - name, desc, results = microformat.parse_url(grpurl) - except urllib2.HTTPError, e: - if e.code == 404: + grpurlcache = os.path.join(cache, os.path.basename(baseurl) + + ".html") + + if ooblib.cacheonly: + print >>sys.stderr, "Trying group URL cache file", grpurlcache + if os.path.exists(grpurlcache): + name, desc, results = pickle.load(open(grpurlcache)) + else: + continue + else: + print >>sys.stderr, "Trying group URL", grpurl + try: + name, desc, results = microformat.parse_url(grpurl) + except urllib2.HTTPError, e: + if e.code == 404: + continue + raise e + if len(results) == 0 or (name is None and desc is None): continue - raise e - if len(results) == 0 or (name is None and desc is None): - continue - print >>sys.stderr, "Found activity group:", name - - for name, info in results.items(): - (version, url) = microformat.only_best_update(info) - print >>sys.stderr, "Examining %s v%s: %s" % (name, version, url) - fd = urllib2.urlopen(url) - headers = fd.info() - if not 'Content-length' in headers: - raise Exception("No content length for %s" % url) - length = int(headers['Content-length']) - path = urlparse.urlsplit(fd.geturl())[2] + print >>sys.stderr, "Found activity group:", name + pickle.dump([name, desc, results], open(grpurlcache, 'w')) + + if results: + break #process only the first URL (or cached file) + + if not results: + print >>sys.stderr, "No Activity Group URL found" + sys.exit(1) + + for name, info in results.items(): + (version, url) = microformat.only_best_update(info) + print >>sys.stderr, "Examining %s v%s: %s" % (name, version, url) + + if ooblib.cacheonly: + path = urlparse.urlsplit(url)[2] path = os.path.basename(path) localpath = os.path.join(cache, path) if os.path.exists(localpath): - localsize = os.stat(localpath).st_size - if localsize == length: - print >>sys.stderr, "Not downloading, already in cache." - ooblib.install_sugar_bundle(localpath) - continue - - print >>sys.stderr, "Downloading (%dkB)..." % (length/1024) - localfd = open(localpath, 'w') - localfd.write(fd.read()) - fd.close() - localfd.close() - ooblib.install_sugar_bundle(localpath) + print >>sys.stderr, "Using: ", localpath + ooblib.install_sugar_bundle(localpath) + continue + else: + print >>sys.stderr, "Cannot find cache for ", url + sys.exit(1) + + fd = None + for attempts in range(5): + if attempts > 0: + print >>sys.stderr, 'Retrying.' + time.sleep(1) + try: + fd = urllib2.urlopen(url) + break + except urllib2.HTTPError, e: + print >>sys.stderr, 'HTTP error: ', e.code + except urllib2.URLError, e: + print >>sys.stderr, 'Network or server error: ', e.reason + + if not fd: + print >>sys.stderr, 'Could not reach ', url + sys.exit(1) + + headers = fd.info() + if not 'Content-length' in headers: + raise Exception("No content length for %s" % url) + length = int(headers['Content-length']) + path = urlparse.urlsplit(fd.geturl())[2] + path = os.path.basename(path) + + localpath = os.path.join(cache, path) + if os.path.exists(localpath): + localsize = os.stat(localpath).st_size + if localsize == length: + print >>sys.stderr, "Not downloading, already in cache." + ooblib.install_sugar_bundle(localpath) + continue - # only process the first working URL - break + print >>sys.stderr, "Downloading (%dkB)..." % (length/1024) + localfd = open(localpath, 'w') + localfd.write(fd.read()) + fd.close() + localfd.close() + ooblib.install_sugar_bundle(localpath) if systemwide: print "mkdir -p $INSTALL_ROOT/etc/olpc-update" diff --git a/modules/sugar_welcome_activity/README b/modules/sugar_welcome_activity/README new file mode 100644 index 0000000..b41faf0 --- /dev/null +++ b/modules/sugar_welcome_activity/README @@ -0,0 +1,38 @@ +This module is EXPERIMENTAL and usage may change. + +This module allows you auto-start an activity or other program in the +first Sugar startup -- before the user enters a name and picks icon colors. + +By default it will use the Welcome activity -- you MUST have it installed +for this to work. + +It can also + + - Customize the images displayed by the welcome activity. + + - Start a _different_ activity or program. + +Take care - this module will also let you break the Welcome activity. + +Basic configuration -- just put an empty section(ensure you +are including the Welcome activity!): + + [sugar_welcome_activity] + # nothing here, magic defaults + +Advanced configurations: + + Changing welcome images + + [sugar_welcome_activity] + images_path=/home/myuser/welcome-images + + Using a different activity + + [sugar_welcome_activity] + welcome_screen_cmd=python /home/olpc/Activities/MyCustomWelcome.activity/activity.py + + Using a different program + + [sugar_welcome_activity] + welcome_screen_cmd=/usr/bin/someprogram --option parameter diff --git a/modules/sugar_welcome_activity/defaults.ini b/modules/sugar_welcome_activity/defaults.ini new file mode 100644 index 0000000..c7d9ac9 --- /dev/null +++ b/modules/sugar_welcome_activity/defaults.ini @@ -0,0 +1,2 @@ +[sugar_welcome_activity] +welcome_screen_cmd=python /home/olpc/Activities/Welcome.activity/activity.py diff --git a/modules/sugar_welcome_activity/kspost.77.nochroot.replace_images.py b/modules/sugar_welcome_activity/kspost.77.nochroot.replace_images.py new file mode 100644 index 0000000..d5e4d71 --- /dev/null +++ b/modules/sugar_welcome_activity/kspost.77.nochroot.replace_images.py @@ -0,0 +1,18 @@ +# NOTE: Order matters - this script must run after activity unpacking (currently 75) +# and before welcome_cmd +import ooblib +import os, sys +from pipes import quote + +images_path=ooblib.read_config('sugar_welcome_activity', 'images_path') + +if images_path: + if not os.path.exists(images_path): + print >> sys.stderr, "ERROR: sugar_welcome_activity.images_path must point to an existing directory in your build environment" + sys.exit(1) + + # synchronize the files within the path, keeping directory structure + print 'rsync -rlpt %s/ "$INSTALL_ROOT/home/olpc/Activities/Welcome.activity/images/"' % quote(images_path) + # note - chown happens in kspost.80.wecome_cmd as it reads /etc/passwd + print 'chmod -R u+rwx "$INSTALL_ROOT/home/olpc/Activities/Welcome.activity/images/"' + diff --git a/modules/sugar_welcome_activity/kspost.78.welcome_cmd.py b/modules/sugar_welcome_activity/kspost.78.welcome_cmd.py new file mode 100644 index 0000000..5853e0b --- /dev/null +++ b/modules/sugar_welcome_activity/kspost.78.welcome_cmd.py @@ -0,0 +1,16 @@ +# NOTE: Order matters - this script must run right after replace_images +# and before custom_scripts (currently at 80) +import ooblib +from pipes import quote + +welcome_screen_cmd=ooblib.read_config('sugar_welcome_activity', 'welcome_screen_cmd') +images_path=ooblib.read_config('sugar_welcome_activity', 'images_path') + +if welcome_screen_cmd: + print 'mkdir -p /home/olpc' + print 'echo %s > /home/olpc/.welcome_screen' % quote(welcome_screen_cmd) + print 'chown olpc:olpc /home/olpc/.welcome_screen' + print 'chmod u+w /home/olpc/.welcome_screen' + +if images_path: + print 'chown -R olpc:olpc /home/olpc/Activities/Welcome.activity/images/' diff --git a/modules/sugarlabs_activities/kspost.60.nochroot.aslo.sh b/modules/sugarlabs_activities/kspost.60.nochroot.aslo.sh index 0118a53..c090aa4 100644 --- a/modules/sugarlabs_activities/kspost.60.nochroot.aslo.sh +++ b/modules/sugarlabs_activities/kspost.60.nochroot.aslo.sh @@ -16,15 +16,28 @@ for id in $activities; do [ -n "$sugarver" ] && qurl="${qurl}&appVersion=${sugarver}" [ "$experimental" = "1" ] && qurl="${qurl}&experimental=1" - echo "Examining $qurl ..." >&2 - aurl=$(wget --inet4-only -q -O- "$qurl" | grep updateLink | sed -e 's/[[:space:]]*<[^>]*>//g') - if [ -z "$aurl" ]; then - echo "ERROR: Could not find download URL for $id" >&2 - exit 1 + qurlcache="${cache}/${id}" + [ -n "$sugarver" ] && qurlcache="${qurlcache}-s${sugarver}" + [ "$experimental" = "1" ] && qurlcache="${qurlcache}-experimental" + qurlcache="${qurlcache}.url" + + if [ -n "$OOB__cacheonly" ]; then + echo "Using cache for ${id}" >&2 + aurl=$(<$qurlcache) + else + echo "Examining $qurl ..." >&2 + aurl=$(wget --inet4-only -q -O- "$qurl" | grep updateLink | sed -e 's/[[:space:]]*<[^>]*>//g') + if [ -z "$aurl" ]; then + echo "ERROR: Could not find download URL for $id" >&2 + exit 1 + fi + echo "${aurl}" > "${qurlcache}" fi - echo "Downloading from $aurl ..." >&2 - wget --no-verbose --inet4-only -P $cache -N "$aurl" + if [ -z "$OOB__cacheonly" ]; then + echo "Downloading from $aurl ..." >&2 + wget --no-verbose --inet4-only -P $cache -N "$aurl" + fi install_sugar_bundle $cache/$(basename "$aurl") done IFS=$oIFS diff --git a/modules/ubifs_image/image.50.makeimg.sh b/modules/ubifs_image/image.50.makeimg.sh index ce64e93..5122d22 100644 --- a/modules/ubifs_image/image.50.makeimg.sh +++ b/modules/ubifs_image/image.50.makeimg.sh @@ -80,7 +80,6 @@ cat > $ubinize_cfg <<EOF mode=ubi image=$root_tmp_img vol_id=0 -vol_size=973312KiB vol_type=dynamic vol_name=rootfs vol_flags=autoresize diff --git a/modules/x11/kspkglist.60.misc.inc b/modules/x11/kspkglist.60.misc.inc index 06ea893..e6899fa 100644 --- a/modules/x11/kspkglist.60.misc.inc +++ b/modules/x11/kspkglist.60.misc.inc @@ -1,8 +1,8 @@ #fonts -abyssinica-fonts -dejavu-lgc-sans-fonts -dejavu-lgc-sans-mono-fonts -dejavu-lgc-serif-fonts +sil-abyssinica-fonts +dejavu-sans-fonts +dejavu-sans-mono-fonts +dejavu-serif-fonts khmeros-base-fonts lohit-devanagari-fonts nafees-web-naskh-fonts @@ -19,5 +19,4 @@ scim-pinyin # sound backend alsa-utils gstreamer-plugins-good - - +gstreamer1-plugins-good diff --git a/modules/x11/kspost.60.misc.inc b/modules/x11/kspost.60.misc.inc index b63bcf8..f5745d5 100644 --- a/modules/x11/kspost.60.misc.inc +++ b/modules/x11/kspost.60.misc.inc @@ -76,23 +76,5 @@ EOF chown -R olpc:olpc /home/olpc/.scim -if [ -e /usr/lib/xulrunner-*/greprefs/all.js ]; then - # disable Firefox's OGG plugin in favour of totem, because no hw accel is - # available. #10152 - sed -i -e 's:\(media.ogg.enabled",\) true:\1 false:g' /usr/lib/xulrunner-*/greprefs/all.js - - # sl#2259: The layout.css.dpi default setting results in a too big layout and fonts - sed -i -e 's:\(layout.css.dpi",\) -1:\1 96:' /usr/lib/xulrunner-*/greprefs/all.js -fi - -# remove unneccesary package mesa-dri-drivers (#11036) -rpm -e --nodeps mesa-dri-drivers - -# remove gstreamer pulse element so that totem doesn't try to use it (#10158) -[ -e /usr/lib/gstreamer-0.10/libgstpulse.so ] && rm /usr/lib/gstreamer-0.10/libgstpulse.so - -# if totem is installed, set default volume to 100% (#10158) -gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --dir-exists /apps/totem && gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type int --set /apps/totem/volume 100 - exit 0 diff --git a/modules/xo1/kspkglist.50.xo1.inc b/modules/xo1/kspkglist.50.xo1.inc index 5f6d5e6..8c83684 100644 --- a/modules/xo1/kspkglist.50.xo1.inc +++ b/modules/xo1/kspkglist.50.xo1.inc @@ -1 +1,3 @@ +olpc-firmware +libertas-usb8388-olpc-firmware xorg-x11-drv-geode diff --git a/modules/xo1/kspost.50.xo1-tweaks.inc b/modules/xo1/kspost.50.xo1-tweaks.inc index d55324d..194a40e 100644 --- a/modules/xo1/kspost.50.xo1-tweaks.inc +++ b/modules/xo1/kspost.50.xo1-tweaks.inc @@ -1,114 +1,6 @@ -# FIXME: old olpc.fth looks for olpcrd.img, but we now use initrd.img -# any nicer way to fix this? -[ -e "/boot/olpcrd.img" ] || ln -s initrd.img /boot/olpcrd.img - -# olpc.fth really shouldnt specify a root device or filesystem, the initramfs -# figures this out (like in the signed boot path). -# FIXME: fix bootfw package -# sed -i -e 's:root=mtd0 rootfstype=jffs2::g' /boot/olpc.fth - # do not show the Sugar default ad-hoc networks on the XO-1 gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type bool --set /desktop/sugar/network/adhoc false -# add /ofw, can be removed when we move to newer kernels with /proc/device-tree -mkdir /ofw -echo "none /ofw promfs defaults 0 0" >> /etc/fstab - -# Temporary workaround to #11214 transition -cat <<'EOF' > /boot/olpc.fth -\ OLPC boot script - -[ifndef] do-firmware-update - -: do-firmware-update ( img$ -- ) - -\ Keep .error from printing an input sream position report -\ which makes a buffer@<address> show up in the error message - ['] noop to show-error - - visible - - tuck flash-buf swap move ( len ) - - ['] ?image-valid catch ?dup if ( ) - visible - red-letters - ." Bad firmware image file - " .error - ." Continuing with old firmware" cr - black-letters - exit - then - - true to file-loaded? - - d# 12,000 wait-until \ Wait for EC to notice the battery - - ['] ?enough-power catch ?dup if - visible - red-letters - ." Unsafe to update firmware now - " .error - ." Continuing with old firmware" cr - black-letters - exit - then - - " Updating firmware" ?lease-debug-cr - - ec-indexed-io-off? if - visible - ." Restarting to enable SPI FLASH writing." cr - d# 3000 ms - ec-ixio-reboot - security-failure - then - - \ Latch alternate? flag for next startup - alternate? if [char] A h# 82 cmos! then - - reflash \ Should power-off and reboot - show-x - " Reflash returned, unexpectedly" .security-failure -; - -[then] - -[ifndef] ?ofw-reflash -\ Check for new firmware. -: ?ofw-reflash ( -- ) - " ${DN}${PN}\bootfw.zip" expand$ - ['] (boot-read) catch if 2drop exit then - img$ firmware-up-to-date? if exit then - img$ do-firmware-update -; - -[then] - -: set-path-macros ( -- ) - button-o game-key? if " \boot-alt" else " \boot" then pn-buf place - - " /chosen" find-package if ( phandle ) - " bootpath" rot get-package-property 0= if ( propval$ ) - get-encoded-string ( bootpath$ ) - [char] \ left-parse-string 2nip ( dn$ ) - dn-buf place ( ) - then - then - - " nand" dn-buf count sindex 0>= if - " " - else - " root=LABEL=OLPCRoot rootfstype=ext3" - then - " ROOTDEV" $set-macro -; - -: olpc-fth-boot-me - set-path-macros - ?ofw-reflash - " ro ${ROOTDEV} console=ttyS0,115200 console=tty0 fbcon=font:SUN12x22" expand$ to boot-file - " ${DN}${PN}\vmlinuz" expand$ to boot-device - " ${DN}${PN}\olpcrd.img" expand$ to ramdisk - boot -; -olpc-fth-boot-me -EOF +# enable serial console on ttyS0 +ln -sf /lib/systemd/system/serial-getty@.service \ + /etc/systemd/system/getty.target.wants/serial-getty@ttyS0.service diff --git a/modules/xo1/prepare.10.model.sh b/modules/xo1/prepare.10.model.sh new file mode 100644 index 0000000..06c12ef --- /dev/null +++ b/modules/xo1/prepare.10.model.sh @@ -0,0 +1,5 @@ +# Copyright (C) 2012 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib +set_laptop_model_number 0 diff --git a/modules/xo1_5/kspkglist.50.xo1_5.inc b/modules/xo1_5/kspkglist.50.xo1_5.inc index 705a4da..0ef417d 100644 --- a/modules/xo1_5/kspkglist.50.xo1_5.inc +++ b/modules/xo1_5/kspkglist.50.xo1_5.inc @@ -1,3 +1,6 @@ +olpc-firmware +libertas-sd8686-firmware + xorg-x11-drv-chrome # currently XO-1.5 / XO-1.75 only diff --git a/modules/xo1_5/kspost.50.xo15-tweaks.inc b/modules/xo1_5/kspost.50.xo15-tweaks.inc index 0463297..b83d40e 100644 --- a/modules/xo1_5/kspost.50.xo15-tweaks.inc +++ b/modules/xo1_5/kspost.50.xo15-tweaks.inc @@ -1,98 +1,8 @@ -# add /ofw, can be removed when we move to newer kernels with /proc/device-tree -mkdir /ofw -echo "none /ofw promfs defaults 0 0" >> /etc/fstab - -# Workaround an unknown bug where TamTam sound is crackly on XO-1.5 (#9414) -sed -i -e 's/dmix.rate 48000/dmix.rate 44100/' /usr/share/alsa/alsa.conf - -# Temporary workaround to #11214 transition -cat <<'EOF' > /boot/olpc.fth -\ OLPC boot script - -[ifndef] do-firmware-update - -: do-firmware-update ( img$ -- ) - -\ Keep .error from printing an input sream position report -\ which makes a buffer@<address> show up in the error message - ['] noop to show-error - - visible - - tuck flash-buf swap move ( len ) - - ['] ?image-valid catch ?dup if ( ) - visible - red-letters - ." Bad firmware image file - " .error - ." Continuing with old firmware" cr - black-letters - exit - then - - true to file-loaded? - - d# 12,000 wait-until \ Wait for EC to notice the battery - - ['] ?enough-power catch ?dup if - visible - red-letters - ." Unsafe to update firmware now - " .error - ." Continuing with old firmware" cr - black-letters - exit - then - - " Updating firmware" ?lease-debug-cr - - ec-indexed-io-off? if - visible - ." Restarting to enable SPI FLASH writing." cr - d# 3000 ms - ec-ixio-reboot - security-failure - then - - \ Latch alternate? flag for next startup - alternate? if [char] A h# 82 cmos! then - - reflash \ Should power-off and reboot - show-x - " Reflash returned, unexpectedly" .security-failure -; - -[then] - -[ifndef] ?ofw-reflash -\ Check for new firmware. -: ?ofw-reflash ( -- ) - " ${DN}${PN}\bootfw.zip" expand$ - ['] (boot-read) catch if 2drop exit then - img$ firmware-up-to-date? if exit then - img$ do-firmware-update -; - -[then] - -: set-path-macros ( -- ) - button-o game-key? if " \boot-alt" else " \boot" then pn-buf place - - " /chosen" find-package if ( phandle ) - " bootpath" rot get-package-property 0= if ( propval$ ) - get-encoded-string ( bootpath$ ) - [char] \ left-parse-string 2nip ( dn$ ) - dn-buf place ( ) - then - then -; - -: olpc-fth-boot-me - set-path-macros - ?ofw-reflash - " console=ttyS0,115200 console=tty0 fbcon=font:SUN12x22 " expand$ to boot-file - " ${DN}${PN}\vmlinuz" expand$ to boot-device - " ${DN}${PN}\initrd.img" expand$ to ramdisk - boot -; -olpc-fth-boot-me -EOF +# enable serial console on ttyS0 +ln -sf /lib/systemd/system/serial-getty@.service \ + /etc/systemd/system/getty.target.wants/serial-getty@ttyS0.service + +# enable serial console for runin too +mkdir -p /etc/systemd/system/runin.target.wants +ln -sf /lib/systemd/system/serial-getty@.service \ + /etc/systemd/system/runin.target.wants/serial-getty@ttyS0.service diff --git a/modules/xo1_5/prepare.10.model.sh b/modules/xo1_5/prepare.10.model.sh new file mode 100644 index 0000000..9543cd6 --- /dev/null +++ b/modules/xo1_5/prepare.10.model.sh @@ -0,0 +1,5 @@ +# Copyright (C) 2012 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib +set_laptop_model_number 1 diff --git a/modules/xo1_75/kspkglist.50.xo1_75.inc b/modules/xo1_75/kspkglist.50.xo1_75.inc index 5229ebc..3f3ecb0 100644 --- a/modules/xo1_75/kspkglist.50.xo1_75.inc +++ b/modules/xo1_75/kspkglist.50.xo1_75.inc @@ -1,10 +1,6 @@ +olpc-firmware-q4 +libertas-sd8686-firmware xorg-x11-drv-dove # currently XO-1.5 / XO-1.75 only olpc-runin-tests - -# currently not pulled in by ARM for some reason -ntfs-3g - -# 2-bpp version of Adwaita cursors -cursors-adwaita2b diff --git a/modules/xo1_75/kspost.50.xo1_75-tweaks.inc b/modules/xo1_75/kspost.50.xo1_75-tweaks.inc index bd2caed..6d435c9 100644 --- a/modules/xo1_75/kspost.50.xo1_75-tweaks.inc +++ b/modules/xo1_75/kspost.50.xo1_75-tweaks.inc @@ -1 +1,8 @@ -gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --type string --set /desktop/gnome/peripherals/mouse/cursor_theme Adwaita2b +# enable serial console on ttyS2 +ln -sf /lib/systemd/system/serial-getty@.service \ + /etc/systemd/system/getty.target.wants/serial-getty@ttyS2.service + +# enable serial console for runin too +mkdir -p /etc/systemd/system/runin.target.wants +ln -sf /lib/systemd/system/serial-getty@.service \ + /etc/systemd/system/runin.target.wants/serial-getty@ttyS2.service diff --git a/modules/xo1_75/prepare.10.model.sh b/modules/xo1_75/prepare.10.model.sh new file mode 100644 index 0000000..1d21671 --- /dev/null +++ b/modules/xo1_75/prepare.10.model.sh @@ -0,0 +1,5 @@ +# Copyright (C) 2012 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib +set_laptop_model_number 2 diff --git a/modules/xo4/README b/modules/xo4/README new file mode 100644 index 0000000..cccafa6 --- /dev/null +++ b/modules/xo4/README @@ -0,0 +1,3 @@ +This module applies various build tweaks required for the XO-4 platform. +If you are building for XO-4, include this module. Do not include it +otherwise. diff --git a/modules/xo4/kspkglist.50.xo4.inc b/modules/xo4/kspkglist.50.xo4.inc new file mode 100644 index 0000000..200d837 --- /dev/null +++ b/modules/xo4/kspkglist.50.xo4.inc @@ -0,0 +1,5 @@ +olpc-firmware-q7 +libertas-sd8686-firmware +libertas-sd8787-firmware +xorg-x11-drv-dove +olpc-runin-tests diff --git a/modules/xo4/kspost.50.xo4-tweaks.inc b/modules/xo4/kspost.50.xo4-tweaks.inc new file mode 100644 index 0000000..6d435c9 --- /dev/null +++ b/modules/xo4/kspost.50.xo4-tweaks.inc @@ -0,0 +1,8 @@ +# enable serial console on ttyS2 +ln -sf /lib/systemd/system/serial-getty@.service \ + /etc/systemd/system/getty.target.wants/serial-getty@ttyS2.service + +# enable serial console for runin too +mkdir -p /etc/systemd/system/runin.target.wants +ln -sf /lib/systemd/system/serial-getty@.service \ + /etc/systemd/system/runin.target.wants/serial-getty@ttyS2.service diff --git a/modules/xo4/prepare.10.model.sh b/modules/xo4/prepare.10.model.sh new file mode 100644 index 0000000..2cca919 --- /dev/null +++ b/modules/xo4/prepare.10.model.sh @@ -0,0 +1,5 @@ +# Copyright (C) 2012 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib +set_laptop_model_number 4 diff --git a/modules/yumcfg/kspost.50.yumcfg.py b/modules/yumcfg/kspost.50.yumcfg.py index dc16716..cda5273 100644 --- a/modules/yumcfg/kspost.50.yumcfg.py +++ b/modules/yumcfg/kspost.50.yumcfg.py @@ -3,7 +3,6 @@ import os import sys -import urllib2 from gzip import GzipFile from StringIO import StringIO @@ -12,6 +11,8 @@ import ooblib addrepos = [] excludes = set() +farch = ooblib.read_config('global', 'fedora_arch').strip() + # read in repos for var in os.environ: if not var.startswith("CFG_yumcfg__addrepo"): @@ -25,11 +26,11 @@ for var in os.environ: for for_excludes, name, url in addrepos: if not for_excludes: continue - fd = urllib2.urlopen(url + "/repodata/primary.xml.gz") + fd = ooblib.cachedurlopen(url + "/repodata/primary.xml.gz") data = fd.read() fd.close() fd = GzipFile(fileobj=StringIO(data)) - ooblib.add_packages_from_xml(fd, excludes) + ooblib.add_packages_from_xml(fd, excludes, farch) # write shell code to generate yum repo files for for_excludes, name, url in addrepos: diff --git a/osbuilder.py b/osbuilder.py index 87f282d..3713241 100755 --- a/osbuilder.py +++ b/osbuilder.py @@ -33,6 +33,7 @@ import subprocess import shutil import re import time +import pipes from optparse import OptionParser class StageException(Exception): @@ -49,39 +50,6 @@ class Stage(object): self.ignore_failures = ignore_failures pass - def _make_environment(self): - env = {} - - # copy some bits from parent environment - for key in ('HOSTNAME', 'USER', 'USERNAME', 'LANG', 'HOME', 'LOGNAME', - 'SHELL', 'PATH'): - if key in os.environ: - env[key] = os.environ[key] - - env['PYTHONPATH'] = self.osb.libdir - env['OOB__shlib'] = os.path.join(self.osb.libdir, 'shlib.sh') - env['OOB__libdir'] = self.osb.libdir - env['OOB__bindir'] = self.osb.bindir - env['OOB__builddir'] = self.osb.builddir - env['OOB__cachedir'] = self.osb.cachedir - env['OOB__intermediatesdir'] = self.osb.intermediatesdir - env['OOB__outputdir'] = self.osb.outputdir - env['OOB__statedir'] = self.osb.statedir - env['OOB__fsmount'] = self.osb.fsmount - - env['oob_config_dir'] = os.path.dirname(self.osb.build_config) - - envpath = env['PATH'].split(':') - for dir in ('/sbin', '/usr/sbin'): - if envpath.count(dir) == 0: - env['PATH'] = env['PATH'] + ':' + dir - - for section in self.osb.cfg.sections(): - for option in self.osb.cfg.options(section): - val = self.osb.cfg.get(section, option) - env["CFG_%s__%s" % (section, option)] = val - return env - def _run_part(self, mod, part, output): print " * Running part %s %s %s..." % (self.name, mod, part) self.on_run_part(mod, part, output) @@ -97,9 +65,8 @@ class Stage(object): for line in fd: output.write(line) elif path.endswith(".sh"): - shenv = self._make_environment() proc = subprocess.Popen(["/bin/bash", path], shell=False, - stdout=outtype, env=shenv) + stdout=outtype, env=self.osb.env) try: (out, err) = proc.communicate() except (Exception, KeyboardInterrupt), e: @@ -111,9 +78,8 @@ class Stage(object): if not self.console_output: output.write(out) elif path.endswith(".py"): - shenv = self._make_environment() proc = subprocess.Popen(["/usr/bin/python", path], shell=False, - stdout=outtype, env=shenv) + stdout=outtype, env=self.osb.env) try: (out, err) = proc.communicate() except (Exception, KeyboardInterrupt), e: @@ -208,13 +174,18 @@ class KspostStage(KsStage): super(KspostStage, self).__init__(osb, "kspost") def on_run_part(self, mod, part, output): - output.write("\n%post --erroronfail") - if ".nochroot." in part: + output.write("\n%post --erroronfail --interpreter=/bin/bash") + nochroot = ".nochroot." in part + if nochroot: output.write(" --nochroot") print >>output, "\necho 'Executing code generated by %s:%s/%s...'" \ % (self.name, mod, part) print >>output, "set -e" + # Make the normal environment available for non-chroot scripts + if nochroot: + print >>output, ". " + os.path.join(self.osb.intermediatesdir, 'env') + def on_run_part_done(self, mod, part, output): print >>output, "%end" @@ -254,9 +225,10 @@ class OsBuilderException(Exception): pass class OsBuilder(object): - def __init__(self, build_config, additional_defaults): - self.build_config = os.path.abspath(build_config) - self.additional_defaults = additional_defaults + def __init__(self, build_configs): + self.build_configs = [] + for cfg in build_configs: + self.build_configs.append(os.path.abspath(cfg)) print " * OLPC OS builder v%s" % VERSION if INSTALLED: @@ -273,19 +245,20 @@ class OsBuilder(object): self.cachedir = os.path.join(self.builddir, 'cache') self.intermediatesdir = os.path.join(self.builddir, 'intermediates') + self.shareddir = os.path.join(self.intermediatesdir, 'shared') self.outputdir = os.path.join(self.builddir, 'output') self.statedir = os.path.join(self.builddir, 'state') self.fsmount = os.path.join(self.builddir, 'mnt-fs') + # gets set in build() + self.cacheonly = False + # load config to find module list # and set interpolation default for oob_config_dir self.cfg = SafeConfigParser({'oob_config_dir': - os.path.dirname(self.build_config)}) - self.cfg.read(self.build_config) - - # read in defaults specified on the command line - if self.additional_defaults is not None: - self.cfg.read(self.additional_defaults) + os.path.dirname(self.build_configs[0])}) + for cfg in self.build_configs: + self.cfg.read(cfg) if self.cfg.has_option('global', 'suggested_oob_version'): suggested = self.cfg.get('global','suggested_oob_version') @@ -302,20 +275,56 @@ class OsBuilder(object): print "Press Ctrl+C to abort. Continuing in 15 seconds." time.sleep(15) - self.modules = [] - for option in self.cfg.options('global'): - if not option.startswith('modules_') and option != "modules": - continue - self.modules.extend(self.cfg.get('global', option).split(',')) + self.modules = self.cfg.sections() + if 'global' in self.modules: + self.modules.remove('global') - # clean up - for idx, mod in enumerate(self.modules): - self.modules[idx] = mod.strip() + self.read_config() + self.env = self.make_environment() - # remove duplicates - self.modules = list(set(self.modules)) + def make_environment(self): + env = {} - self.read_config() + # copy some bits from parent environment + for key in ('HOSTNAME', 'USER', 'USERNAME', 'LANG', 'HOME', 'LOGNAME', + 'SHELL', 'PATH'): + if key in os.environ: + env[key] = os.environ[key] + + env['PYTHONPATH'] = self.libdir + env['OOB__shlib'] = os.path.join(self.libdir, 'shlib.sh') + env['OOB__libdir'] = self.libdir + env['OOB__bindir'] = self.bindir + env['OOB__builddir'] = self.builddir + env['OOB__cachedir'] = self.cachedir + env['OOB__intermediatesdir'] = self.intermediatesdir + env['OOB__shareddir'] = self.shareddir + env['OOB__outputdir'] = self.outputdir + env['OOB__statedir'] = self.statedir + env['OOB__fsmount'] = self.fsmount + + env['oob_config_dir'] = os.path.dirname(self.build_configs[0]) + + if self.cacheonly: + env['OOB__cacheonly'] = 'True' + + envpath = env['PATH'].split(':') + for dir in ('/sbin', '/usr/sbin'): + if envpath.count(dir) == 0: + env['PATH'] = env['PATH'] + ':' + dir + + for section in self.cfg.sections(): + for option in self.cfg.options(section): + val = self.cfg.get(section, option) + env["CFG_%s__%s" % (section, option)] = val + return env + + def dump_environment(self): + # Dump the build environment into a bash-compatible script + fd = open(os.path.join(self.intermediatesdir, "env"), "w") + for var, value in self.env.iteritems(): + fd.write("export %s=%s\n" % (var, pipes.quote(value))) + fd.close() def suggested_mismatch(self, suggested_version): # we only compare the first two version components @@ -329,7 +338,7 @@ class OsBuilder(object): """Read and validate config (including module defaults)""" # reset config since we want to load the module defaults first self.cfg = SafeConfigParser({'oob_config_dir': - os.path.dirname(self.build_config)}) + os.path.dirname(self.build_configs[0])}) for mod in self.modules: m = re.match(r"[A-Za-z_][A-Za-z0-9_]*$", mod) @@ -344,12 +353,9 @@ class OsBuilder(object): # read in defaults self.cfg.read(os.path.join(modpath, 'defaults.ini')) - # read in defaults specified on the command line - if self.additional_defaults is not None: - self.cfg.read(self.additional_defaults) - # now load the users config, overriding other settings where specified - self.cfg.read(self.build_config) + for cfg in self.build_configs: + self.cfg.read(cfg) for section in self.cfg.sections(): m = re.match(r"[A-Za-z_][A-Za-z0-9_]*$", section) @@ -377,18 +383,25 @@ class OsBuilder(object): # cleanup stage not listed here as its a bit of a special case ) - def build(self, clean_output=True, clean_intermediates=True): + def build(self, clean_output=True, clean_intermediates=True, cacheonly=False): # cleanup from previous runs if clean_intermediates and os.path.exists(self.intermediatesdir): shutil.rmtree(self.intermediatesdir) if clean_output and os.path.exists(self.outputdir): shutil.rmtree(self.outputdir) + self.cacheonly = cacheonly + if cacheonly and not os.path.exists(self.cachedir): + raise OsBuilderException("Missing cache, cannot use --cache-only") + for dir in (self.builddir, self.cachedir, self.intermediatesdir, - self.outputdir, self.statedir, self.fsmount): + self.outputdir, self.statedir, self.fsmount, + self.shareddir): if not os.path.exists(dir): os.makedirs(dir) + self.dump_environment() + # truncate file and write header ksfd = open(self.get_ks_file_path(), 'w') ksfd.write("# Generated with OLPC OS builder\n") @@ -414,25 +427,27 @@ class OsBuilder(object): print " * Output is in", self.outputdir def main(): - op = OptionParser(usage="%prog [options] buildconfig", version=VERSION) + op = OptionParser(usage="%prog [options] buildconfig [buildconfig2...]", version=VERSION) op.add_option('--no-clean-output', dest="clean_output", action="store_false", default=True, help="Don't clean output directory on startup") op.add_option('--no-clean-intermediates', dest="clean_intermediates", action="store_false", default=True, help="Don't clean intermediates directory on startup or exit") - op.add_option('--additional-defaults', dest="additional_defaults", - action="store", default=None, - help="Additional config file with default settings") + op.add_option('--cache-only', dest="cacheonly", + action="store_true", default=False, + help="Run entirely from cache") + (options, args) = op.parse_args() - if len(args) != 1: + if len(args) < 1: op.error("incorrect number of arguments") try: - osb = OsBuilder(args[0], options.additional_defaults) + osb = OsBuilder(args) osb.build(clean_output=options.clean_output, - clean_intermediates=options.clean_intermediates) + clean_intermediates=options.clean_intermediates, + cacheonly=options.cacheonly) except OsBuilderException, e: print >>sys.stderr, "ERROR:", e sys.exit(1) |