Merge lp:~steve-mcintyre/linaro-chromiumos/python-rewrite into lp:linaro-chromiumos

Proposed by Steve McIntyre
Status: Merged
Merged at revision: 14
Proposed branch: lp:~steve-mcintyre/linaro-chromiumos/python-rewrite
Merge into: lp:linaro-chromiumos
Diff against target: 350 lines (+278/-53)
4 files modified
remote/run_build (+0/-14)
remote/run_build.py (+59/-0)
remote/setup_build (+0/-39)
remote/setup_build.py (+219/-0)
To merge this branch: bzr merge lp:~steve-mcintyre/linaro-chromiumos/python-rewrite
Reviewer Review Type Date Requested Status
Loïc Minier Pending
Review via email: mp+54250@code.launchpad.net

Description of the change

Rewrite in python.
Adding more features for better control of what we're building and where.

To post a comment you must log in.
14. By Steve McIntyre

Add creation of the top-level work area, using sudo to make sure it succeeds.

Revision history for this message
Loïc Minier (lool) wrote :

I submitted a branch based on yours for you to merge, as I felt it was simpler to show the changes in commits rather than explain them, then ask you to do them, then review them etc. These were all very simple changes, and overall your code was really good, thanks! See https://code.launchpad.net/~lool/linaro-chromiumos/python-rewrite/+merge/54551 for the mp.

There is one major issue with the new Python code: usage of os.system() is unchecked, which means we don't fail the run when any command fails. This really must be fixed; with the new run() wrapper I introduced, it should be simpler to add this in a single place.

