aboutsummaryrefslogtreecommitdiff
blob: 8b365544625a29faf0193cad9d68480fa1fde862 (plain)
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#!/bin/bash
# vim: set sw=4 sts=4 et :


# Directory from which we will rsync portage to chroot
PORTAGE_DIR=/usr/portage

# stage tarball path
STAGE_TARBALL=""


# ==================================================================
#                       CODE
# ===================================================================


help()
{
    echo "Usage: `basename $0` OPTIONS BASE_CHROOT_DIR WORK_CHROOT_DIR"
    echo
    echo "   -c                 force clean BASE_CHROOT if it exists and start over from scratch"
    echo "   -p PORTAGE_DIR     directory where portage is (default is /usr/portage)"
    echo "   -s STAGE_FILE      stage file used to create base chroot directory"
    
    exit 1
}

clean_work_chroot()
{
    echo -n "Cleaning work chroot..."
    if [ -d $WORK_CHROOT ];then
        for dir in {"PKGDIR","DISTDIR"};do
            umount_dir $dir
        done
        for dir in $WORK_CHROOT/{"/dev","/proc","/sys","$PORTAGE_DIR"};do
            umount "$dir" || umount -l "$dir"
        done

        rm -rf --one-file-system "$WORK_CHROOT"
    fi
    echo Done
}

clean_base_chroot()
{
    echo -n "Cleaning base chroot..."
    if [ -d "$BASE_CHROOT" ];then
        rm -rf --one-file-system "$BASE_CHROOT"
    fi
    if [ -f "$BASE_CHROOT.tar" ];then
        rm -f "$BASE_CHROOT.tar"
    fi
    echo Done
}

GPSRET=""
get_portage_setting()
{
    setting=`grep $1 "$BASE_CHROOT/etc/make.conf" | sed -e "s/.*$1[[:space:]]*=[[:space:]]*//;s/\"//g;"`
    if [ "y$setting" == "y" ];then
        case $1 in
          "PORTDIR" )
                GPSRET=`portageq portdir`
                return 0;;
          "DISTDIR" )
                GPSRET=`portageq distdir`
                return 0;;
          "PKGDIR" )
                GPSRET=`portageq pkgdir`
                return 0;;
          * )
                return 1;;
        esac
    fi
    GPSRET=$setting
    return 0;
}

mount_dir()
{
    get_portage_setting $1
    if [ $? -eq 0 ];then
        if [ ! -e "$GPSRET" ];then
            mkdir -p "$GPSRET"
        fi
        mkdir -p "$WORK_CHROOT/$GPSRET"
        mount -o bind "$GPSRET" "$WORK_CHROOT/$GPSRET"
    else
        echo "Unable to get setting for $1 variable"
        exit 1
    fi
}

umount_dir()
{
    get_portage_setting $1
    umount "$WORK_CHROOT/$GPSRET" || umount -l "$WORK_CHROOT/$GPSRET"
}

FORCE_CLEAN_BASE=0

while getopts "p:s:c" Option
do
  case $Option in
    p ) PORTAGE_DIR="$OPTARG";;
    s ) STAGE_TARBALL="$OPTARG";;
    c ) FORCE_CLEAN_BASE=1;;
    * ) echo "Unimplemented option chosen.";;   # DEFAULT
  esac
done


shift $(($OPTIND - 1))

if [ $# -ne 2 ];then
    echo "Wrong number of arguments"
    help
fi

BASE_CHROOT="$1"
WORK_CHROOT="$2"

echo "Using settings:"
echo "base chroot directory: $BASE_CHROOT"
echo "work chroot directory: $WORK_CHROOT"
echo "portage directory:     $PORTAGE_DIR"
echo "stage tarball:         $STAGE_TARBALL"


if [ $FORCE_CLEAN_BASE -eq 1 ];then
    clean_base_chroot    
fi

if [ -d "$BASE_CHROOT" ];then 
    echo "We found $BASE_CHROOT directory, assuming it's ready"
else
    if [ -z "$STAGE_TARBALL" ];then
        echo "We need stage tarball to create base chroot!! (option -s)"
        help
    fi

    # we will need to create usr/ anyway so why not do it at once
    mkdir -p "$BASE_CHROOT/usr"

    echo -n "Unpacking stage tarball..."
    tar xf "$STAGE_TARBALL" -C "$BASE_CHROOT"
    if [ $? -ne 0 ];then
        echo "Errors unpacking stage tarball, bailing out!!!"
        rm -rf "$BASE_CHROOT"
        exit 1
    fi
    echo Done

    rm -rf --one-file-system "$BASE_CHROOT/etc/portage/"
    mkdir -p "$BASE_CHROOT/etc/portage"
    
    echo -n "Copying settings..."
    cp -L /etc/resolv.conf "$BASE_CHROOT/etc"
    cp -L /etc/make.conf "$BASE_CHROOT/etc"
    cp -RL /etc/portage "$BASE_CHROOT/etc"
    echo Done

fi

if [ ! -f "$BASE_CHROOT.tar" ];then
    echo -n "Creating tar from $BASE_CHROOT..."
    tar cf "$BASE_CHROOT.tar" -C "$BASE_CHROOT" .
    if [ $? -ne 0 ];then
        echo "Creating tar from $BASE_CHROOT failed, bailing out!!!"
        rm -rf "$BASE_CHROOT"
        exit 1
    fi
    echo Done
fi

clean_work_chroot

echo -n "Untaring base chroot to work chroot now"
mkdir -p "$WORK_CHROOT"
tar pxf "$BASE_CHROOT.tar" -C "$WORK_CHROOT"
if [ $? -ne 0 ];then
    echo "There were problems unpacking base chroot to work chroot!!"
    exit 1
fi
echo Done



echo -n "Mounting filesystems..."
mount -t proc none "$WORK_CHROOT/proc"
mount -o bind /dev "$WORK_CHROOT/dev"
mount -o bind /sys "$WORK_CHROOT/sys"

mkdir -p "$WORK_CHROOT/usr/portage"
mount -o bind "$PORTAGE_DIR" "$WORK_CHROOT/usr/portage"
# this is bug/issue with current kernels, ro binds don't work so we have to remount
mount -o remount,ro "$WORK_CHROOT/usr/portage"


mount_dir "DISTDIR"
mount_dir "PKGDIR"



echo Done


echo -n "Chrooting and updating env..."
# so that we can run env-update 
chroot "$WORK_CHROOT" /usr/sbin/env-update
echo Done

exit 0