Merge lp:~sergiusens/goget-ubuntu-touch/beBetter into lp:goget-ubuntu-touch

Proposed by Sergio Schvezov
Status: Merged
Approved by: John Lenton
Approved revision: 195
Merged at revision: 183
Proposed branch: lp:~sergiusens/goget-ubuntu-touch/beBetter
Merge into: lp:goget-ubuntu-touch
Diff against target: 833 lines (+282/-405)
5 files modified
diskimage/common.go (+232/-19)
diskimage/core_grub.go (+8/-194)
diskimage/core_uboot.go (+9/-181)
diskimage/errors.go (+32/-0)
ubuntu-device-flash/core.go (+1/-11)
To merge this branch: bzr merge lp:~sergiusens/goget-ubuntu-touch/beBetter
Reviewer Review Type Date Requested Status
John Lenton (community) Approve
Michael Vogt (community) Approve
Review via email: mp+261804@code.launchpad.net

Commit message

Remove code duplication and manage mounting/unmounting better

To post a comment you must log in.
187. By Sergio Schvezov

Revert uneeded func name change

Revision history for this message
Michael Vogt (mvo) wrote :

Woah, very nice consolidation. I have a lot of questions in the begining probably because its very hot here. Feel free to ignore, this is great and fine to land - I like how it kills duplication.

review: Approve
Revision history for this message
Sergio Schvezov (sergiusens) :
188. By Sergio Schvezov

Try to cleanly unmount on mount errors

189. By Sergio Schvezov

Message about not being able to remove basemount

190. By Sergio Schvezov

Use syscall sync

191. By Sergio Schvezov

Nicer error for unmounting

192. By Sergio Schvezov

Adding errors.go

193. By Sergio Schvezov

Mapping errors

194. By Sergio Schvezov

removing duplicate code for paths to mounts

195. By Sergio Schvezov

Cleanup moved

Revision history for this message
Michael Vogt (mvo) wrote :

Nice!

review: Approve
Revision history for this message
John Lenton (chipaca) wrote :

LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'diskimage/common.go'
--- diskimage/common.go 2015-04-21 19:35:46 +0000
+++ diskimage/common.go 2015-06-15 15:32:50 +0000
@@ -8,6 +8,7 @@
8package diskimage8package diskimage
99
10import (10import (
11 "bufio"
11 "errors"12 "errors"
12 "fmt"13 "fmt"
13 "io/ioutil"14 "io/ioutil"
@@ -15,6 +16,7 @@
15 "os/exec"16 "os/exec"
16 "path/filepath"17 "path/filepath"
17 "strings"18 "strings"
19 "syscall"
18)20)
1921
20// This program is free software: you can redistribute it and/or modify it22// This program is free software: you can redistribute it and/or modify it
@@ -37,6 +39,10 @@
37 }39 }
38}40}
3941
42var (
43 syscallSync = syscall.Sync
44)
45
40type Image interface {46type Image interface {
41 Mount() error47 Mount() error
42 Unmount() error48 Unmount() error
@@ -149,40 +155,247 @@
149 return strings.TrimSpace(string(out)), err155 return strings.TrimSpace(string(out)), err
150}156}
151157
152func mount(partitions []partition) (baseMount string, err error) {158// BaseImage implements the basic primitives to manage images.
153 baseMount, err = ioutil.TempDir(os.TempDir(), "diskimage")159type BaseImage struct {
160 baseMount string
161 hardware HardwareDescription
162 location string
163 oem OemDescription
164 parts []partition
165 partCount int
166 size int64
167}
168
169// Mount mounts the image. This also maps the loop device.
170func (img *BaseImage) Mount() error {
171 if err := img.Map(); err != nil {
172 return err
173 }
174
175 baseMount, err := ioutil.TempDir(os.TempDir(), "diskimage")
154 if err != nil {176 if err != nil {
155 return "", err177 return err
156 }
157
158 // We change the mode so snappy can unpack as non root
159 if err := os.Chmod(baseMount, 0755); err != nil {
160 return "", err
161 }178 }
162179
163 //Remove Mountpoint if we fail along the way180 //Remove Mountpoint if we fail along the way
164 defer func() {181 defer func() {
165 if err != nil {182 if err != nil {
166 os.Remove(baseMount)183 if err := os.Remove(baseMount); err != nil {
184 fmt.Println("WARNING: cannot remove", baseMount, "due to", err)
185 }
167 }186 }
168 }()187 }()
169188
170 for _, part := range partitions {189 // We change the mode so snappy can unpack as non root
190 if err := os.Chmod(baseMount, 0755); err != nil {
191 return err
192 }
193
194 for _, part := range img.parts {
171 if part.fs == fsNone {195 if part.fs == fsNone {
172 continue196 continue
173 }197 }
174198
175 mountpoint := filepath.Join(baseMount, string(part.dir))199 mountpoint := filepath.Join(baseMount, string(part.dir))
176 if err := os.MkdirAll(mountpoint, 0755); err != nil {200 if err := os.MkdirAll(mountpoint, 0755); err != nil {
177 return "", err201 return err
178 }202 }
179 if out, err := exec.Command("mount", filepath.Join("/dev/mapper", part.loop), mountpoint).CombinedOutput(); err != nil {203
180 return "", fmt.Errorf("unable to mount dir to create system image: %s", out)204 dev := filepath.Join("/dev/mapper", part.loop)
181 }205 printOut("Mounting", dev, part.fs, "to", mountpoint)
182 }206 if out, errMount := exec.Command("mount", filepath.Join("/dev/mapper", part.loop), mountpoint).CombinedOutput(); errMount != nil {
183207 return ErrMount{dev: dev, mountpoint: mountpoint, fs: part.fs, out: out}
184 return baseMount, nil208 }
185209 // this is cleanup in case one of the mounts fail
210 defer func() {
211 if err != nil {
212 if err := exec.Command("umount", mountpoint).Run(); err != nil {
213 fmt.Println("WARNING:", mountpoint, "could not be unmounted")
214 return
215 }
216
217 if err := os.Remove(mountpoint); err != nil {
218 fmt.Println("WARNING: could not remove ", mountpoint)
219 }
220 }
221 }()
222 }
223 img.baseMount = baseMount
224
225 return nil
226
227}
228
229// Unmount unmounts the image. This also unmaps the loop device.
230func (img *BaseImage) Unmount() error {
231 if img.baseMount == "" {
232 panic("No base mountpoint set")
233 }
234
235 syscallSync()
236
237 for _, part := range img.parts {
238 if part.fs == fsNone {
239 continue
240 }
241
242 mountpoint := filepath.Join(img.baseMount, string(part.dir))
243 if out, err := exec.Command("umount", mountpoint).CombinedOutput(); err != nil {
244 lsof, _ := exec.Command("lsof", "-w", mountpoint).CombinedOutput()
245 printOut(string(lsof))
246 dev := filepath.Join("/dev/mapper", part.loop)
247 return ErrMount{dev: dev, mountpoint: mountpoint, fs: part.fs, out: out}
248 }
249 }
250
251 if err := os.RemoveAll(img.baseMount); err != nil {
252 return err
253 }
254 img.baseMount = ""
255
256 return img.Unmap()
257}
258
259// Map maps the image to loop devices
260func (img *BaseImage) Map() error {
261 if isMapped(img.parts) {
262 panic("cannot double map partitions")
263 }
264
265 kpartxCmd := exec.Command("kpartx", "-avs", img.location)
266 stdout, err := kpartxCmd.StdoutPipe()
267 if err != nil {
268 return err
269 }
270
271 if err := kpartxCmd.Start(); err != nil {
272 return err
273 }
274
275 loops := make([]string, 0, img.partCount)
276 scanner := bufio.NewScanner(stdout)
277 for scanner.Scan() {
278 fields := strings.Fields(scanner.Text())
279
280 if len(fields) > 2 {
281 loops = append(loops, fields[2])
282 } else {
283 return fmt.Errorf("issues while determining drive mappings (%q)", fields)
284 }
285 }
286 if err := scanner.Err(); err != nil {
287 return err
288 }
289
290 if len(loops) != img.partCount {
291 return ErrMapCount{expectedParts: img.partCount, foundParts: len(loops)}
292 }
293
294 mapPartitions(img.parts, loops)
295
296 if err := kpartxCmd.Wait(); err != nil {
297 return err
298 }
299
300 return nil
301}
302
303//Unmap destroys loop devices for the partitions
304func (img *BaseImage) Unmap() error {
305 if img.baseMount != "" {
306 panic("cannot unmap mounted partitions")
307 }
308
309 for _, part := range img.parts {
310 if err := exec.Command("dmsetup", "clear", part.loop).Run(); err != nil {
311 return err
312 }
313 }
314
315 if err := exec.Command("kpartx", "-ds", img.location).Run(); err != nil {
316 return err
317 }
318
319 unmapPartitions(img.parts)
320
321 return nil
322}
323
324// Format formats the image following the partition types and labels them
325// accordingly.
326func (img BaseImage) Format() error {
327 for _, part := range img.parts {
328 dev := filepath.Join("/dev/mapper", part.loop)
329
330 if part.fs == fsFat32 {
331 cmd := []string{"-F", "32", "-n", string(part.label)}
332
333 size, err := sectorSize(dev)
334 if err != nil {
335 return err
336 }
337
338 if size != "512" {
339 cmd = append(cmd, "-s", "1")
340 }
341
342 cmd = append(cmd, "-S", size, dev)
343
344 if out, err := exec.Command("mkfs.vfat", cmd...).CombinedOutput(); err != nil {
345 return fmt.Errorf("unable to create filesystem: %s", out)
346 }
347 } else {
348 if out, err := exec.Command("mkfs.ext4", "-F", "-L", string(part.label), dev).CombinedOutput(); err != nil {
349 return fmt.Errorf("unable to create filesystem: %s", out)
350 }
351 }
352 }
353
354 return nil
355}
356
357// User returns the writable path
358func (img BaseImage) Writable() string {
359 if img.parts == nil {
360 panic("img is not setup with partitions")
361 }
362
363 if img.baseMount == "" {
364 panic("img not mounted")
365 }
366
367 return filepath.Join(img.baseMount, string(writableDir))
368}
369
370func (img BaseImage) pathToMount(dir directory) string {
371 if img.parts == nil {
372 panic("img is not setup with partitions")
373 }
374
375 if img.baseMount == "" {
376 panic("img not mounted")
377 }
378
379 return filepath.Join(img.baseMount, string(dir))
380}
381
382//System returns the system path
383func (img BaseImage) System() string {
384 return img.pathToMount(systemADir)
385}
386
387// Boot returns the system-boot path
388func (img BaseImage) Boot() string {
389 return img.pathToMount(bootDir)
390}
391
392// BaseMount returns the base directory used to mount the image partitions.
393func (img BaseImage) BaseMount() string {
394 if img.baseMount == "" {
395 panic("image needs to be mounted")
396 }
397
398 return img.baseMount
186}399}
187400
188func printOut(args ...interface{}) {401func printOut(args ...interface{}) {
189402
=== modified file 'diskimage/core_grub.go'
--- diskimage/core_grub.go 2015-06-11 03:13:19 +0000
+++ diskimage/core_grub.go 2015-06-15 15:32:50 +0000
@@ -8,14 +8,12 @@
8package diskimage8package diskimage
99
10import (10import (
11 "bufio"
12 "errors"11 "errors"
13 "fmt"12 "fmt"
14 "io"13 "io"
15 "os"14 "os"
16 "os/exec"15 "os/exec"
17 "path/filepath"16 "path/filepath"
18 "strings"
19 "time"17 "time"
2018
21 "launchpad.net/goget-ubuntu-touch/sysutils"19 "launchpad.net/goget-ubuntu-touch/sysutils"
@@ -34,21 +32,18 @@
34// with this program. If not, see <http://www.gnu.org/licenses/>.32// with this program. If not, see <http://www.gnu.org/licenses/>.
3533
36type CoreGrubImage struct {34type CoreGrubImage struct {
37 CoreImage35 BaseImage
38 hardware HardwareDescription
39 oem OemDescription
40 location string
41 size int64
42 baseMount string
43 parts []partition
44}36}
4537
46func NewCoreGrubImage(location string, size int64, hw HardwareDescription, oem OemDescription) *CoreGrubImage {38func NewCoreGrubImage(location string, size int64, hw HardwareDescription, oem OemDescription) *CoreGrubImage {
47 return &CoreGrubImage{39 return &CoreGrubImage{
48 location: location,40 BaseImage{
49 size: size,41 location: location,
50 hardware: hw,42 size: size,
51 oem: oem,43 hardware: hw,
44 oem: oem,
45 partCount: 5,
46 },
52 }47 }
53}48}
5449
@@ -63,43 +58,6 @@
63configfile $prefix/grub.cfg58configfile $prefix/grub.cfg
64`59`
6560
66func (img *CoreGrubImage) Mount() error {
67 baseMount, err := mount(img.parts)
68 if err != nil {
69 return err
70 }
71 img.baseMount = baseMount
72
73 return nil
74}
75
76func (img *CoreGrubImage) Unmount() (err error) {
77 if img.baseMount == "" {
78 panic("No base mountpoint set")
79 }
80 defer os.Remove(img.baseMount)
81
82 if out, err := exec.Command("sync").CombinedOutput(); err != nil {
83 return fmt.Errorf("Failed to sync filesystems before unmounting: %s", out)
84 }
85
86 for _, part := range img.parts {
87 if part.fs == fsNone {
88 continue
89 }
90
91 mountpoint := filepath.Join(img.baseMount, string(part.dir))
92 if out, err := exec.Command("umount", "-l", mountpoint).CombinedOutput(); err != nil {
93 return fmt.Errorf("unable to unmount dir for image: %s", out)
94 } else {
95 }
96 }
97
98 img.baseMount = ""
99
100 return nil
101}
102
103//Partition creates a partitioned image from an img61//Partition creates a partitioned image from an img
104func (img *CoreGrubImage) Partition() error {62func (img *CoreGrubImage) Partition() error {
105 if err := sysutils.CreateEmptyFile(img.location, img.size, sysutils.GB); err != nil {63 if err := sysutils.CreateEmptyFile(img.location, img.size, sysutils.GB); err != nil {
@@ -125,150 +83,6 @@
125 return parted.create(img.location)83 return parted.create(img.location)
126}84}
12785
128//Map creates loop devices for the partitions
129func (img *CoreGrubImage) Map() error {
130 if isMapped(img.parts) {
131 panic("cannot double map partitions")
132 }
133
134 kpartxCmd := exec.Command("kpartx", "-avs", img.location)
135 stdout, err := kpartxCmd.StdoutPipe()
136 if err != nil {
137 return err
138 }
139
140 if err := kpartxCmd.Start(); err != nil {
141 return err
142 }
143
144 loops := make([]string, 0, 4)
145 scanner := bufio.NewScanner(stdout)
146 for scanner.Scan() {
147 fields := strings.Fields(scanner.Text())
148
149 if len(fields) > 2 {
150 loops = append(loops, fields[2])
151 } else {
152 return errors.New("issues while determining drive mappings")
153 }
154 }
155 if err := scanner.Err(); err != nil {
156 return err
157 }
158
159 // there are 5 partitions, so there should be five loop mounts
160 if len(loops) != 5 {
161 return errors.New("more partitions then expected while creating loop mapping")
162 }
163
164 mapPartitions(img.parts, loops)
165
166 if err := kpartxCmd.Wait(); err != nil {
167 return err
168 }
169
170 return nil
171}
172
173//Unmap destroys loop devices for the partitions
174func (img *CoreGrubImage) Unmap() error {
175 if img.baseMount != "" {
176 panic("cannot unmap mounted partitions")
177 }
178
179 for _, part := range img.parts {
180 if err := exec.Command("dmsetup", "clear", part.loop).Run(); err != nil {
181 return err
182 }
183 }
184
185 if err := exec.Command("kpartx", "-d", img.location).Run(); err != nil {
186 return err
187 }
188
189 unmapPartitions(img.parts)
190
191 return nil
192}
193
194func (img CoreGrubImage) Format() error {
195 for _, part := range img.parts {
196 dev := filepath.Join("/dev/mapper", part.loop)
197
198 if part.fs == fsFat32 {
199 cmd := []string{"-F", "32", "-n", string(part.label)}
200
201 size, err := sectorSize(dev)
202 if err != nil {
203 return err
204 }
205
206 if size != "512" {
207 cmd = append(cmd, "-s", "1")
208 }
209
210 cmd = append(cmd, "-S", size, dev)
211
212 if out, err := exec.Command("mkfs.vfat", cmd...).CombinedOutput(); err != nil {
213 return fmt.Errorf("unable to create filesystem: %s", out)
214 }
215 } else if part.fs == fsExt4 {
216 if out, err := exec.Command("mkfs.ext4", "-F", "-L", string(part.label), dev).CombinedOutput(); err != nil {
217 return fmt.Errorf("unable to create filesystem: %s", out)
218 }
219 }
220 }
221
222 return nil
223}
224
225// User returns the writable path
226func (img CoreGrubImage) Writable() string {
227 if img.parts == nil {
228 panic("img is not setup with partitions")
229 }
230
231 if img.baseMount == "" {
232 panic("img not mounted")
233 }
234
235 return filepath.Join(img.baseMount, string(writableDir))
236}
237
238// Boot returns the system-boot path
239func (img CoreGrubImage) Boot() string {
240 if img.parts == nil {
241 panic("img is not setup with partitions")
242 }
243
244 if img.baseMount == "" {
245 panic("img not mounted")
246 }
247
248 return filepath.Join(img.baseMount, string(bootDir))
249}
250
251//System returns the system path
252func (img CoreGrubImage) System() string {
253 if img.parts == nil {
254 panic("img is not setup with partitions")
255 }
256
257 if img.baseMount == "" {
258 panic("img not mounted")
259 }
260
261 return filepath.Join(img.baseMount, string(systemADir))
262}
263
264func (img CoreGrubImage) BaseMount() string {
265 if img.baseMount == "" {
266 panic("image needs to be mounted")
267 }
268
269 return img.baseMount
270}
271
272func (img *CoreGrubImage) SetupBoot(oemRootPath string) error {86func (img *CoreGrubImage) SetupBoot(oemRootPath string) error {
273 for _, dev := range []string{"dev", "proc", "sys"} {87 for _, dev := range []string{"dev", "proc", "sys"} {
274 src := filepath.Join("/", dev)88 src := filepath.Join("/", dev)
27589
=== modified file 'diskimage/core_uboot.go'
--- diskimage/core_uboot.go 2015-06-11 03:13:19 +0000
+++ diskimage/core_uboot.go 2015-06-15 15:32:50 +0000
@@ -8,14 +8,10 @@
8package diskimage8package diskimage
99
10import (10import (
11 "bufio"
12 "errors"
13 "fmt"11 "fmt"
14 "io/ioutil"12 "io/ioutil"
15 "os"13 "os"
16 "os/exec"
17 "path/filepath"14 "path/filepath"
18 "strings"
19 "text/template"15 "text/template"
2016
21 "launchpad.net/goget-ubuntu-touch/sysutils"17 "launchpad.net/goget-ubuntu-touch/sysutils"
@@ -34,14 +30,7 @@
34// with this program. If not, see <http://www.gnu.org/licenses/>.30// with this program. If not, see <http://www.gnu.org/licenses/>.
3531
36type CoreUBootImage struct {32type CoreUBootImage struct {
37 CoreImage33 BaseImage
38 SystemImage
39 hardware HardwareDescription
40 oem OemDescription
41 location string
42 size int64
43 baseMount string
44 parts []partition
45}34}
4635
47const snappySystemTemplate = `# This is a snappy variables and boot logic file and is entirely generated and36const snappySystemTemplate = `# This is a snappy variables and boot logic file and is entirely generated and
@@ -79,44 +68,14 @@
7968
80func NewCoreUBootImage(location string, size int64, hw HardwareDescription, oem OemDescription) *CoreUBootImage {69func NewCoreUBootImage(location string, size int64, hw HardwareDescription, oem OemDescription) *CoreUBootImage {
81 return &CoreUBootImage{70 return &CoreUBootImage{
82 hardware: hw,71 BaseImage{
83 oem: oem,72 hardware: hw,
84 location: location,73 oem: oem,
85 size: size,74 location: location,
86 }75 size: size,
87}76 partCount: 4,
8877 },
89func (img *CoreUBootImage) Mount() error {78 }
90 baseMount, err := mount(img.parts)
91 if err != nil {
92 return err
93 }
94 img.baseMount = baseMount
95
96 return nil
97}
98
99func (img *CoreUBootImage) Unmount() (err error) {
100 if img.baseMount == "" {
101 panic("No base mountpoint set")
102 }
103 defer func() {
104 os.Remove(img.baseMount)
105 img.baseMount = ""
106 }()
107
108 if out, err := exec.Command("sync").CombinedOutput(); err != nil {
109 return fmt.Errorf("Failed to sync filesystems before unmounting: %s", out)
110 }
111
112 for _, part := range img.parts {
113 mountpoint := filepath.Join(img.baseMount, string(part.dir))
114 if out, err := exec.Command("umount", "-l", mountpoint).CombinedOutput(); err != nil {
115 panic(fmt.Sprintf("unable to unmount dir for image: %s", out))
116 }
117 }
118
119 return nil
120}79}
12180
122//Partition creates a partitioned image from an img81//Partition creates a partitioned image from an img
@@ -142,137 +101,6 @@
142 return parted.create(img.location)101 return parted.create(img.location)
143}102}
144103
145//Map creates loop devices for the partitions
146func (img *CoreUBootImage) Map() error {
147 if isMapped(img.parts) {
148 panic("cannot double map partitions")
149 }
150
151 kpartxCmd := exec.Command("kpartx", "-avs", img.location)
152 stdout, err := kpartxCmd.StdoutPipe()
153 if err != nil {
154 return err
155 }
156
157 if err := kpartxCmd.Start(); err != nil {
158 return err
159 }
160
161 loops := make([]string, 0, 4)
162 scanner := bufio.NewScanner(stdout)
163 for scanner.Scan() {
164 fields := strings.Fields(scanner.Text())
165
166 if len(fields) > 2 {
167 loops = append(loops, fields[2])
168 } else {
169 return errors.New("issues while determining drive mappings")
170 }
171 }
172 if err := scanner.Err(); err != nil {
173 return err
174 }
175
176 // there are 5 partitions, so there should be five loop mounts
177 if len(loops) != 4 {
178 return errors.New("more partitions then expected while creating loop mapping")
179 }
180
181 mapPartitions(img.parts, loops)
182
183 if err := kpartxCmd.Wait(); err != nil {
184 return err
185 }
186
187 return nil
188}
189
190//Unmap destroys loop devices for the partitions
191func (img *CoreUBootImage) Unmap() error {
192 if img.baseMount != "" {
193 panic("cannot unmap mounted partitions")
194 }
195
196 for _, part := range img.parts {
197 if err := exec.Command("dmsetup", "clear", part.loop).Run(); err != nil {
198 return err
199 }
200 }
201
202 if err := exec.Command("kpartx", "-d", img.location).Run(); err != nil {
203 return err
204 }
205
206 unmapPartitions(img.parts)
207
208 return nil
209}
210
211func (img CoreUBootImage) Format() error {
212 for _, part := range img.parts {
213 dev := filepath.Join("/dev/mapper", part.loop)
214
215 if part.fs == fsFat32 {
216 cmd := []string{"-F", "32", "-n", string(part.label)}
217
218 size, err := sectorSize(dev)
219 if err != nil {
220 return err
221 }
222
223 if size != "512" {
224 cmd = append(cmd, "-s", "1")
225 }
226
227 cmd = append(cmd, "-S", size, dev)
228
229 if out, err := exec.Command("mkfs.vfat", cmd...).CombinedOutput(); err != nil {
230 return fmt.Errorf("unable to create filesystem: %s", out)
231 }
232 } else {
233 if out, err := exec.Command("mkfs.ext4", "-F", "-L", string(part.label), dev).CombinedOutput(); err != nil {
234 return fmt.Errorf("unable to create filesystem: %s", out)
235 }
236 }
237 }
238
239 return nil
240}
241
242// User returns the writable path
243func (img *CoreUBootImage) Writable() string {
244 if img.parts == nil {
245 panic("img is not setup with partitions")
246 }
247
248 if img.baseMount == "" {
249 panic("img not mounted")
250 }
251
252 return filepath.Join(img.baseMount, string(writableDir))
253}
254
255//System returns the system path
256func (img *CoreUBootImage) System() string {
257 if img.parts == nil {
258 panic("img is not setup with partitions")
259 }
260
261 if img.baseMount == "" {
262 panic("img not mounted")
263 }
264
265 return filepath.Join(img.baseMount, string(systemADir))
266}
267
268func (img CoreUBootImage) BaseMount() string {
269 if img.baseMount == "" {
270 panic("image needs to be mounted")
271 }
272
273 return img.baseMount
274}
275
276func (img CoreUBootImage) SetupBoot(oemRootPath string) error {104func (img CoreUBootImage) SetupBoot(oemRootPath string) error {
277 // destinations105 // destinations
278 bootPath := filepath.Join(img.baseMount, string(bootDir))106 bootPath := filepath.Join(img.baseMount, string(bootDir))
279107
=== added file 'diskimage/errors.go'
--- diskimage/errors.go 1970-01-01 00:00:00 +0000
+++ diskimage/errors.go 2015-06-15 15:32:50 +0000
@@ -0,0 +1,32 @@
1//
2// diskimage - handles ubuntu disk images
3//
4// Copyright (c) 2015 Canonical Ltd.
5//
6// Written by Sergio Schvezov <sergio.schvezov@canonical.com>
7//
8package diskimage
9
10import "fmt"
11
12// ErrMount represents a mount error
13type ErrMount struct {
14 dev string
15 mountpoint string
16 fs fsType
17 out []byte
18}
19
20func (e ErrMount) Error() string {
21 return fmt.Sprintf("cannot mount %s(%s) on %s: %s", e.dev, e.fs, e.mountpoint, e.out)
22}
23
24// ErrMapCount represents an error on the expected amount of partitions
25type ErrMapCount struct {
26 foundParts int
27 expectedParts int
28}
29
30func (e ErrMapCount) Error() string {
31 return fmt.Sprintf("expected %d partitons but found %d", e.expectedParts, e.foundParts)
32}
033
=== modified file 'ubuntu-device-flash/core.go'
--- ubuntu-device-flash/core.go 2015-06-09 13:57:34 +0000
+++ ubuntu-device-flash/core.go 2015-06-15 15:32:50 +0000
@@ -322,24 +322,14 @@
322}322}
323323
324func (coreCmd *CoreCmd) setup(img diskimage.CoreImage, filePathChan <-chan string, fileCount int) error {324func (coreCmd *CoreCmd) setup(img diskimage.CoreImage, filePathChan <-chan string, fileCount int) error {
325 printOut("Mapping...")
326 if err := img.Map(); err != nil {
327 return err
328 }
329 defer func() {
330 printOut("Unmapping...")
331 defer img.Unmap()
332 }()
333
334 printOut("Mounting...")325 printOut("Mounting...")
335 if err := img.Mount(); err != nil {326 if err := img.Mount(); err != nil {
336 fmt.Println(err)
337 return err327 return err
338 }328 }
339 defer func() {329 defer func() {
340 printOut("Unmounting...")330 printOut("Unmounting...")
341 if err := img.Unmount(); err != nil {331 if err := img.Unmount(); err != nil {
342 fmt.Println(err)332 fmt.Println("WARNING: unexpected issue:", err)
343 }333 }
344 }()334 }()
345335

Subscribers

People subscribed via source and target branches