Add tix-upgrade(8).
This commit is contained in:
parent
83ac75a083
commit
d3d339b616
19 changed files with 1004 additions and 13 deletions
6
Makefile
6
Makefile
|
@ -231,6 +231,8 @@ sysroot-system: sysroot-fsh sysroot-base-headers
|
||||||
echo /etc/sortix-release >> "$(SYSROOT)/tix/manifest/system"
|
echo /etc/sortix-release >> "$(SYSROOT)/tix/manifest/system"
|
||||||
ln -sf sortix-release "$(SYSROOT)/etc/os-release"
|
ln -sf sortix-release "$(SYSROOT)/etc/os-release"
|
||||||
echo /etc/os-release >> "$(SYSROOT)/tix/manifest/system"
|
echo /etc/os-release >> "$(SYSROOT)/tix/manifest/system"
|
||||||
|
find etc | sed -e 's,^,/,' >> "$(SYSROOT)/tix/manifest/system"
|
||||||
|
cp -RT etc "$(SYSROOT)/etc"
|
||||||
find share | sed -e 's,^,/,' >> "$(SYSROOT)/tix/manifest/system"
|
find share | sed -e 's,^,/,' >> "$(SYSROOT)/tix/manifest/system"
|
||||||
cp -RT share "$(SYSROOT)/share"
|
cp -RT share "$(SYSROOT)/share"
|
||||||
export SYSROOT="$(SYSROOT)" && \
|
export SYSROOT="$(SYSROOT)" && \
|
||||||
|
@ -269,6 +271,7 @@ else ifneq ($(SORTIX_INCLUDE_SOURCE),no)
|
||||||
cp Makefile -t "$(SYSROOT)/src"
|
cp Makefile -t "$(SYSROOT)/src"
|
||||||
cp README -t "$(SYSROOT)/src"
|
cp README -t "$(SYSROOT)/src"
|
||||||
cp -RT build-aux "$(SYSROOT)/src/build-aux"
|
cp -RT build-aux "$(SYSROOT)/src/build-aux"
|
||||||
|
cp -RT etc "$(SYSROOT)/src/etc"
|
||||||
cp -RT share "$(SYSROOT)/src/share"
|
cp -RT share "$(SYSROOT)/src/share"
|
||||||
(for D in $(MODULES); do (cp -R $$D -t "$(SYSROOT)/src" && $(MAKE) -C "$(SYSROOT)/src/$$D" clean) || exit $$?; done)
|
(for D in $(MODULES); do (cp -R $$D -t "$(SYSROOT)/src" && $(MAKE) -C "$(SYSROOT)/src/$$D" clean) || exit $$?; done)
|
||||||
endif
|
endif
|
||||||
|
@ -452,6 +455,9 @@ $(LIVE_INITRD): sysroot
|
||||||
echo "include /etc/default/passwd.d/*" >> $(LIVE_INITRD).d/etc/passwd
|
echo "include /etc/default/passwd.d/*" >> $(LIVE_INITRD).d/etc/passwd
|
||||||
echo "root::0:root" > $(LIVE_INITRD).d/etc/group
|
echo "root::0:root" > $(LIVE_INITRD).d/etc/group
|
||||||
echo "include /etc/default/group.d/*" >> $(LIVE_INITRD).d/etc/group
|
echo "include /etc/default/group.d/*" >> $(LIVE_INITRD).d/etc/group
|
||||||
|
(echo 'channel = $(CHANNEL)' && \
|
||||||
|
echo 'release_key = $(RELEASE_KEY)' && \
|
||||||
|
echo 'release_sig_url = $(RELEASE_SIG_URL)') > $(LIVE_INITRD).d/etc/upgrade.conf
|
||||||
mkdir -p $(LIVE_INITRD).d/root -m 700
|
mkdir -p $(LIVE_INITRD).d/root -m 700
|
||||||
cp -RT "$(SYSROOT)/etc/skel" $(LIVE_INITRD).d/root
|
cp -RT "$(SYSROOT)/etc/skel" $(LIVE_INITRD).d/root
|
||||||
(echo "You can view the documentation for new users by typing:" && \
|
(echo "You can view the documentation for new users by typing:" && \
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
set_minimal="cut dash e2fsprogs grep grub mdocml sed xargs"
|
set_minimal="cut dash e2fsprogs grep grub libssl mdocml sed signify tar wget xargs xz"
|
||||||
set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip irssi libcurl libcurses libssl libstdc++ m4 make nano ntpd patch perl pkg-config python ssh tar texinfo vim wget xz xorriso"
|
set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip irssi libcurl libcurses libstdc++ m4 make nano ntpd patch perl pkg-config python ssh texinfo vim xorriso"
|
||||||
sets="basic minimal"
|
sets="basic minimal"
|
||||||
|
|
|
@ -1,2 +1,6 @@
|
||||||
VERSION=1.1dev
|
VERSION=1.1dev
|
||||||
|
CHANNEL?=nightly
|
||||||
RELEASE?=$(VERSION)
|
RELEASE?=$(VERSION)
|
||||||
|
RELEASE_MASTER?=https://sortix.org/release
|
||||||
|
RELEASE_KEY=/etc/signify/sortix-$(VERSION).pub
|
||||||
|
RELEASE_SIG_URL?=$(RELEASE_MASTER)/$(CHANNEL)/$(HOST_MACHINE).sh.sig
|
||||||
|
|
2
etc/signify/sortix-1.1.pub
Normal file
2
etc/signify/sortix-1.1.pub
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
untrusted comment: signify public key
|
||||||
|
RWQiTQbFzyZJVobf/pn53Jp3njhRB9DgwkMaNakCpDE9RaTABMjlbz9W
|
2
etc/signify/sortix-1.1dev.pub
Normal file
2
etc/signify/sortix-1.1dev.pub
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
untrusted comment: signify public key
|
||||||
|
RWQnkSm9lj1YIZYpt1Y3mHYzFsaky82gQF6CrW4lme9OoEYzSIl2ZsIC
|
2
etc/signify/sortix-1.2.pub
Normal file
2
etc/signify/sortix-1.2.pub
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
untrusted comment: signify public key
|
||||||
|
RWTGrBXmGvl2zUpCa47ui5EyPsnitKLjsCZ2YZphNY8F3b33t6QWYDs1
|
2
etc/signify/sortix-1.2dev.pub
Normal file
2
etc/signify/sortix-1.2dev.pub
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
untrusted comment: signify public key
|
||||||
|
RWRTbLQ+3+a9I5yche2BEVP03TRtumGO4Vgq1AQ/5bRj8JAJ1R0+vpxE
|
|
@ -22,6 +22,10 @@ as part of
|
||||||
.Xr installation 7
|
.Xr installation 7
|
||||||
to match what was installed.
|
to match what was installed.
|
||||||
.Pp
|
.Pp
|
||||||
|
The file also controls the actions of
|
||||||
|
.Xr tix 8
|
||||||
|
when upgrading releases and installing ports.
|
||||||
|
.Pp
|
||||||
Developers may wish to customize what happens to
|
Developers may wish to customize what happens to
|
||||||
.Pa /src
|
.Pa /src
|
||||||
on a system upgrade.
|
on a system upgrade.
|
||||||
|
@ -44,7 +48,32 @@ Lines are supposed to contain assignments to variables.
|
||||||
An assignment is the name of the variable, whitespace, an equal character,
|
An assignment is the name of the variable, whitespace, an equal character,
|
||||||
whitespace, the value, whitespace, and then the end of the line.
|
whitespace, the value, whitespace, and then the end of the line.
|
||||||
.Bl -tag -width "12345678"
|
.Bl -tag -width "12345678"
|
||||||
.It Sy grub Ns "=" Ns Oo Sy no "|" yes Oc (default Sy no ) .
|
.It Sy channel Ns "=" Ns Ar channel
|
||||||
|
If the current release has an upgrade path named
|
||||||
|
.Ar channel
|
||||||
|
to a new release,
|
||||||
|
then system upgrades will upgrade to that new release.
|
||||||
|
If no such release path exists or if this variable is not set, upgrades will
|
||||||
|
continue to upgrade to the current release series.
|
||||||
|
Depending on the current release, the offically supported values are
|
||||||
|
.Sy stable
|
||||||
|
for stable releases and
|
||||||
|
.Sy nightly
|
||||||
|
for development releases.
|
||||||
|
Downgrading releases is not supported. For instance, if the current system is
|
||||||
|
a development release, specifying
|
||||||
|
.Sy stable
|
||||||
|
will not downgrade the system to the previous stable release, as no such upgrade
|
||||||
|
path exists.
|
||||||
|
Instead upgrades will upgrade to the next stable release when it becomes
|
||||||
|
available.
|
||||||
|
.It Sy force_mirror Ns "=" Ns Oo Sy no "|" yes Oc (default Sy no )
|
||||||
|
Use the preferred mirror set with
|
||||||
|
.Sy mirror
|
||||||
|
even if the file specified by
|
||||||
|
.Sy release_sig_url
|
||||||
|
does not list it.
|
||||||
|
.It Sy grub Ns "=" Ns Oo Sy no "|" yes Oc (default Sy no )
|
||||||
States GRUB is used as the bootloader.
|
States GRUB is used as the bootloader.
|
||||||
If either the
|
If either the
|
||||||
.Sy system
|
.Sy system
|
||||||
|
@ -56,7 +85,18 @@ then the bootloader is reinstalled
|
||||||
.Xr ( grub-install 8 )
|
.Xr ( grub-install 8 )
|
||||||
and updated
|
and updated
|
||||||
.Xr ( update-grub 8 ) .
|
.Xr ( update-grub 8 ) .
|
||||||
.It Sy newsrc Ns "=" Ns Oo Sy no "|" yes Oc (default Sy no ) .
|
.It Sy mirror Ns "=" Ns Ar mirror
|
||||||
|
Download releases and ports from this preferred
|
||||||
|
.Ar mirror ,
|
||||||
|
a URL to the top level directory of a mirror.
|
||||||
|
The mirror is only used if the file specified by
|
||||||
|
.Sy release_sig_url
|
||||||
|
lists this mirror, unless
|
||||||
|
.Sy force_mirror
|
||||||
|
is set to
|
||||||
|
.Sy yes .
|
||||||
|
If no mirror is set, a default mirror is used.
|
||||||
|
.It Sy newsrc Ns "=" Ns Oo Sy no "|" yes Oc (default Sy no )
|
||||||
Place the new source code in
|
Place the new source code in
|
||||||
.Pa /newsrc
|
.Pa /newsrc
|
||||||
and move any existing
|
and move any existing
|
||||||
|
@ -68,17 +108,39 @@ This preserves the current
|
||||||
directory.
|
directory.
|
||||||
This takes precedence over and disables the behavior described under
|
This takes precedence over and disables the behavior described under
|
||||||
.Sy src .
|
.Sy src .
|
||||||
.It Sy ports Ns "=" Ns Oo Sy no "|" yes Oc (default Sy yes ) .
|
.It Sy ports Ns "=" Ns Oo Sy no "|" yes Oc (default Sy yes )
|
||||||
Install the new ports.
|
Install the new ports.
|
||||||
Ports that don't exist anymore will be removed.
|
Ports that don't exist anymore will be removed.
|
||||||
.It Sy src Ns "=" Ns Oo Sy no "|" yes Oc (default Sy no ) .
|
.It Sy release_key Ns "=" Ns Ar release_key
|
||||||
|
Verify the file specified by
|
||||||
|
.Sy release_sig_url
|
||||||
|
with the
|
||||||
|
.Xr signify 1
|
||||||
|
public key file at the path
|
||||||
|
.Ar release_key .
|
||||||
|
This variable is updated during system upgrades and there is no need to change
|
||||||
|
this variable manually.
|
||||||
|
.It Sy release_sig_url Ns "=" Ns Ar release_sig_url
|
||||||
|
Download the meta-information about the current release from the URL
|
||||||
|
.Ar release_sig_url .
|
||||||
|
This file is verified with the
|
||||||
|
.Xr signify 1
|
||||||
|
public key in the
|
||||||
|
.Sy release_key
|
||||||
|
variable.
|
||||||
|
The file describes the current release, provides checksums of all the published
|
||||||
|
files, lists all the supported mirrors, provides instructions on how to upgrade
|
||||||
|
to this release, and lists all the supported upgrade paths to new releases.
|
||||||
|
This variable is updated during system upgrades and there is no need to change
|
||||||
|
this variable manually.
|
||||||
|
.It Sy src Ns "=" Ns Oo Sy no "|" yes Oc (default Sy no )
|
||||||
Place the new source code in
|
Place the new source code in
|
||||||
.Pa /src
|
.Pa /src
|
||||||
and move any existing
|
and move any existing
|
||||||
.Pa /src
|
.Pa /src
|
||||||
into
|
into
|
||||||
.Pa /oldsrc .
|
.Pa /oldsrc .
|
||||||
.It Sy system Ns "=" Ns Oo Sy no "|" yes Oc (default Sy yes ) .
|
.It Sy system Ns "=" Ns Oo Sy no "|" yes Oc (default Sy yes )
|
||||||
Install the new system.
|
Install the new system.
|
||||||
The upgrade hooks are run if needed as described in
|
The upgrade hooks are run if needed as described in
|
||||||
.Xr following-development 7 .
|
.Xr following-development 7 .
|
||||||
|
@ -95,6 +157,18 @@ then regenerate
|
||||||
The defaults will be used if
|
The defaults will be used if
|
||||||
.Pa /etc/upgrade.conf
|
.Pa /etc/upgrade.conf
|
||||||
is missing.
|
is missing.
|
||||||
|
If
|
||||||
|
.Sy release_key
|
||||||
|
or
|
||||||
|
.Sy release_sig_url
|
||||||
|
are absent,
|
||||||
|
.Xr tix 8
|
||||||
|
will not be able to upgrade the current system nor install ports.
|
||||||
|
If
|
||||||
|
.Sy channel
|
||||||
|
is absent,
|
||||||
|
.Xr tix 8
|
||||||
|
will not upgrade to new releases.
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width "/etc/upgrade.conf" -compact
|
.Bl -tag -width "/etc/upgrade.conf" -compact
|
||||||
.It Pa /etc/upgrade.conf
|
.It Pa /etc/upgrade.conf
|
||||||
|
@ -102,13 +176,14 @@ Upgrade configuration.
|
||||||
.El
|
.El
|
||||||
.Sh EXAMPLES
|
.Sh EXAMPLES
|
||||||
.Bd -literal
|
.Bd -literal
|
||||||
system = yes
|
grub = yes
|
||||||
ports = yes
|
ports = yes
|
||||||
src = no
|
src = no
|
||||||
grub = yes
|
system = yes
|
||||||
.Ed
|
.Ed
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr autoinstall.conf 5 ,
|
.Xr autoinstall.conf 5 ,
|
||||||
.Xr autoupgrade.conf 5 ,
|
.Xr autoupgrade.conf 5 ,
|
||||||
.Xr upgrade 7 ,
|
.Xr upgrade 7 ,
|
||||||
.Xr sysupgrade 8
|
.Xr sysupgrade 8 ,
|
||||||
|
.Xr tix 8
|
||||||
|
|
|
@ -37,6 +37,10 @@ void conf_init(struct conf* conf)
|
||||||
|
|
||||||
void conf_free(struct conf* conf)
|
void conf_free(struct conf* conf)
|
||||||
{
|
{
|
||||||
|
free(conf->channel);
|
||||||
|
free(conf->mirror);
|
||||||
|
free(conf->release_key);
|
||||||
|
free(conf->release_sig_url);
|
||||||
conf_init(conf);
|
conf_init(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +64,43 @@ static bool conf_assign(struct conf* conf,
|
||||||
const char* path,
|
const char* path,
|
||||||
off_t line_number)
|
off_t line_number)
|
||||||
{
|
{
|
||||||
if ( !strcmp(name, "grub") )
|
char* new_value;
|
||||||
|
if ( !strcmp(name, "channel") )
|
||||||
|
{
|
||||||
|
if ( !(new_value = strdup(value)) )
|
||||||
|
return false;
|
||||||
|
free(conf->channel);
|
||||||
|
conf->channel = new_value;
|
||||||
|
}
|
||||||
|
else if ( !strcmp(name, "force_mirror") )
|
||||||
|
conf->force_mirror = conf_boolean(name, value, path, line_number);
|
||||||
|
else if ( !strcmp(name, "grub") )
|
||||||
conf->grub = conf_boolean(name, value, path, line_number);
|
conf->grub = conf_boolean(name, value, path, line_number);
|
||||||
|
else if ( !strcmp(name, "mirror") )
|
||||||
|
{
|
||||||
|
if ( !(new_value = strdup(value)) )
|
||||||
|
return false;
|
||||||
|
free(conf->mirror);
|
||||||
|
conf->mirror = new_value;
|
||||||
|
}
|
||||||
else if ( !strcmp(name, "newsrc") )
|
else if ( !strcmp(name, "newsrc") )
|
||||||
conf->newsrc = conf_boolean(name, value, path, line_number);
|
conf->newsrc = conf_boolean(name, value, path, line_number);
|
||||||
else if ( !strcmp(name, "ports") )
|
else if ( !strcmp(name, "ports") )
|
||||||
conf->ports = conf_boolean(name, value, path, line_number);
|
conf->ports = conf_boolean(name, value, path, line_number);
|
||||||
|
else if ( !strcmp(name, "release_key") )
|
||||||
|
{
|
||||||
|
if ( !(new_value = strdup(value)) )
|
||||||
|
return false;
|
||||||
|
free(conf->release_key);
|
||||||
|
conf->release_key = new_value;
|
||||||
|
}
|
||||||
|
else if ( !strcmp(name, "release_sig_url") )
|
||||||
|
{
|
||||||
|
if ( !(new_value = strdup(value)) )
|
||||||
|
return false;
|
||||||
|
free(conf->release_sig_url);
|
||||||
|
conf->release_sig_url = new_value;
|
||||||
|
}
|
||||||
else if ( !strcmp(name, "src") )
|
else if ( !strcmp(name, "src") )
|
||||||
conf->src = conf_boolean(name, value, path, line_number);
|
conf->src = conf_boolean(name, value, path, line_number);
|
||||||
else if ( !strcmp(name, "system") )
|
else if ( !strcmp(name, "system") )
|
||||||
|
|
|
@ -22,9 +22,14 @@
|
||||||
|
|
||||||
struct conf
|
struct conf
|
||||||
{
|
{
|
||||||
|
char* channel;
|
||||||
|
bool force_mirror;
|
||||||
bool grub;
|
bool grub;
|
||||||
|
char* mirror;
|
||||||
bool newsrc;
|
bool newsrc;
|
||||||
bool ports;
|
bool ports;
|
||||||
|
char* release_key;
|
||||||
|
char* release_sig_url;
|
||||||
bool src;
|
bool src;
|
||||||
bool system;
|
bool system;
|
||||||
};
|
};
|
||||||
|
|
|
@ -485,6 +485,8 @@ void upgrade_prepare(const struct release* old_release,
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add upstream mirror to /etc/upgrade.conf.
|
||||||
}
|
}
|
||||||
|
|
||||||
void upgrade_finalize(const struct release* old_release,
|
void upgrade_finalize(const struct release* old_release,
|
||||||
|
|
|
@ -630,6 +630,21 @@ int main(void)
|
||||||
// TODO: You can leave this program by pressing ^C but it can leave your
|
// TODO: You can leave this program by pressing ^C but it can leave your
|
||||||
// system in an inconsistent state.
|
// system in an inconsistent state.
|
||||||
|
|
||||||
|
if ( conf.channel )
|
||||||
|
install_configurationf("upgrade.conf", "a", "channel = %s\n",
|
||||||
|
conf.channel);
|
||||||
|
if ( conf.force_mirror != false )
|
||||||
|
install_configurationf("upgrade.conf", "a", "force_mirror = %s\n",
|
||||||
|
conf.force_mirror ? "yes" : "no");
|
||||||
|
if ( conf.mirror )
|
||||||
|
install_configurationf("upgrade.conf", "a", "mirror = %s\n",
|
||||||
|
conf.mirror);
|
||||||
|
if ( conf.release_key )
|
||||||
|
install_configurationf("upgrade.conf", "a", "release_key = %s\n",
|
||||||
|
conf.release_key);
|
||||||
|
if ( conf.release_sig_url )
|
||||||
|
install_configurationf("upgrade.conf", "a", "release_sig_url = %s\n",
|
||||||
|
conf.release_sig_url);
|
||||||
install_configurationf("upgrade.conf", "a", "src = yes\n");
|
install_configurationf("upgrade.conf", "a", "src = yes\n");
|
||||||
|
|
||||||
bool kblayout_setable = 0 <= tcgetblob(0, "kblayout", NULL, 0) ||
|
bool kblayout_setable = 0 <= tcgetblob(0, "kblayout", NULL, 0) ||
|
||||||
|
|
|
@ -403,6 +403,10 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
if ( copy_files )
|
if ( copy_files )
|
||||||
{
|
{
|
||||||
|
// TODO: Update /etc/upgrade.conf with new release values.
|
||||||
|
// TODO: What about native upgrades using make sysmerge? Should those
|
||||||
|
// values be updated then? Should there be an option to control
|
||||||
|
// this behavior?
|
||||||
const char* sysmerge = target;
|
const char* sysmerge = target;
|
||||||
if ( wait )
|
if ( wait )
|
||||||
{
|
{
|
||||||
|
|
|
@ -904,6 +904,7 @@ int main(void)
|
||||||
}
|
}
|
||||||
if ( conf.system )
|
if ( conf.system )
|
||||||
upgrade_finalize(target_release, &new_release, "", ".");
|
upgrade_finalize(target_release, &new_release, "", ".");
|
||||||
|
// TODO: Update /etc/upgrade.conf with new release values.
|
||||||
if ( conf.system )
|
if ( conf.system )
|
||||||
{
|
{
|
||||||
printf(" - Creating initrd...\n");
|
printf(" - Creating initrd...\n");
|
||||||
|
|
|
@ -26,12 +26,15 @@ tix-vars \
|
||||||
|
|
||||||
PROGRAMS:=\
|
PROGRAMS:=\
|
||||||
$(BINARIES) \
|
$(BINARIES) \
|
||||||
|
tix-clean \
|
||||||
tix-eradicate-libtool-la \
|
tix-eradicate-libtool-la \
|
||||||
|
tix-fetch \
|
||||||
tix-iso-add \
|
tix-iso-add \
|
||||||
tix-iso-bootconfig \
|
tix-iso-bootconfig \
|
||||||
tix-iso-liveconfig \
|
tix-iso-liveconfig \
|
||||||
tix-port \
|
tix-port \
|
||||||
tix-repository \
|
tix-repository \
|
||||||
|
tix-upgrade \
|
||||||
|
|
||||||
MANPAGES8=\
|
MANPAGES8=\
|
||||||
tix-build.8 \
|
tix-build.8 \
|
||||||
|
|
68
tix/tix-clean
Executable file
68
tix/tix-clean
Executable file
|
@ -0,0 +1,68 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 2017 Jonas 'Sortie' Termansen.
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
#
|
||||||
|
# tix-clean
|
||||||
|
# Remove temporary tix files.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
collection=""
|
||||||
|
sysroot=""
|
||||||
|
|
||||||
|
dashdash=
|
||||||
|
previous_option=
|
||||||
|
for argument do
|
||||||
|
if test -n "$previous_option"; then
|
||||||
|
eval $previous_option=\$argument
|
||||||
|
previous_option=
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $argument in
|
||||||
|
*=?*) parameter=$(expr "X$argument" : '[^=]*=\(.*\)' || true) ;;
|
||||||
|
*=) parameter= ;;
|
||||||
|
*) parameter=yes ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case $dashdash$argument in
|
||||||
|
--) dashdash=yes ;;
|
||||||
|
-o) previous_option=output ;;
|
||||||
|
--collection=*) collection=$parameter ;;
|
||||||
|
--collection) previous_option=collection ;;
|
||||||
|
--sysroot=*) sysroot=$parameter ;;
|
||||||
|
--sysroot) previous_option=sysroot ;;
|
||||||
|
-*) echo "$0: unrecognized option $argument" >&2
|
||||||
|
exit 1 ;;
|
||||||
|
*)
|
||||||
|
if [ $operand = 1 ]; then
|
||||||
|
input="$argument"
|
||||||
|
operand=2
|
||||||
|
elif [ $operand = 2 ]; then
|
||||||
|
directory="$argument"
|
||||||
|
operand=3
|
||||||
|
else
|
||||||
|
echo "$0: unexpected extra operand $argument" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -n "$previous_option"; then
|
||||||
|
echo "$0: option '$argument' requires an argument" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf "$collection/var/cache/tix"
|
451
tix/tix-fetch
Executable file
451
tix/tix-fetch
Executable file
|
@ -0,0 +1,451 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 2017, 2021, 2023 Jonas 'Sortie' Termansen.
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
#
|
||||||
|
# tix-fetch
|
||||||
|
# Download operating system files.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
boot=false
|
||||||
|
collection=""
|
||||||
|
continue=""
|
||||||
|
execpatch=false
|
||||||
|
initrd=false
|
||||||
|
insecure_downgrade_to_http=false
|
||||||
|
insecure_no_check_certificate=false
|
||||||
|
input_release_file=
|
||||||
|
input_release_sig_file=
|
||||||
|
input_sha256sum=
|
||||||
|
normalize=false
|
||||||
|
output=""
|
||||||
|
outputdir=""
|
||||||
|
output_release_file= # TODO: A better term for this?
|
||||||
|
output_release_sig_file= # TODO: A better term for this?
|
||||||
|
output_sha256sum=
|
||||||
|
patch=false
|
||||||
|
package=false
|
||||||
|
release=false
|
||||||
|
repository_metadata=false
|
||||||
|
sha256=false
|
||||||
|
sha256sum=false
|
||||||
|
source=false
|
||||||
|
source_full=false
|
||||||
|
sysroot=""
|
||||||
|
toolchain=false
|
||||||
|
url=false
|
||||||
|
url_main=false
|
||||||
|
url_main_release=false
|
||||||
|
url_mirror=false
|
||||||
|
url_mirror_release=false
|
||||||
|
url_release_sig=false
|
||||||
|
url_sha256sum=false
|
||||||
|
upgrade=false
|
||||||
|
# TODO: Option to select this default:
|
||||||
|
# TODO: This hides errors. Fix wget so it has a quiet, but errors, mode.
|
||||||
|
wget_options="-q --show-progress"
|
||||||
|
|
||||||
|
# TODO: Ability to get source code easily for gcc/binutils/libstdc++.
|
||||||
|
|
||||||
|
dashdash=
|
||||||
|
previous_option=
|
||||||
|
for argument do
|
||||||
|
if test -n "$previous_option"; then
|
||||||
|
eval $previous_option=\$argument
|
||||||
|
previous_option=
|
||||||
|
shift
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $argument in
|
||||||
|
*=?*) parameter=$(expr "X$argument" : '[^=]*=\(.*\)' || true) ;;
|
||||||
|
*=) parameter= ;;
|
||||||
|
*) parameter=yes ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case $dashdash$argument in
|
||||||
|
--) dashdash=yes ;;
|
||||||
|
-c) continue="-c" ;;
|
||||||
|
# TODO: Support -ofoo
|
||||||
|
-o) previous_option=output ;;
|
||||||
|
-O) previous_option=outputdir ;;
|
||||||
|
-q) wget_options="-q" ;;
|
||||||
|
-v) wget_options="-v" ;;
|
||||||
|
--boot) boot=true ;;
|
||||||
|
--collection=*) collection=$parameter ;;
|
||||||
|
--collection) previous_option=collection ;;
|
||||||
|
--continue) continue="--continue" ;;
|
||||||
|
--download-non-verbose) wget_options="-nv" ;;
|
||||||
|
--download-non-verbose) wget_options="-v" ;;
|
||||||
|
--download-quiet) wget_options="-q" ;;
|
||||||
|
--download-verbose) wget_options="-v" ;;
|
||||||
|
--execpatch) execpatch=true ;;
|
||||||
|
--initrd) initrd=true ;;
|
||||||
|
--input-release-file=*) input_release_file=$parameter ;;
|
||||||
|
--insecure-downgrade-to-http) insecure_downgrade_to_http=true ;;
|
||||||
|
--insecure-no-check-certificate) insecure_no_check_certificate=true ;;
|
||||||
|
--input-release-file) previous_option=input_release_file ;;
|
||||||
|
--input-release-sig-file=*) input_release_sig_file=$parameter ;;
|
||||||
|
--input-release-sig-file) previous_option=input_release_sig_file ;;
|
||||||
|
--input-sha256sum=*) input_sha256sum=$parameter ;;
|
||||||
|
--input-sha256sum) previous_option=input_sha256sum ;;
|
||||||
|
--normalize) normalize=true ;;
|
||||||
|
--nv) wget_options="-nv" ;;
|
||||||
|
--outputdir=*) outputdir=$parameter ;;
|
||||||
|
--outputdir) previous_option=outputdir ;;
|
||||||
|
--output=*) output=$parameter ;;
|
||||||
|
--output) previous_option=output ;;
|
||||||
|
--output-release-file=*) output_release_file=$parameter ;;
|
||||||
|
--output-release-file) previous_option=output_release_file ;;
|
||||||
|
--output-release-sig-file=*) output_release_sig_file=$parameter ;;
|
||||||
|
--output-release-sig-file) previous_option=output_release_sig_file ;;
|
||||||
|
--output-sha256sum=*) output_sha256sum=$parameter ;;
|
||||||
|
--output-sha256sum) previous_option=output_sha256sum ;;
|
||||||
|
--output-upgrade-file=*) output_upgrade_file=$parameter ;;
|
||||||
|
--output-upgrade-file) previous_option=output_upgrade_file ;;
|
||||||
|
--package) package=true ;;
|
||||||
|
--patch) patch=true ;;
|
||||||
|
--repository-metadata) repository_metadata=true ;;
|
||||||
|
--sha256) sha256=true ;;
|
||||||
|
--sha256sum) sha256sum=true ;;
|
||||||
|
--source-full) source_full=true ;;
|
||||||
|
--source) source=true ;;
|
||||||
|
--sysroot) previous_option=sysroot ;;
|
||||||
|
--sysroot=*) sysroot=$parameter ;;
|
||||||
|
--toolchain) toolchain=true ;;
|
||||||
|
--upgrade) upgrade=true ;;
|
||||||
|
--url) url=true ;;
|
||||||
|
--url-main) url_main=true ;;
|
||||||
|
--url-mirror) url_mirror=true ;;
|
||||||
|
--url-main-release) url_main_release=true ;;
|
||||||
|
--url-mirror-release) url_mirror_release=true ;;
|
||||||
|
--url-release-sig) url_release_sig=true ;;
|
||||||
|
--url-sha256sum) url_sha256sum=true ;;
|
||||||
|
--wget-options) previous_option=wget_options ;;
|
||||||
|
--wget-options=*) wget_options=$parameter ;;
|
||||||
|
-*) echo "$0: unrecognized option $argument" >&2
|
||||||
|
exit 1 ;;
|
||||||
|
*) break ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -n "$previous_option"; then
|
||||||
|
echo "$0: option '$argument' requires an argument" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TODO: Mutually incompatible options.
|
||||||
|
|
||||||
|
conf() {
|
||||||
|
sed -E -e 's/([a-zA-Z0-9_]+) *? *= */\U\1=/' \
|
||||||
|
-e 's/=yes$/=true/' -e 's/no$/=false/' "$3" | \
|
||||||
|
tix-vars -d "$2" - "$4"
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpdir=$(mktemp -dt tix-fetch.XXXXXX)
|
||||||
|
trap 'rm -rf -- "$tmpdir"' EXIT HUP INT QUIT TERM
|
||||||
|
|
||||||
|
upgrade_conf="${collection%/}/etc/upgrade.conf"
|
||||||
|
CHANNEL=$(conf -d '' "$upgrade_conf" CHANNEL)
|
||||||
|
RELEASE_KEY=$(conf -d '' "$upgrade_conf" RELEASE_KEY)
|
||||||
|
RELEASE_SIG_URL=$(conf -d '' "$upgrade_conf" RELEASE_SIG_URL)
|
||||||
|
PREFERRED_MIRROR=$(conf -d '' "$upgrade_conf" PREFERRED_MIRROR)
|
||||||
|
FORCE_MIRROR=$(conf -d '' "$upgrade_conf" FORCE_MIRROR)
|
||||||
|
USER_AGENT="$(uname -s)/$(uname -r) ($(uname -m); $(uname -v))"
|
||||||
|
|
||||||
|
if $insecure_no_check_certificate; then
|
||||||
|
echo "$0: warning: insecurely not checking https certificates" >&2
|
||||||
|
wget_options="$wget_options --no-check-certificate"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $insecure_downgrade_to_http; then
|
||||||
|
echo "$0: warning: insecurely downloading without https" >&2
|
||||||
|
RELEASE_SIG_URL="$(echo "$RELEASE_SIG_URL" | sed -E 's,^https:,http:,')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $url_release_sig; then
|
||||||
|
printf "%s\n" "$RELEASE_SIG_URL"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# HACK: Provide more useful errors when wget is silent:
|
||||||
|
do_wget() {
|
||||||
|
(set +e
|
||||||
|
wget "$@"
|
||||||
|
status=$?
|
||||||
|
set -e
|
||||||
|
what=
|
||||||
|
case $status in
|
||||||
|
0) exit 0 ;;
|
||||||
|
1) what="Generic error" ;;
|
||||||
|
2) what="Parse error" ;;
|
||||||
|
3) what="File I/O error" ;;
|
||||||
|
4) what="Network I/O error" ;;
|
||||||
|
5) what="Transport Layer Security verification failure" ;;
|
||||||
|
6) what="Username/password failure" ;;
|
||||||
|
7) what="Protocol error" ;;
|
||||||
|
8) what="Error response" ;;
|
||||||
|
*) what="Exit code $status" ;;
|
||||||
|
esac
|
||||||
|
echo "$0: $what when running: wget $@" >&2
|
||||||
|
exit $status)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fetch signed release description.
|
||||||
|
download_release_sh() {
|
||||||
|
(cd "$tmpdir" &&
|
||||||
|
do_wget -U "$USER_AGENT" $wget_options -O release.sh.sig \
|
||||||
|
-- "$RELEASE_SIG_URL")
|
||||||
|
signify -Vq -p "$RELEASE_KEY" -em "$tmpdir/release.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
true > "$tmpdir/upgrade.sh"
|
||||||
|
|
||||||
|
if [ -z "$input_release_file" -a -z "$input_release_sig_file" ]; then
|
||||||
|
download_release_sh
|
||||||
|
# TODO: tix-vars's output is not quoted so it can be input again.
|
||||||
|
tix-vars "$tmpdir/release.sh" | \
|
||||||
|
grep -E '^UPGRADE_=' | \
|
||||||
|
cat > "$tmpdir/upgrade.sh"
|
||||||
|
UPGRADE_SIG_URL=$(tix-vars -d '' "$tmpdir/upgrade.sh" UPGRADE_SIG_URL)
|
||||||
|
if $upgrade && [ -n "$UPGRADE_SIG_URL" ]; then
|
||||||
|
RELEASE_SIG_URL="$UPGRADE_SIG_URL"
|
||||||
|
RELEASE_KEY=$(tix-vars "$tmpdir/upgrade.sh" UPGRADE_KEY)
|
||||||
|
download_release_sh
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$input_release_file" ]; then
|
||||||
|
cp -T -- "$input_release_file" "$tmpdir/release.sh"
|
||||||
|
elif [ -n "$input_release_sig_file" ]; then
|
||||||
|
signify -Vq -p "$RELEASE_KEY" -em "$tmpdir/release.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Store the signed release file if requested.
|
||||||
|
if [ -n "$output_release_sig_file" ]; then
|
||||||
|
cp -T -- "$tmpdir/release.sh.sig" "$output_release_sig_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Store the release file (without signature) if requested.
|
||||||
|
if [ -n "$output_release_file" ]; then
|
||||||
|
cp -T -- "$tmpdir/release.sh" "$output_release_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Store the upgrade file if requested.
|
||||||
|
if [ -n "$output_upgrade_file" ]; then
|
||||||
|
cp -T -- "$tmpdir/upgrade.sh" "$output_upgrade_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Load the release description.
|
||||||
|
# TODO: SECURITY: Protect against responding with older release.sh.
|
||||||
|
|
||||||
|
# TODO: DO NOT SUBMIT: Temporary compatibility.
|
||||||
|
MAIN=$(tix-vars -d '' "$tmpdir/release.sh" MAIN)
|
||||||
|
MASTER=$(tix-vars -d '' "$tmpdir/release.sh" MASTER)
|
||||||
|
if [ -z "$MAIN" ]; then
|
||||||
|
MAIN="$MASTER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
RELEASE=$(tix-vars "$tmpdir/release.sh" RELEASE)
|
||||||
|
MACHINE=$(tix-vars "$tmpdir/release.sh" MACHINE)
|
||||||
|
SHA256SUM_FILE=$(tix-vars -d sha256sum "$tmpdir/release.sh" SHA256SUM_FILE)
|
||||||
|
SHA256SUM_SHA256SUM=$(tix-vars "$tmpdir/release.sh" SHA256SUM_SHA256SUM)
|
||||||
|
MIRRORS=$(tix-vars -d '' "$tmpdir/release.sh" MIRRORS)
|
||||||
|
|
||||||
|
if $url_main; then
|
||||||
|
printf "%s\n" "$MAIN"
|
||||||
|
exit
|
||||||
|
elif $url_main_release; then
|
||||||
|
printf "%s\n" "$MAIN/$RELEASE"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Default to the main mirror but switch to the preferred mirror if the release
|
||||||
|
# description knows about the mirror and believes it to be trustworthy.
|
||||||
|
MIRROR="$MAIN"
|
||||||
|
for POTENTIAL_MIRROR in $MIRRORS; do
|
||||||
|
if [ "$POTENTIAL_MIRROR" = "$PREFERRED_MIRROR" ]; then
|
||||||
|
MIRROR="$PREFERRED_MIRROR"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ -n "$PREFERRED_MIRROR" ] && [ "$MIRROR" != "$PREFERRED_MIRROR" ]; then
|
||||||
|
if [ "$FORCE_MIRROR" = true ]; then
|
||||||
|
MIRROR="$PREFERRED_MIRROR"
|
||||||
|
else
|
||||||
|
echo "$0: warning: ignoring unsupported mirror $PREFERRED_MIRROR" >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TODO: Make sure the distant future http downgrade is supported.
|
||||||
|
if $insecure_downgrade_to_http; then
|
||||||
|
MIRROR="$(echo "$MIRROR" | sed -E 's,^https:,http:,')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $url_mirror; then
|
||||||
|
printf "%s\n" "$MIRROR"
|
||||||
|
exit
|
||||||
|
elif $url_mirror_release; then
|
||||||
|
printf "%s\n" "$MIRROR/$RELEASE"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
RELEASE_URL="$MIRROR/$RELEASE"
|
||||||
|
|
||||||
|
# Fetch sha256sum file and check its SHA256 hash with the release description.
|
||||||
|
if $url_sha256sum; then
|
||||||
|
printf "%s\n" "$RELEASE_URL/$SHA256SUM_FILE"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
if [ -z "$input_sha256sum" ]; then
|
||||||
|
# TODO: If the mirror doesn't work, try the main.
|
||||||
|
(cd "$tmpdir" &&
|
||||||
|
do_wget -U "$USER_AGENT" $wget_options -O sha256sum \
|
||||||
|
-- "$RELEASE_URL/$SHA256SUM_FILE")
|
||||||
|
else
|
||||||
|
cp -T -- "$input_sha256sum" "$tmpdir/sha256sum"
|
||||||
|
fi
|
||||||
|
# TODO: Check if upstream release description changed, if so, start over.
|
||||||
|
echo "$SHA256SUM_SHA256SUM $tmpdir/sha256sum" | sha256sum -cq
|
||||||
|
|
||||||
|
# Store the sha256sum file if requested.
|
||||||
|
if [ -n "$output_sha256sum" ]; then
|
||||||
|
cp -T -- "$tmpdir/sha256sum" "$output_sha256sum"
|
||||||
|
fi
|
||||||
|
|
||||||
|
escape_extended_regex() {
|
||||||
|
printf "%s\n" "$1" | sed -E -e 's/[[$()*?\+.^{|}]/\\\0/g'
|
||||||
|
}
|
||||||
|
|
||||||
|
request() {
|
||||||
|
REQUEST="$1"
|
||||||
|
REQUESTDIR="$2"
|
||||||
|
REQUESTFINAL="${3-$1}"
|
||||||
|
FULLREQUEST="$REQUESTDIR$REQUEST"
|
||||||
|
|
||||||
|
if $url; then
|
||||||
|
printf '%s\n' "$RELEASE_URL/$FULLREQUEST"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $sha256 || $sha256sum; then
|
||||||
|
set +e # Don't fail if grep exits 1 (no match).
|
||||||
|
# TODO: Should this be a checksum(1) feature to look up a hash?
|
||||||
|
grep -E "^[0-9a-fA-F]{64} $(escape_extended_regex "$FULLREQUEST")$" \
|
||||||
|
"$tmpdir/sha256sum" > "$tmpdir/match"
|
||||||
|
EXITCODE=$?
|
||||||
|
set -e
|
||||||
|
if [ 2 -le "$EXITCODE" ]; then (exit $EXITCODE); fi
|
||||||
|
if $sha256 && [ -s "$tmpdir/match" ]; then
|
||||||
|
grep -Eo '^[0-9a-fA-F]{64}' "$tmpdir/match"
|
||||||
|
fi
|
||||||
|
if $sha256sum && [ -s "$tmpdir/match" ]; then
|
||||||
|
cat "$tmpdir/match"
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Decide the final location the file will end up.
|
||||||
|
if [ -n "$output" ]; then
|
||||||
|
FINAL="$output"
|
||||||
|
OUTPUTDIR=$(dirname -- "$output")
|
||||||
|
elif [ -n "$outputdir" ]; then
|
||||||
|
FINAL="$outputdir/$REQUESTFINAL"
|
||||||
|
OUTPUTDIR="$outputdir"
|
||||||
|
else
|
||||||
|
FINAL="$REQUESTFINAL"
|
||||||
|
OUTPUTDIR=.
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If a resumable download, store the file directly to the destination path.
|
||||||
|
# Otherwise download to a temporary directory and move only to the final
|
||||||
|
# location if the cryptographic check is passed.
|
||||||
|
if [ -n "$continue" ]; then
|
||||||
|
DOWNLOADDIR="$OUTPUTDIR"
|
||||||
|
OUTPUT="$FINAL"
|
||||||
|
else
|
||||||
|
DOWNLOADDIR="$tmpdir/download"
|
||||||
|
OUTPUT="$DOWNLOADDIR/$REQUEST"
|
||||||
|
mkdir -p -- "$DOWNLOADDIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fetch the file.
|
||||||
|
# TODO: If the mirror doesn't work, try the main.
|
||||||
|
(cd "$DOWNLOADDIR" &&
|
||||||
|
mkdir -p -- "$(dirname -- "$REQUEST")" &&
|
||||||
|
do_wget -U "$USER_AGENT" $wget_options $continue -O "$REQUEST" \
|
||||||
|
-- "$RELEASE_URL/$FULLREQUEST")
|
||||||
|
|
||||||
|
# Verify the cryptographic integrity of the fetched file.
|
||||||
|
ABSOLUTE_OUTPUT=$(realpath -- "$OUTPUT")
|
||||||
|
mkdir -p -- "$tmpdir/check"
|
||||||
|
(cd "$tmpdir/check" &&
|
||||||
|
mkdir -p -- "$(dirname -- "$FULLREQUEST")"
|
||||||
|
ln -s -- "$ABSOLUTE_OUTPUT" "$FULLREQUEST"
|
||||||
|
if ! sha256sum -q -C "$tmpdir/sha256sum" -- "$FULLREQUEST"; then
|
||||||
|
# Don't leave behind a file that didn't pass a cryptographic check.
|
||||||
|
if [ -n "$continue" ]; then
|
||||||
|
# TODO: Check if upstream release description changed, if so, start over.
|
||||||
|
echo "error: Deleting corrupted output file: $OUTPUT" 2>&1
|
||||||
|
rm -f -- "$OUTPUT"
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi)
|
||||||
|
rm -rf -- "$tmpdir/check"
|
||||||
|
|
||||||
|
# Move the file to the final destination if not already.
|
||||||
|
if [ -z "$continue" ]; then
|
||||||
|
if [ -z "$output" ]; then
|
||||||
|
(cd "$OUTPUTDIR" && mkdir -p -- "$(dirname -- "$REQUESTFINAL")")
|
||||||
|
fi
|
||||||
|
cp -T -- "$OUTPUT" "$FINAL"
|
||||||
|
rm -rf -- "$tmpdir/download"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if $release; then
|
||||||
|
MIRRORS=$(tix-vars "$tmpdir/release.sh" BUILD_FILE)
|
||||||
|
request "$BUILD_FILE" "" "$(basename -- "$BUILD_FILE")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TODO: --source, --source-full
|
||||||
|
# TODO: --binutils, --gcc, --libstdc++
|
||||||
|
|
||||||
|
# Fetch each of the specified signed files from the mirror.
|
||||||
|
for REQUEST; do
|
||||||
|
if $package; then
|
||||||
|
REQUEST="$REQUEST.tix.tar.xz"
|
||||||
|
REQUESTDIR="repository/$MACHINE-sortix/"
|
||||||
|
elif $repository_metadata; then
|
||||||
|
REQUESTDIR="repository/$MACHINE-sortix/"
|
||||||
|
elif $boot; then
|
||||||
|
REQUEST="$REQUEST"
|
||||||
|
REQUESTDIR="$MACHINE/boot/"
|
||||||
|
elif $initrd; then
|
||||||
|
REQUEST="$REQUEST.tar.xz"
|
||||||
|
REQUESTDIR="$MACHINE/boot/"
|
||||||
|
elif $patch; then
|
||||||
|
REQUEST="$REQUEST.patch"
|
||||||
|
REQUESTDIR="patches/"
|
||||||
|
elif $normalize; then
|
||||||
|
REQUEST="$REQUEST.normalize"
|
||||||
|
REQUESTDIR="patches/"
|
||||||
|
elif $toolchain; then
|
||||||
|
REQUESTDIR="toolchain/"
|
||||||
|
else
|
||||||
|
REQUESTDIR=""
|
||||||
|
fi
|
||||||
|
request "$REQUEST" "$REQUESTDIR"
|
||||||
|
done
|
273
tix/tix-upgrade
Executable file
273
tix/tix-upgrade
Executable file
|
@ -0,0 +1,273 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 2017, 2021, 2023, 2024 Jonas 'Sortie' Termansen.
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
#
|
||||||
|
# tix-upgrade
|
||||||
|
# Upgrade operating system and ports.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cachedir=""
|
||||||
|
cancel=false
|
||||||
|
clean=false
|
||||||
|
collection=/
|
||||||
|
download_only=false
|
||||||
|
fetch_options=
|
||||||
|
sysroot=""
|
||||||
|
upgrade=--upgrade
|
||||||
|
upgrade_ports=false
|
||||||
|
upgrade_system=false
|
||||||
|
wait=""
|
||||||
|
|
||||||
|
dashdash=
|
||||||
|
previous_option=
|
||||||
|
for argument do
|
||||||
|
if test -n "$previous_option"; then
|
||||||
|
eval $previous_option=\$argument
|
||||||
|
previous_option=
|
||||||
|
shift
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $argument in
|
||||||
|
*=?*) parameter=$(expr "X$argument" : '[^=]*=\(.*\)' || true) ;;
|
||||||
|
*=) parameter= ;;
|
||||||
|
*) parameter=yes ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case $dashdash$argument in
|
||||||
|
--) dashdash=yes ;;
|
||||||
|
-w) wait=-w ;;
|
||||||
|
--cachedir=*) cachedir=$parameter ;;
|
||||||
|
--cachedir) previous_option=cachedir ;;
|
||||||
|
--cancel) cancel=true ;;
|
||||||
|
--clean) clean=true ;;
|
||||||
|
--collection=*) collection=$parameter ;;
|
||||||
|
--collection) previous_option=collection ;;
|
||||||
|
--download-only) download_only=true ;;
|
||||||
|
--fetch-options=*) fetch_options="$parameter" ;;
|
||||||
|
--fetch-options) previous_option=fetch_options ;;
|
||||||
|
--insecure-downgrade-to-http) fetch_options="$fetch_options $argument" ;;
|
||||||
|
--insecure-no-check-certificate) fetch_options="$fetch_options $argument" ;;
|
||||||
|
--no-upgrade) upgrade= ;;
|
||||||
|
--ports) upgrade_ports=true ;;
|
||||||
|
--system) upgrade_system=true ;;
|
||||||
|
--sysroot) previous_option=sysroot ;;
|
||||||
|
--sysroot=*) sysroot=$parameter ;;
|
||||||
|
--wait) wait=--wait ;;
|
||||||
|
-*) echo "$0: unrecognized option $argument" >&2
|
||||||
|
exit 1 ;;
|
||||||
|
*) break ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -n "$previous_option"; then
|
||||||
|
echo "$0: option '$argument' requires an argument" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ 0 -lt $# ]; then
|
||||||
|
echo "$0: Unexpected extra operand: $1" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
conf() {
|
||||||
|
sed -E -e 's/([a-zA-Z0-9_]+) *? *= */\U\1=/' \
|
||||||
|
-e 's/=yes$/=true/' -e 's/no$/=false/' "$3" | \
|
||||||
|
tix-vars -d "$2" - "$4"
|
||||||
|
}
|
||||||
|
|
||||||
|
escape_extended_regex_sed() {
|
||||||
|
printf "%s\n" "$1" | sed -E -e 's/[[$()*?\+.^{|}'"$2"']/\\\0/g'
|
||||||
|
}
|
||||||
|
|
||||||
|
collection=$(cd "$collection" && pwd)
|
||||||
|
|
||||||
|
if ! $upgrade_ports && ! $upgrade_system; then
|
||||||
|
upgrade_ports=true
|
||||||
|
upgrade_system=true
|
||||||
|
if [ -e "$collection/etc/upgrade.conf" ]; then
|
||||||
|
upgrade_ports=$(conf -d true "$collection/etc/upgrade.conf" PORTS)
|
||||||
|
upgrade_system=$(conf -d true "$collection/etc/upgrade.conf" SYSTEM)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If this isn't a system installation, only upgrade the ports.
|
||||||
|
if [ ! -e "$collection/tix/manifest/system" ]; then
|
||||||
|
upgrade_system=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$upgrade_system$upgrade_ports" in
|
||||||
|
truefalse) what_to_upgrade=--system;;
|
||||||
|
falsetrue) what_to_upgrade=--ports;;
|
||||||
|
*) what_to_upgrade=;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$cachedir" ]; then
|
||||||
|
cachedir="${collection%/}/var/cache/tix"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $cancel || $clean; then
|
||||||
|
echo "Removing cache directory: $cachedir"
|
||||||
|
rm -rf -- "$cachedir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $cancel; then
|
||||||
|
sysmerge -t "$collection" --cancel
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
mkdir -p -- "$cachedir"
|
||||||
|
mkdir -p -- "$cachedir/new"
|
||||||
|
|
||||||
|
# Fetch the latest official signed release.sh and its matching sha256sum file.
|
||||||
|
tix-fetch $fetch_options \
|
||||||
|
--collection="$collection" \
|
||||||
|
--output-release-file="$cachedir/new/release.sh" \
|
||||||
|
--output-sha256sum="$cachedir/new/sha256sum" \
|
||||||
|
--output-upgrade-file="$cachedir/new/upgrade.sh" \
|
||||||
|
$upgrade
|
||||||
|
|
||||||
|
# If release.sh or sha256sum changed, clean the cache directory of downloads
|
||||||
|
# that were currently in progress as they might not have the right checksums.
|
||||||
|
if [ ! -e "$cachedir/release.sh" ] ||
|
||||||
|
[ ! -e "$cachedir/sha256sum" ] ||
|
||||||
|
[ ! -e "$cachedir/upgrade.sh" ] ||
|
||||||
|
! (cd "$cachedir/new" && sha256sum release.sh sha256sum upgrade.sh) |
|
||||||
|
(cd "$cachedir" && sha256sum -cs); then
|
||||||
|
rm -rf -- "$cachedir/boot"
|
||||||
|
rm -rf -- "$cachedir/repository"
|
||||||
|
rm -rf -- "$cachedir/sysroot"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Store the new release.sh and sha256sum files so we can resume the download
|
||||||
|
# if cancelled and these files still match.
|
||||||
|
mv -- "$cachedir/new/release.sh" "$cachedir/release.sh"
|
||||||
|
mv -- "$cachedir/new/sha256sum" "$cachedir/sha256sum"
|
||||||
|
mv -- "$cachedir/new/upgrade.sh" "$cachedir/upgrade.sh"
|
||||||
|
rm -rf -- "$cachedir/new"
|
||||||
|
|
||||||
|
# Check if we're upgrading to a new release.
|
||||||
|
UPGRADE_SIG_URL=$(tix-vars -d '' "$cachedir/upgrade.sh" UPGRADE_SIG_URL)
|
||||||
|
if [ -n "$UPGRADE_SIG_URL" ]; then
|
||||||
|
UPGRADE_CHANNEL=$(tix-vars "$cachedir/upgrade.sh" UPGRADE_CHANNEL)
|
||||||
|
UPGRADE_KEY=$(tix-vars "$cachedir/upgrade.sh" UPGRADE_KEY)
|
||||||
|
UPGRADE_NAME=$(tix-vars "$cachedir/upgrade.sh" UPGRADE_NAME)
|
||||||
|
if [ -n "$upgrade" ]; then
|
||||||
|
echo "Upgrading to $UPGRADE_NAME."
|
||||||
|
else
|
||||||
|
echo "Ignoring available upgrade to $UPGRADE_NAME."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Decide what binary packages to upgrade.
|
||||||
|
installed_packages=$(LC_ALL=C ls -- "$collection/tix/tixinfo")
|
||||||
|
if $upgrade_system && $upgrade_ports; then
|
||||||
|
upgrade_packages="$installed_packages"
|
||||||
|
else
|
||||||
|
upgrade_packages=
|
||||||
|
for package in $installed_packages; do
|
||||||
|
is_system=$(tix-vars -d false "$collection/tix/tixinfo/$package" SYSTEM)
|
||||||
|
if ($upgrade_system && [ "$is_system" = true ]) ||
|
||||||
|
($upgrade_ports && [ "$is_system" = false ]); then
|
||||||
|
upgrade_packages="$upgrade_packages $package"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TODO: Tracking sets like minimal/basic/full with new mandatory or recommended ports.
|
||||||
|
|
||||||
|
mkdir -p -- "$cachedir/repository"
|
||||||
|
|
||||||
|
tix-fetch $fetch_options \
|
||||||
|
--collection="$collection" \
|
||||||
|
--input-release-file="$cachedir/release.sh" \
|
||||||
|
--input-sha256sum="$cachedir/sha256sum" \
|
||||||
|
--repository-metadata -O "$cachedir/repository" renames.list
|
||||||
|
|
||||||
|
# Follow RENAMES recursively to handle renames, splits, and deletions.
|
||||||
|
rename() {
|
||||||
|
if grep -Eq "^$(escape_extended_regex_sed "$1"):" \
|
||||||
|
"$cachedir/repository/renames.list"; then
|
||||||
|
for new in $(grep -E "^$(escape_extended_regex_sed "$1"):" \
|
||||||
|
"$cachedir/repository/renames.list" |
|
||||||
|
grep -Eo '[^:]*$'); do
|
||||||
|
rename "$new"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "$1" | grep -Eo '^[^@]*'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine the final package list after the renames.
|
||||||
|
packages=""
|
||||||
|
for package in $(LC_ALL=C ls -- "$collection/tix/tixinfo"); do
|
||||||
|
edition=$(tix-vars -d 1 "$collection/tix/tixinfo/$package" EDITION)
|
||||||
|
packages="$packages $(rename "$package@$edition")"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Sort and deduplicate the package list and check for existence.
|
||||||
|
packages=$(for package in $packages; do
|
||||||
|
# The package exists upstream if it has a hash.
|
||||||
|
if [ -n "$(tix-fetch $fetch_options \
|
||||||
|
--collection="$collection" \
|
||||||
|
--input-release-file="$cachedir/release.sh" \
|
||||||
|
--input-sha256sum="$cachedir/sha256sum" \
|
||||||
|
--sha256 --package -- $package)" ]; then
|
||||||
|
echo $package
|
||||||
|
fi
|
||||||
|
done | LC_ALL=C sort -u)
|
||||||
|
|
||||||
|
# Fetch each binary package from the mirror.
|
||||||
|
for package in $packages; do
|
||||||
|
tix-fetch $fetch_options \
|
||||||
|
--collection="$collection" \
|
||||||
|
--input-release-file="$cachedir/release.sh" \
|
||||||
|
--input-sha256sum="$cachedir/sha256sum" \
|
||||||
|
-c --package -O "$cachedir/repository" -- $package
|
||||||
|
done
|
||||||
|
|
||||||
|
# Stop if only downloading.
|
||||||
|
if $download_only; then
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf -- "$cachedir/sysroot"
|
||||||
|
mkdir -p -- "$cachedir/sysroot"
|
||||||
|
|
||||||
|
# Forward the upgrade metadata.
|
||||||
|
UPGRADE_SIG_URL=$(tix-vars -d '' "$cachedir/upgrade.sh" UPGRADE_SIG_URL)
|
||||||
|
if [ -n $upgrade ] && [ -n "$UPGRADE_SIG_URL" ]; then
|
||||||
|
mkdir -p -- "$cachedir/etc"
|
||||||
|
# TODO: More flexible and simple model.
|
||||||
|
cat > "$cachedir/etc/upgrade.conf" << EOF
|
||||||
|
channel = $UPGRADE_CHANNEL
|
||||||
|
release_key = $UPGRADE_KEY
|
||||||
|
release_sig_url = $UPGRADE_SIG_URL
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract the binary packages into the sysroot.
|
||||||
|
for package in $packages; do
|
||||||
|
echo "Extracting $package.tix.tar.xz..."
|
||||||
|
tar -C "$cachedir/sysroot" -xJf "$cachedir/repository/$package.tix.tar.xz"
|
||||||
|
rm -f "$cachedir/repository/$package.tix.tar.xz"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Merge the new sysroot onto the installation.
|
||||||
|
sysmerge -t "$collection" --full $what_to_upgrade $wait "$cachedir/sysroot"
|
||||||
|
|
||||||
|
rm -rf -- "$cachedir/repository"
|
||||||
|
rm -rf -- "$cachedir/sysroot"
|
45
tix/tix.c
45
tix/tix.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2015, 2016, 2023 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2013, 2015, 2016, 2017, 2023 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -186,6 +186,8 @@ static void version(FILE* fp, const char* argv0)
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
const char* tmp = getenv_def("TMPDIR", "/tmp");
|
||||||
|
|
||||||
params_t params;
|
params_t params;
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.collection = NULL;
|
params.collection = NULL;
|
||||||
|
@ -260,7 +262,7 @@ int main(int argc, char* argv[])
|
||||||
errx(1, "error: no command specified.");
|
errx(1, "error: no command specified.");
|
||||||
|
|
||||||
const char* cmd = argv[1];
|
const char* cmd = argv[1];
|
||||||
if ( !strcmp(cmd, "install") )
|
if ( !strcmp(cmd, "old-install") )
|
||||||
{
|
{
|
||||||
if ( argc == 2 )
|
if ( argc == 2 )
|
||||||
errx(1, "expected list of packages to install after `install'");
|
errx(1, "expected list of packages to install after `install'");
|
||||||
|
@ -298,6 +300,45 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if ( !strcmp(cmd, "install") )
|
||||||
|
{
|
||||||
|
initialize_tmp(tmp, "tix-install");
|
||||||
|
if ( chdir(tmp_root) < 0 )
|
||||||
|
err(1, "%s", tmp_root);
|
||||||
|
|
||||||
|
if ( fork_and_wait_or_death() )
|
||||||
|
{
|
||||||
|
char** fetch_argv = malloc(sizeof(char*) * (5 + (argc-2) + 1));
|
||||||
|
fetch_argv[0] = (char*) "tix-fetch";
|
||||||
|
fetch_argv[1] = (char*) "--collection";
|
||||||
|
fetch_argv[2] = params.collection;
|
||||||
|
fetch_argv[3] = (char*) "--package";
|
||||||
|
fetch_argv[4] = (char*) "--";
|
||||||
|
int offset = 5;
|
||||||
|
for ( int i = 0; i < argc-2; i++ )
|
||||||
|
fetch_argv[offset + i] = argv[2 + i];
|
||||||
|
fetch_argv[offset + argc-2] = NULL;
|
||||||
|
execvp(fetch_argv[0], (char* const*) fetch_argv);
|
||||||
|
err(127, "`%s'", fetch_argv[0]);
|
||||||
|
}
|
||||||
|
for ( int i = 2; i < argc; i++ )
|
||||||
|
{
|
||||||
|
const char* pkg_name = argv[i];
|
||||||
|
char* pkg_path = print_string("%s%s", pkg_name, ".tix.tar.xz");
|
||||||
|
if ( fork_and_wait_or_death() )
|
||||||
|
{
|
||||||
|
const char* install_argv[] =
|
||||||
|
{
|
||||||
|
"tix-install",
|
||||||
|
"--collection", params.collection,
|
||||||
|
"--", pkg_path,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
execvp(install_argv[0], (char* const*) install_argv);
|
||||||
|
err(127, "`%s'", install_argv[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: unknown command: `%s'\n", argv0, cmd);
|
fprintf(stderr, "%s: unknown command: `%s'\n", argv0, cmd);
|
||||||
|
|
Loading…
Reference in a new issue