installer: Rework downloading ISO and allow using a custom URL

This commit is contained in:
Michael Tremer
2014-10-25 14:56:23 +02:00
parent 2404450b40
commit c0511f3ab3
8 changed files with 193 additions and 66 deletions

View File

@@ -31,6 +31,7 @@ DIR_APP = $(DIR_SRC)/$(THISAPP)
TARGET = $(DIR_INFO)/$(THISAPP)
SLOGAN = An Open Source Firewall Solution
DOWNLOAD_URL = http://downloads.ipfire.org/releases/ipfire-2.x/$(VERSION)-core$(CORE)/$(SNAME)-$(VERSION).$(MACHINE)-full-core$(CORE).iso
###############################################################################
# Top-level Rules
@@ -58,12 +59,11 @@ $(TARGET) :
--with-distro-name="$(NAME)" \
--with-distro-sname="$(SNAME)" \
--with-distro-slogan="$(SLOGAN)" \
--with-config-root="$(CONFIG_ROOT)"
--with-config-root="$(CONFIG_ROOT)" \
--with-download-url="$(DOWNLOAD_URL)"
cd $(DIR_APP) && make $(MAKETUNING)
cd $(DIR_APP) && make install
#Patch ISO Name for download ...
#sed -i -e "s|ipfire.iso|download.ipfire.org/releases/ipfire-2.x/$(VERSION)-core$(CORE)/$(SNAME)-$(VERSION).$(MACHINE)-full-core$(CORE).iso|g" \
# /usr/bin/downloadsource.sh
@rm -rf $(DIR_APP)
@$(POSTBUILD)

View File

