mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-11 11:35:54 +02:00
installer: Rework downloading ISO and allow using a custom URL
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -56,6 +56,10 @@ function main() {
|
||||
fi
|
||||
|
||||
echo "Successfully started on ${interface}"
|
||||
|
||||
# Wait until everything is settled
|
||||
sleep 15
|
||||
|
||||
return 0
|
||||
done
|
||||
|
||||
|
||||
Reference in New Issue
Block a user