Other things I had in mind:
- we should have a place to share code between the scripts
- we should move them out of remote and kill my linaro-chromiumos-build frontend
- (low priority) getopt doesn't integrate too nicely with Python in my experience, there are nicer ways to handle flags, but it works with getopt so we can keep it for now
- create_logdir() feels a bit specific; I think we should have an ensure_dir() thin wrapper around os.isdir() + os.makedirs(), and we should setup logdir early; perhaps it's easier to just expose it as an option; this would also allow merging logged_run() with run()
- I think we should use stderr consistently for our own output, but I'm open to discuss this
- the run() interface should take an array of commands rather than a command string; this is nicer to deal with when preparing commands before running them

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== removed file 'remote/run_build'
--- remote/run_build 2011-03-09 17:35:56 +0000
+++ remote/run_build 1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
1#!/bin/sh
2
3set -e
4
5./setup_board --board x86-generic
6./build_packages --board x86-generic
7
8# <wait a long time>
9
10./build_image --board x86-generic --noenable_rootfs_verification
11
12# <wait a long time>
13# Success?
14
150
=== added file 'remote/run_build.py'
--- remote/run_build.py 1970-01-01 00:00:00 +0000
+++ remote/run_build.py 2011-03-23 14:06:22 +0000
@@ -0,0 +1,59 @@
1#!/usr/bin/python
2#
3# Simple wrapper build script for Chromium OS builds
4#
5# Copyright (C) 2011 Linaro
6#
7# GPL v2+
8
9import os
10import getopt
11import sys
12import warnings
13import errno
14import shutil
15
16options = {}
17options['logdir'] = ''
18options['board-type'] = 'x86-generic'
19options['nousepkg'] = False
20
21try:
22 opts, args = getopt.getopt(sys.argv[1:], "",
23 ["logdir=",
24 "board-type=",
25 "nousepkg="])
26except getopt.GetoptError, err:
27 # print help information and exit:
28 print str(err) # will print something like "option -a not recognized"
29 usage()
30 sys.exit(2)
31
32for o, a in opts:
33 options[o[2:]] = a
34
35
36if not options['logdir'] == '':
37 os.environ['PORT_LOGDIR'] = options['logdir']
38 try:
39 os.environ['FEATURES'] = os.environ['FEATURES'] + ' binpkg-logs'
40 except:
41 os.environ['FEATURES'] = 'binpkg-logs'
42 os.system('sudo rm -rf %s'% options['logdir'])
43 os.system('sudo mkdir %s' % options['logdir'])
44
45build_options = ''
46build_options += ' --board=%s' % options['board-type']
47if options['nousepkg']:
48 build_options += ' --nousepkg'
49
50os.system('./setup_board --force %s' % build_options)
51os.system('./build_packages %s' % build_options)
52
53# <wait a long time>
54image_options = ' --noenable_rootfs_verification '
55image_options += ' --board=%s' % options['board-type']
56os.system('./build_image %s' % image_options)
57
58# <wait a long time>
59# Success?
060
=== removed file 'remote/setup_build'
--- remote/setup_build 2011-03-09 17:35:56 +0000
+++ remote/setup_build 1970-01-01 00:00:00 +0000
@@ -1,39 +0,0 @@
1#!/bin/sh
2
3set -e
4
5MANIFEST=$1
6if [ "$MANIFEST"x = "" ] ; then
7 MANIFEST=http://git.chromium.org/git/manifest
8fi
9
10BASEDIR=`dirname $0`
11WDIR=/mnt/chromeos
12
13# Basic setup
14export LC_ALL=C
15sudo apt-get update
16sudo apt-get install git subversion build-essential
17
18# Make working directory
19if [ ! -d $WDIR ] ; then
20 sudo mkdir $WDIR
21 sudo chown ubuntu: $WDIR
22fi
23
24# Grab basic stuff
25cd $WDIR
26svn co http://src.chromium.org/svn/trunk/tools/depot_tools
27export PATH=$PATH:$PWD/depot_tools
28
29# Start grabbing source
30repo init -u $MANIFEST
31repo sync
32
33# Set up the working chroot
34/mnt/chromeos/src/scripts/make_chroot --chroot=chroot-x86
35cp $BASEDIR/run_build chroot-x86/src/scripts
36
37# Now chroot into it and do stuff
38script -c "/mnt/chromeos/src/scripts/enter_chroot.sh --chroot=chroot-x86 -- ./run_build" cros-build.log
39
400
=== added file 'remote/setup_build.py'
--- remote/setup_build.py 1970-01-01 00:00:00 +0000
+++ remote/setup_build.py 2011-03-23 14:06:22 +0000
@@ -0,0 +1,219 @@
1#!/usr/bin/python
2#
3# Simple setup script for Chromium OS builds
4#
5# Copyright (C) 2011 Linaro
6#
7# GPL v2+
8
9import os
10import getopt
11import sys
12import warnings
13import errno
14import shutil
15
16# Set defaults for options
17options = {}
18options['build-name'] = 'build'
19options['board-type'] = 'x86-generic'
20options['use-network'] = True
21options['working-dir'] = ''
22#options['toolchain'] = 'default'
23options['manifest'] = 'http://git.chromium.org/git/manifest'
24options['nousepkg'] = False
25options['build-script'] = 'run_build.py'
26
27commands = 'create_tree get_source create_chroot build'.split()
28
29def usage():
30 print "%s\n" % sys.argv[0]
31 print "usage:\n"
32 print " setup_build.py [options] <command>\n"
33 print " options include:\n"
34 print " --working-dir=<name>"
35 print " specify a base location for a working directory"
36 print " (default is \"%s\")" % options['working-dir']
37 print " --build-name=<name>"
38 print " specify a name to use for this build"
39 print " (default is \"%s\")" % options['build-name']
40 print " --board-type=<board>"
41 print " specify the target board/platform"
42 print " (default is \"%s\")" % options['board-type']
43 print " --use-network=<true|false>"
44 print " should network access be allowed during the build?"
45 print " (default is %s)" % options['use-network']
46 print " --toolchain=<toolchain>"
47 print " choice of toolchain. Not yet implemented."
48 print " --manifest=<manifest URL>"
49 print " specify the manifest file to use"
50 print " (default is \"%s\")" % options['manifest']
51 print " --nousepkg=<true|false>"
52 print " force building of everything from source"
53 print " needed if --use-network==true or if using a new toolchain"
54 print " (default is \"%s\")" % options['nousepkg']
55 print
56 print "commands:\n"
57 print " create_tree"
58 print " create a working tree; necessary for other commands to run"
59 print " get_source"
60 print " download / update source code"
61 print " create_chroot"
62 print " create a chroot; necessary for later commands to run"
63 print " build"
64 print " build Chromium OS"
65 print
66
67def do_install_depot_tools(options, tree_dir):
68 os.chdir(tree_dir)
69 os.system('svn co http://src.chromium.org/svn/trunk/tools/depot_tools')
70
71def do_create_logdir(options, tree_dir):
72 logdir = os.path.join(tree_dir, 'logs')
73 if not os.path.exists(logdir):
74 os.mkdir(logdir)
75
76def do_create_tree(options, tree_dir):
77 print 'do_create_tree'
78
79 if os.path.exists(tree_dir):
80 print 'do_create_tree: tree %s already exists. Abort.' % tree_dir
81 return errno.EEXIST
82
83 os.makedirs(tree_dir, 0755)
84 os.system('sudo apt-get update')
85 os.system('sudo apt-get install -y git subversion build-essential')
86 do_install_depot_tools(options, tree_dir)
87 do_create_logdir(options, tree_dir)
88
89def do_get_source(options, tree_dir):
90 print 'do_get_source'
91
92 if not os.path.exists(tree_dir):
93 print 'do_get_source: tree %s does not exist. Abort.' % tree_dir
94 return errno.ENOENT
95
96 basedir = os.path.dirname(os.path.realpath(sys.argv[0]))
97
98 do_create_logdir(options, tree_dir)
99 os.chdir(tree_dir)
100 # Needs the "echo" piped in here to stop "repo init" asking
101 # awkward interactive questions that you can't pass on the command
102 # line.
103 cmdline = 'script -c "'
104 cmdline += 'echo | repo init -u %s' % options['manifest']
105 cmdline += '" logs/repo-init.log'
106 os.system(cmdline)
107
108 cmdline = 'script -c "'
109 cmdline += 'repo sync'
110 cmdline += '" logs/repo-sync.log'
111 os.system(cmdline)
112
113 # Copy in our script to do the actual build work inside the chroot
114 build_script = os.path.join(basedir, options['build-script'])
115 os.chmod(build_script, 0755)
116 shutil.copy(build_script, './src/scripts')
117
118def do_create_chroot(options, tree_dir):
119 print 'do_create_chroot'
120
121 if not os.path.exists(tree_dir):
122 print 'do_create_chroot: tree %s does not exist. Abort.' % tree_dir
123 return errno.ENOENT
124
125 do_create_logdir(options, tree_dir)
126 os.chdir(tree_dir)
127 cmdline = 'script -c "'
128 cmdline += './src/scripts/make_chroot'
129 if options['nousepkg']:
130 cmdline += ' --nousepkg'
131 cmdline += '" logs/create-chroot.log'
132 os.system(cmdline)
133
134def do_build(options, tree_dir):
135 print 'do_build'
136
137 if not os.path.exists(tree_dir):
138 print 'do_build: tree %s does not exist. Abort.' % tree_dir
139 return errno.ENOENT
140
141 chroot_path = os.path.join(tree_dir, 'chroot')
142 if not os.path.exists(chroot_path):
143 print 'do_build: chroot %s does not exist. Abort.' % chroot_path
144 return errno.ENOENT
145
146 do_create_logdir(options, tree_dir)
147 os.chdir(tree_dir)
148
149 cmdline = 'script -c "'
150 cmdline += './src/scripts/enter_chroot.sh -- ./%s' % options['build-script']
151 if options['nousepkg']:
152 cmdline += ' --nousepkg=True'
153 cmdline += ' --board-type=%s' % options['board-type']
154 cmdline += ' --logdir=/var/log/saved-logs'
155 cmdline += '" logs/cros-build.log'
156 os.system(cmdline)
157
158 cmdline = 'tar c -C chroot/var/log --lzma -f logs/build-logs.tar.lzma saved-logs'
159 os.system(cmdline)
160
161try:
162 opts, args = getopt.getopt(sys.argv[1:], "",
163 ["help",
164 "working-dir=",
165 "build-name=",
166 "board-type=",
167 "use-network=",
168 "toolchain=",
169 "nousepkg=",
170 "manifest="])
171except getopt.GetoptError, err:
172 # print help information and exit:
173 print str(err) # will print something like "option -a not recognized"
174 usage()
175 sys.exit(2)
176
177for o, a in opts:
178 if o in ("--help"):
179 usage()
180 sys.exit(0)
181 else:
182 options[o[2:]] = a
183
184if options['working-dir'] == '':
185 print 'Need to specify a working dir. Abort.'
186 usage()
187 sys.exit(2)
188
189if args == []:
190 print "Not asked to do anything"
191 usage()
192 sys.exit(0)
193
194for command in args:
195 if not command in (commands):
196 print "Unknown command %s" % command
197 usage()
198 sys.exit(2)
199
200if not os.path.exists(options['working-dir']):
201 # Create working dir area; likely to be on a separate filesystem
202 # somewhere, so let's make this as simple as possible using sudo.
203 os.system('sudo mkdir -p -m 0755 %s' % options['working-dir'])
204 os.system('sudo chown %s: %s' % (os.environ['LOGNAME'], options['working-dir']))
205
206tree_dir = os.path.join(options['working-dir'], options['build-name'])
207depot_tools_dir = os.path.join(tree_dir, 'depot_tools')
208os.environ['LC_ALL'] = 'C'
209os.environ['PATH'] = os.environ['PATH'] + os.pathsep + depot_tools_dir
210
211if 'create_tree' in args:
212 err = do_create_tree(options, tree_dir)
213if 'get_source' in args:
214 err = do_get_source(options, tree_dir)
215if 'create_chroot' in args:
216 err = do_create_chroot(options, tree_dir)
217if 'build' in args:
218 err = do_build(options, tree_dir)
219

Subscribers

People subscribed via source and target branches