@@ -84,6 +84,11 @@ AC_ARG_WITH([config-root],
AC_DEFINE_UNQUOTED([CONFIG_ROOT], "$withval", [The config-root]),
AC_MSG_ERROR([*** you need to set CONFIG_ROOT with --with-config-root=]))
AC_ARG_WITH([download-url],
AS_HELP_STRING([--with-download-url] [The default download URL]),
AC_DEFINE_UNQUOTED([DOWNLOAD_URL], "$withval", [The default download URL]),
AC_MSG_ERROR([*** you need to set DOWNLOAD_URL with --with-download-url=]))
AC_CONFIG_FILES([
Makefile
po/Makefile.in

View File

@@ -19,29 +19,39 @@
# #
###############################################################################
#lfs change the url while build!
IPFireISO=ipfire.iso
#
function download() {
wget -U "IPFire-NetInstall/2.x" "$@"
}
#Get user defined download from boot cmdline
grep "netinstall=" /proc/cmdline > /dev/null && CMDLINE=1
if ( [ "$CMDLINE" == "1" ]); then
read CMDLINE < /proc/cmdline
POS=${CMDLINE%%netinstall*}
POS=${#POS}
IPFireISO=`echo ${CMDLINE:POS} | cut -d"=" -f2 | cut -d" " -f1`
if [ $# -lt 2 ]; then
echo "$0: Insufficient number of arguments" >&2
exit 2
fi
echo "Download with wget..."
wget $IPFireISO -O /tmp/download.iso -t3 -U IPFire_NetInstall/2.x
wget $IPFireISO.md5 -O /tmp/download.iso.md5 -t3 -U IPFire_NetInstall/2.x
echo
echo "Checking download..."
md5_file=`md5sum /tmp/download.iso | cut -d" " -f1`
md5_down=`cat /tmp/download.iso.md5 | cut -d" " -f1`
if [ "$md5_file" == "$md5_down" ]; then
echo -n "/tmp/download.iso" > /tmp/source_device
exit 0
OUTPUT="${1}"
URL="${2}"
echo "Downloading ${URL}..."
if ! download -O "${OUTPUT}" "${URL}"; then
echo "Download failed" >&2
rm -f "${OUTPUT}"
exit 1
fi
echo "Error - SKIP"
exit 10
# Download went well. Checking for MD5 sum
if download -O "${OUTPUT}.md5" "${URL}.md5" &>/dev/null; then
# Read downloaded checksum
read -r md5sum rest < "${OUTPUT}.md5"
rm -f "${OUTPUT}.md5"
# Compute checkum of downloaded image file
read -r md5sum_image rest <<< "$(md5sum "${OUTPUT}")"
if [ "${md5sum}" != "${md5sum_image}" ]; then
echo "MD5 sum mismatch: ${md5sum} != ${md5sum_image}" >&2
exit 2
fi
fi
exit 0

View File

@@ -12,21 +12,45 @@
#
########################################################################
dhcpcd_up()
{
LEASE_FILE="/var/ipfire/dhcpc/dhcpcd-${interface}.info"
export_lease() {
set | grep "^new_" | sed "s|^new_||g" | \
sed "s|'||g" | \
sort > /var/ipfire/dhcpc/dhcpcd-$interface.info
DNS=`grep "domain_name_servers" /var/ipfire/dhcpc/dhcpcd-$interface.info | cut -d"=" -f2`
DNS1=`echo $DNS | cut -d" " -f1`
DNS2=`echo $DNS | cut -d" " -f2`
echo "nameserver $DNS1" > /etc/resolv.conf
echo "nameserver $DNS2" >> /etc/resolv.conf
sed "s|'||g" | sort > ${LEASE_FILE}
}
case "$reason" in
BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT|STATIC) dhcpcd_up;;
make_resolvconf() {
local DNS="$(grep 'domain_name_servers' ${LEASE_FILE} | cut -d'=' -f2)"
local DNS1="$(echo ${DNS} | cut -d' ' -f1)"
local DNS2="$(echo ${DNS} | cut -d' ' -f2)"
(
echo "nameserver ${DNS1}"
echo "nameserver ${DNS2}"
) > /etc/resolv.conf
}
case "${reason}" in
PREINIT)
# Configure MTU
if [ -n "${new_interface_mtu}" ] && [ ${new_interface_mtu} -gt 576 ]; then
echo "Setting MTU to ${new_interface_mtu}"
ip link set "${interface}" mtu "${new_interface_mtu}"
fi
;;
BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT|STATIC)
# Export all information about the newly received lease
# to file
export_lease
# Create system configuration files
make_resolvconf
;;
EXPIRE|FAIL|IPV4LL|NAK|NOCARRIER|RELEASE|STOP)
rm -f "${LEASE_FILE}"
;;
esac
exit 0

View File

@@ -35,17 +35,18 @@ install() {
inst_multiple tar gzip lzma xz
# Networking
inst_multiple dhcpcd ethtool hostname ip ping wget
inst_multiple dhcpcd ethtool hostname ip ping sort wget
inst /usr/bin/start-networking.sh
inst /var/ipfire/dhcpc/dhcpcd-run-hooks
inst /var/ipfire/dhcpc/dhcpcd.conf
for file in /var/ipfire/dhcpc/dhcpcd-hooks/*; do
inst "${file}"
done
inst /var/ipfire/dhcpc/dhcpcd-run-hooks
inst "$moddir/70-dhcpcd.exe" "/var/ipfire/dhcpc/dhcpcd-hooks/70-dhcpcd.exe"
inst /etc/host.conf /etc/hosts /etc/protocols
inst /etc/nsswitch.conf /etc/resolv.conf
inst_libdir_file "libnss_dns.so.*"
# Misc. tools
inst_multiple cut grep eject killall md5sum touch
inst_multiple cut grep eject id killall md5sum touch
inst_multiple -o fdisk cfdisk df ps top
# Hardware IDs

View File

@@ -26,12 +26,14 @@
#include <blkid/blkid.h>
#include <fcntl.h>
#include <libudev.h>
#include <linux/loop.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/swap.h>
#include <sys/sysinfo.h>
#include <unistd.h>
@@ -82,11 +84,56 @@ static int strstartswith(const char* a, const char* b) {
return (strncmp(a, b, strlen(b)) == 0);
}
static char loop_device[STRING_SIZE];
static int setup_loop_device(const char* source, const char* device) {
int file_fd = open(source, O_RDWR);
if (file_fd < 0)
goto ERROR;
int device_fd = -1;
if ((device_fd = open(device, O_RDWR)) < 0)
goto ERROR;
if (ioctl(device_fd, LOOP_SET_FD, file_fd) < 0)
goto ERROR;
close(file_fd);
close(device_fd);
return 0;
ERROR:
if (file_fd >= 0)
close(file_fd);
if (device_fd >= 0) {
ioctl(device_fd, LOOP_CLR_FD, 0);
close(device_fd);
}
return -1;
}
int hw_mount(const char* source, const char* target, const char* fs, int flags) {
const char* loop_device = "/dev/loop0";
// Create target if it does not exist
if (access(target, X_OK) != 0)
mkdir(target, S_IRWXU|S_IRWXG|S_IRWXO);
struct stat st;
stat(source, &st);
if (S_ISREG(st.st_mode)) {
int r = setup_loop_device(source, loop_device);
if (r == 0) {
source = loop_device;
} else {
return -1;
}
}
return mount(source, target, fs, flags, NULL);
}

View File

@@ -229,13 +229,18 @@ static struct config {
int unattended;
int serial_console;
int require_networking;
int perform_download;
char download_url[STRING_SIZE];
} config = {
.unattended = 0,
.serial_console = 0,
.require_networking = 0,
.perform_download = 0,
.download_url = DOWNLOAD_URL,
};
static void parse_command_line(struct config* c) {
char buffer[STRING_SIZE];
char cmdline[STRING_SIZE];
FILE* f = fopen("/proc/cmdline", "r");
@@ -244,9 +249,13 @@ static void parse_command_line(struct config* c) {
int r = fread(&cmdline, 1, sizeof(cmdline) - 1, f);
if (r > 0) {
char* token = strtok(&cmdline, " ");
char* token = strtok(cmdline, " ");
while (token) {
strncpy(buffer, token, sizeof(buffer));
char* val = &buffer;
char* key = strsep(&val, "=");
// serial console
if (strcmp(token, "console=ttyS0") == 0)
c->serial_console = 1;
@@ -259,6 +268,15 @@ static void parse_command_line(struct config* c) {
else if (strcmp(token, "installer.unattended") == 0)
c->unattended = 1;
// download url
else if (strcmp(key, "installer.download-url") == 0) {
strncpy(&c->download_url, val, sizeof(c->download_url));
c->perform_download = 1;
// Require networking for the download
c->require_networking = 1;
}
token = strtok(NULL, " ");
}
}
@@ -364,16 +382,21 @@ int main(int argc, char *argv[]) {
/* Search for a source drive that holds the right
* version of the image we are going to install. */
sourcedrive = hw_find_source_medium(hw);
fprintf(flog, "Source drive: %s\n", sourcedrive);
if (!config.perform_download) {
sourcedrive = hw_find_source_medium(hw);
fprintf(flog, "Source drive: %s\n", sourcedrive);
}
/* If we could not find a source drive, we will try
* downloading the install image */
if (!sourcedrive) {
if (!sourcedrive)
config.perform_download = 1;
if (config.perform_download) {
if (!config.unattended) {
// Show the right message to the user
char reason[STRING_SIZE];
if (config.require_networking) {
if (config.perform_download) {
snprintf(reason, sizeof(reason),
_("The installer will now try downloading the installation image."));
} else {
@@ -392,6 +415,7 @@ int main(int argc, char *argv[]) {
goto EXIT;
}
// Make sure that we enable networking before download
config.require_networking = 1;
}
@@ -420,20 +444,31 @@ int main(int argc, char *argv[]) {
}
// Download the image if required
while (!sourcedrive) {
snprintf(commandstring, sizeof(commandstring), "/usr/bin/downloadsource.sh %s", SOURCE_TEMPFILE);
runcommandwithstatus(commandstring, title, _("Downloading installation image..."), logfile);
if (config.perform_download) {
fprintf(flog, "Download URL: %s\n", config.download_url);
snprintf(commandstring, sizeof(commandstring), "/usr/bin/downloadsource.sh %s %s",
SOURCE_TEMPFILE, config.download_url);
FILE* f = fopen(SOURCE_TEMPFILE, "r");
if (f) {
sourcedrive = SOURCE_TEMPFILE;
fclose(f);
} else {
rc = newtWinOkCancel(title, _("The installation image could not be downloaded."),
60, 8, _("Retry"), _("Cancel"));
while (!sourcedrive) {
rc = runcommandwithstatus(commandstring, title, _("Downloading installation image..."), logfile);
if (rc)
goto EXIT;
FILE* f = fopen(SOURCE_TEMPFILE, "r");
if (f) {
sourcedrive = SOURCE_TEMPFILE;
fclose(f);
} else {
char reason[STRING_SIZE] = "-";
if (rc == 2)
snprintf(reason, sizeof(STRING_SIZE), _("MD5 checksum mismatch"));
snprintf(message, sizeof(message),
_("The installation image could not be downloaded.\n Reason: %s\n\n%s"),
reason, config.download_url);
rc = newtWinOkCancel(title, message, 75, 12, _("Retry"), _("Cancel"));
if (rc)
goto EXIT;
}
}
}
}
@@ -442,9 +477,10 @@ int main(int argc, char *argv[]) {
int r = hw_mount(sourcedrive, SOURCE_MOUNT_PATH, "iso9660", MS_RDONLY);
if (r) {
fprintf(flog, "Could not mount %s to %s\n", sourcedrive, SOURCE_MOUNT_PATH);
fprintf(flog, strerror(errno));
exit(1);
snprintf(message, sizeof(message), _("Could not mount %s to %s:\n %s\n"),
sourcedrive, SOURCE_MOUNT_PATH, strerror(errno));
errorbox(message);
goto EXIT;
}
if (!config.unattended) {

View File

@@ -56,6 +56,10 @@ function main() {
fi
echo "Successfully started on ${interface}"
# Wait until everything is settled
sleep 15
return 0
done