forked from snapcore/snapd
/
mkfs.go
123 lines (112 loc) · 3.36 KB
/
mkfs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2019 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package gadget
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"github.com/snapcore/snapd/osutil"
)
// MkfsExt4 creates an EXT4 filesystem in given image file, with an optional
// filesystem label, and populates it with the contents of provided root
// directory.
func MkfsExt4(img, label, contentsRootDir string) error {
// taken from ubuntu-image
mkfsArgs := []string{
"mkfs.ext4",
// default usage type
"-T", "default",
// disable metadata checksum, which were unsupported in Ubuntu
// 16.04 and Ubuntu Core 16 systems and would lead to a boot
// failure if enabled
"-O", "-metadata_csum",
// allow uninitialized block groups
"-O", "uninit_bg",
// mkfs.ext4 can populate the filesystem with contents of given
// root directory
// TODO: support e2fsprogs 1.42 without -d in Ubuntu 16.04
"-d", contentsRootDir,
}
if label != "" {
mkfsArgs = append(mkfsArgs, "-L", label)
}
mkfsArgs = append(mkfsArgs, img)
// run through fakeroot so that files are owned by root
cmd := exec.Command("fakeroot", mkfsArgs...)
out, err := cmd.CombinedOutput()
if err != nil {
return osutil.OutputErr(out, err)
}
return nil
}
// MkfsVfat creates a VFAT filesystem in given image file, with an optional
// filesystem label, and populates it with the contents of provided root
// directory.
func MkfsVfat(img, label, contentsRootDir string) error {
// taken from ubuntu-image
mkfsArgs := []string{
// 512B logical sector size
"-S", "512",
// 1 sector per cluster
"-s", "1",
// 32b FAT size
"-F", "32",
}
if label != "" {
mkfsArgs = append(mkfsArgs, "-n", label)
}
mkfsArgs = append(mkfsArgs, img)
cmd := exec.Command("mkfs.vfat", mkfsArgs...)
out, err := cmd.CombinedOutput()
if err != nil {
return osutil.OutputErr(out, err)
}
// mkfs.vfat does not know how to populate the filesystem with contents,
// we need to do the work ourselves
fis, err := ioutil.ReadDir(contentsRootDir)
if err != nil {
return fmt.Errorf("cannot list directory contents: %v", err)
}
if len(fis) == 0 {
// nothing to copy to the image
return nil
}
mcopyArgs := make([]string, 0, 4+len(fis))
mcopyArgs = append(mcopyArgs,
// recursive copy
"-s",
// image file
"-i", img)
for _, fi := range fis {
mcopyArgs = append(mcopyArgs, filepath.Join(contentsRootDir, fi.Name()))
}
mcopyArgs = append(mcopyArgs,
// place content at the / of the filesystem
"::")
cmd = exec.Command("mcopy", mcopyArgs...)
cmd.Env = os.Environ()
// skip mtools checks to avoid unnecessary warnings
cmd.Env = append(cmd.Env, "MTOOLS_SKIP_CHECK=1")
out, err = cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("cannot populate vfat filesystem with contents: %v", osutil.OutputErr(out, err))
}
return nil
}