|
root / base / hammerhead-userland / build.sh
build.sh Bash 188 lines 5.9 KB
  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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/bin/ksh93
# Build script for hammerhead-userland
# Packages commands, libraries, headers, and system configuration from proto area
#
# Requires PROTO_AREA to be set to the hammerhead proto path, e.g.:
#   export PROTO_AREA=/usr/src/hammerhead-build/root_amd64
#
# Optional: ROOTFS_DIR for rootfs overlay (config files, ownership manifest)
#   export ROOTFS_DIR=/usr/src/hammerhead/rootfs

set -e

PROTO_AREA="${PROTO_AREA:?PROTO_AREA must be set to hammerhead proto path}"

# Validate required directories
for dir in bin sbin lib usr etc var; do
    if [ ! -d "$PROTO_AREA/$dir" ]; then
        printf "ERROR: %s/%s does not exist\n" "$PROTO_AREA" "$dir"
        printf "Has the hammerhead build completed successfully?\n"
        exit 1
    fi
done

# Validate critical files
for f in lib/libc.so.1 lib/ld.so.1 sbin/init; do
    if [ ! -f "$PROTO_AREA/$f" ]; then
        printf "ERROR: %s not found in proto area\n" "$f"
        exit 1
    fi
done

# --- /bin (real directory with boot-essential commands) ---
printf "Packaging bin...\n"
mkdir -p "$PKGDIR/bin"
(cd "$PROTO_AREA/bin" && find . | cpio -pdm "$PKGDIR/bin" 2>/dev/null)

# --- /sbin (essential system commands) ---
printf "Packaging sbin...\n"
mkdir -p "$PKGDIR/sbin"
(cd "$PROTO_AREA/sbin" && find . | cpio -pdm "$PKGDIR/sbin" 2>/dev/null)

# --- /lib (essential libraries + SMF infrastructure) ---
printf "Packaging lib...\n"
mkdir -p "$PKGDIR/lib"
(cd "$PROTO_AREA/lib" && find . | cpio -pdm "$PKGDIR/lib" 2>/dev/null)

# --- /usr (commands, libraries, headers, man pages, data) ---
printf "Packaging usr...\n"
mkdir -p "$PKGDIR/usr"
(cd "$PROTO_AREA/usr" && find . | cpio -pdm "$PKGDIR/usr" 2>/dev/null)

# --- /etc (system configuration) ---
# Exclude system-specific runtime files that are populated at install time
# or by the kernel. These must NOT be overwritten on upgrade.
printf "Packaging etc...\n"
mkdir -p "$PKGDIR/etc"
(cd "$PROTO_AREA/etc" && find . \
    ! -name name_to_major \
    ! -name path_to_inst \
    ! -name driver_aliases \
    ! -name driver_classes \
    ! -name minor_perm \
    ! -name device.tab \
    ! -name devlink.tab \
    ! -name dacf.conf \
    ! -name iu.ap \
    ! -name mnttab \
    ! -name utmpx \
    ! -name wtmpx \
    | cpio -pdm "$PKGDIR/etc" 2>/dev/null)

# --- /var (state directories — mostly empty structure) ---
printf "Packaging var...\n"
mkdir -p "$PKGDIR/var"
(cd "$PROTO_AREA/var" && find . | cpio -pdm "$PKGDIR/var" 2>/dev/null)

# --- Apply rootfs overlay ---
# These are Hammerhead-specific config files that override proto defaults
if [ -n "$ROOTFS_DIR" ] && [ -d "$ROOTFS_DIR" ]; then
    printf "Applying rootfs overlay...\n"
    for overlay_dir in etc lib root; do
        if [ -d "$ROOTFS_DIR/$overlay_dir" ]; then
            (cd "$ROOTFS_DIR/$overlay_dir" && find . | cpio -pdm "$PKGDIR/$overlay_dir" 2>/dev/null)
        fi
    done
    # Copy .zshrc for root
    if [ -f "$ROOTFS_DIR/root/.zshrc" ]; then
        mkdir -p "$PKGDIR/root"
        cp "$ROOTFS_DIR/root/.zshrc" "$PKGDIR/root/.zshrc"
    fi
fi

