File: isenkram-autoinstall-firmware

package info (click to toggle)
isenkram 0.33
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 3,184 kB
  • ctags: 71
  • sloc: python: 562; sh: 298; perl: 53; makefile: 15
file content (172 lines) | stat: -rwxr-xr-x 4,770 bytes parent folder | download
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
#!/bin/sh
#
# Find missing firmware files requested by the kernel, and install the
# binary packages with the files.  Fetch them the from the non-free section
# if that is needed.
#
# This script was copied from auto-addfirmware from the debian-edu-config
# package and extended here.

PATH=/sbin:/usr/sbin:$PATH
export PATH

dist=$(lsb_release -cs)
if [ "n/a" = "$dist" ] ; then
    dist=testing
fi
arch=$(dpkg --print-architecture)
mirror=http://httpredir.debian.org/debian
aptsourcelist=/etc/apt/sources.list.d/isenkram-autoinstall-firmware.list

if [ "-l" = "$1" ] ; then
    listonly=true
else
    listonly=false
fi

loginfo() {
    echo "info: $@" 1>&2
}

add_contrib_nonfree() {
    if $listonly ; then
	return
    fi
    cat <<EOF > $aptsourcelist
deb $mirror $dist contrib non-free
deb-src $mirror $dist contrib non-free
EOF
    chmod a+r $aptsourcelist
    echo "apt updated" > $nonfreeflag
}

appstreamlookup() {
    fwfile="$1"
    appstreamcli what-provides firmware:runtime "$fwfile" | \
	awk '/Package:/ { print $2}'
}

# Find firmware files requested by loaded kernel drivers.
for fwfile in $(for module in $(awk '{print $1}' /proc/modules) ; do modinfo $module 2>/dev/null |awk '/^firmware:/ {print $2}'; done|sort -u); do
    if [ ! -e /lib/firmware/$fwfile ] ; then
	fwfiles="${fwfiles:+$fwfiles }$fwfile"
    fi
done

# Also look in dmesg for requested firmware for modules that refuse to
# load without their firmware.  See also bug #725714.
if dmesg >/dev/null 2>&1 ; then
    for fwfile in $(dmesg | sed -rn 's/^(\[[^]]*\] )?([^ ]+) [^ ]+: firmware: failed to load ([^ ]+) .*/\3/p'); do
	loginfo "looking for firmware file $fwfile requested by kernel"
	if [ ! -e /lib/firmware/$fwfile ] ; then
            fwfiles="${fwfiles:+$fwfiles }$fwfile"
	fi
    done
else
    loginfo "unable to check dmesg, list might be incomplete"
fi

if [ -z "$fwfiles" ] ; then
    loginfo "did not find any firmware files requested by loaded kernel modules.  exiting"
    exit 1
fi
loginfo "some kernel driver requested extra firmware files:" $fwfiles

tmpdir=$(mktemp -d)
nonfreeflag=nonfreeflag
cd $tmpdir || exit 1

cleanup() {
    cd /
    rm -rf $tmpdir
}

fetch_latest_data() {
    for section in "main" "contrib" "non-free"; do
        # "" is main in Wheezy.
	if [  main = "$section" ] && [ wheezy = "$dist" ]; then
	    url="$mirror/dists/$dist/Contents-$arch.gz"
	else
	    url="$mirror/dists/$dist/$section/Contents-$arch.gz"
	fi
	loginfo "fetching $url"
	curl --location $url | gunzip | grep ^lib/firmware > Fw-Contents-$arch-$dist-$section
    done
}

# Prefer appstream and use the local copy of firmware->package
# mappings if nothing is found using appstream.  Downloading apt-file
# data is disabled as the local files are available both in Debian
# stable, testing and unstable, and appstream allow for dynamic
# updates.

#fetch_latest_data

datafiles=""
for f in Fw-Contents-$arch-$dist-* \
    /usr/share/isenkram/Fw-Contents-$arch-$dist-* ; do
    if [ -s "$f" ] ; then
	datafiles="$datafiles $f"
    fi
done

if [ "$datafiles" ] ; then
    loginfo "locating packages with the requested firmware files"
    binpkginfos=""
    binpkgs=""
    for fwfile in $fwfiles ; do
	# First check appstream, next look in our local files
	binpkginfo=$(appstreamlookup $fwfile)
	if [ -z "$binpkginfo" ] ; then
	    fwfilere=$(echo $fwfile | sed -e 's%/%\\/%g' -e 's/\./\\./g')
	    binpkginfo="$(awk "/^lib\/firmware\/$fwfilere/ {print \$2}" $datafiles)"
	fi
	if [ -z "$binpkginfo" ] ; then
 	    # Special case for b43 where the firmware is
	    # undistributable by Debian.
	    case "$fwfile" in
		b43/*)
		    add_contrib_nonfree
		    binpkgs="${binpkgs:+$binpkgs }firmware-b43-installer"
		    ;;
	    esac
	else
	    binpkginfos="$binpkginfos $binpkginfo"
	fi
    done
else
    loginfo "unable to find any firmware info for dist $dist"
fi

binpkgs="${binpkgs:+$binpkgs }$(
for binpkginfo in $binpkginfos ; do
    echo $binpkginfo |  while IFS=/ read section srcpkg binpkg ; do
        echo $binpkg
# Enable the non-free section if it is needed
	if LC_ALL=C apt-cache show $binpkg 2>&1 | \
               grep -q 'E: No packages found' \
           && ( [ non-free = "$section" ] \
               || [ contrib = "$section" ] ) ; then 
	    add_contrib_nonfree
	fi
    done
done)"

if [ -e $nonfreeflag ] && ! $listonly ; then
    # Fetch updated package lists
    loginfo "Updating APT sources after adding non-free APT source"
    apt-get -qq update
fi

if [ "$binpkgs" ] ; then
    if $listonly ; then
	echo $binpkgs | tr " " "\n" | sort -u
    else
        # Install firmware packages
	loginfo "trying to install $binpkgs"
	apt-get -qq install -y $binpkgs
    fi
else
    loginfo "No new firmware package with requested firmware detected."
fi
cleanup