# --- Remove items that should NOT be packaged ---
# Build tools
rm -rf "$PKGDIR/opt/onbld" 2>/dev/null || true
# Test suites (large, not needed on target)
rm -rf "$PKGDIR/opt/"*-tests 2>/dev/null || true
rm -rf "$PKGDIR/opt/test-runner" 2>/dev/null || true
# Build system remnants
rm -rf "$PKGDIR/usr/src" 2>/dev/null || true

# --- Apply ownership from manifest ---
if [ -n "$ROOTFS_DIR" ] && [ -f "$ROOTFS_DIR/ownership.manifest" ]; then
    printf "Applying ownership manifest...\n"

    # Phase 1: bulk defaults
    chown -R root:sys "$PKGDIR/"
    chown -R root:bin "$PKGDIR/bin" "$PKGDIR/sbin" \
        "$PKGDIR/usr/bin" "$PKGDIR/usr/sbin" \
        "$PKGDIR/usr/lib" "$PKGDIR/lib" 2>/dev/null || true

    # Phase 2: per-file overrides from manifest
    while IFS=' ' read -r path mode owner group; do
        # Skip comments and blank lines
        [[ -z "$path" || "$path" = \#* ]] && continue
        target="$PKGDIR$path"
        if [ -e "$target" ] || [ -L "$target" ]; then
            chmod "$mode" "$target" 2>/dev/null || true
            chown "$owner:$group" "$target" 2>/dev/null || true
        fi
    done < "$ROOTFS_DIR/ownership.manifest"
else
    # No manifest — apply bulk defaults only
    printf "WARNING: No ownership manifest found, applying bulk defaults\n"
    chown -R root:sys "$PKGDIR/"
    chown -R root:bin "$PKGDIR/bin" "$PKGDIR/sbin" \
        "$PKGDIR/usr/bin" "$PKGDIR/usr/sbin" \
        "$PKGDIR/usr/lib" "$PKGDIR/lib" 2>/dev/null || true
fi

# --- Create .CONFIG (config-protected files) ---
# These files will not be overwritten on upgrade if user has modified them.
# New versions are installed as <file>.pkg for manual merging.
cat > "$PKGDIR/.CONFIG" << 'EOF'
/etc/system
/etc/vfstab
/etc/passwd
/etc/shadow
/etc/group
/etc/hosts
/etc/inet/hosts
/etc/nsswitch.conf
/etc/resolv.conf
/etc/nodename
/etc/pam.conf
/etc/profile
/etc/zshenv
/etc/zshrc
/etc/zprofile
/etc/default/init
/etc/default/login
/etc/default/useradd
/etc/security/policy.conf
/etc/security/crypt.conf
/etc/crypto/pkcs11.conf
/etc/ssh/sshd_config
/etc/syslog.conf
/etc/sudoers.d/zygaena
/etc/svc/profile/site.xml
/etc/coral/coral.conf
EOF

# --- Post-install script ---
mkdir -p "$PKGDIR/.SCRIPTS"
cat > "$PKGDIR/.SCRIPTS/post-install.sh" << 'SCRIPT'
#!/bin/ksh93
# Refresh SMF repository if svc.configd is running (live system upgrade)
if [ -f /lib/svc/bin/svc.configd ]; then
    if pgrep -x svc.configd >/dev/null 2>&1; then
        printf "Refreshing SMF manifests...\n"
        svccfg import /lib/svc/manifest 2>/dev/null || true
    fi
fi
SCRIPT
chmod 755 "$PKGDIR/.SCRIPTS/post-install.sh"

# --- Summary ---
CMDS=0
for d in "$PKGDIR/bin" "$PKGDIR/sbin" "$PKGDIR/usr/bin" "$PKGDIR/usr/sbin"; do
    if [ -d "$d" ]; then
        n=$(find "$d" -type f | wc -l)
        CMDS=$((CMDS + n))
    fi
done
LIBS=$(find "$PKGDIR/lib" "$PKGDIR/usr/lib" -name "*.so.*" -type f 2>/dev/null | wc -l)
SIZE=$(du -sh "$PKGDIR" | cut -f1)
printf "Packaged %d commands, %d libraries (%s total)\n" "$CMDS" "$LIBS" "$SIZE"