unpack: keep conf_files replaced with symlinks, unpack as .new-pkgver
This commit is contained in:
parent
2ad2659d4c
commit
ea2cb1d369
@ -115,7 +115,7 @@ int HIDDEN xbps_cb_message(struct xbps_handle *, xbps_dictionary_t, const char *
|
||||
int HIDDEN xbps_entry_is_a_conf_file(xbps_dictionary_t, const char *);
|
||||
int HIDDEN xbps_entry_install_conf_file(struct xbps_handle *, xbps_dictionary_t,
|
||||
xbps_dictionary_t, struct archive_entry *, const char *,
|
||||
const char *);
|
||||
const char *, bool);
|
||||
int HIDDEN xbps_repository_find_deps(struct xbps_handle *, xbps_array_t,
|
||||
xbps_dictionary_t);
|
||||
xbps_dictionary_t HIDDEN xbps_find_virtualpkg_in_conf(struct xbps_handle *,
|
||||
|
@ -63,7 +63,8 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
|
||||
xbps_dictionary_t pkg_filesd,
|
||||
struct archive_entry *entry,
|
||||
const char *entry_pname,
|
||||
const char *pkgver)
|
||||
const char *pkgver,
|
||||
bool symlink)
|
||||
{
|
||||
xbps_object_t obj, obj2;
|
||||
xbps_object_iterator_t iter, iter2;
|
||||
@ -87,9 +88,10 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
|
||||
xbps_dbg_printf(xhp, "%s: processing conf_file %s\n",
|
||||
pkgver, entry_pname);
|
||||
|
||||
if (pkg_filesd == NULL) {
|
||||
if (pkg_filesd == NULL || symlink) {
|
||||
/*
|
||||
* File exists on disk but it's not managed by the same package.
|
||||
* 1. File exists on disk but it's not managed by the same package.
|
||||
* 2. File exists on disk as symlink.
|
||||
* Install it as file.new-<version>.
|
||||
*/
|
||||
version = xbps_pkg_version(pkgver);
|
||||
|
@ -87,7 +87,7 @@ unpack_archive(struct xbps_handle *xhp,
|
||||
const char *file, *entry_pname, *transact, *binpkg_pkgver;
|
||||
char *pkgname, *buf;
|
||||
int ar_rv, rv, error, entry_type, flags;
|
||||
bool preserve, update, file_exists;
|
||||
bool preserve, update, file_exists, keep_conf_file;
|
||||
bool skip_extract, force, xucd_stats;
|
||||
uid_t euid;
|
||||
|
||||
@ -287,7 +287,7 @@ unpack_archive(struct xbps_handle *xhp,
|
||||
* doesn't match, in that case overwrite the file.
|
||||
* Otherwise skip extracting it.
|
||||
*/
|
||||
skip_extract = file_exists = false;
|
||||
skip_extract = file_exists = keep_conf_file = false;
|
||||
if (lstat(entry_pname, &st) == 0)
|
||||
file_exists = true;
|
||||
/*
|
||||
@ -303,32 +303,41 @@ unpack_archive(struct xbps_handle *xhp,
|
||||
"it's preserved.\n", pkgver, entry_pname);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if current entry is a configuration file,
|
||||
* that should be kept.
|
||||
*/
|
||||
if (!force && (entry_type == AE_IFREG)) {
|
||||
buf = strchr(entry_pname, '.') + 1;
|
||||
assert(buf != NULL);
|
||||
keep_conf_file = xbps_entry_is_a_conf_file(binpkg_filesd, buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* If file to be extracted does not match the file type of
|
||||
* file currently stored on disk, remove file on disk.
|
||||
* file currently stored on disk and is not a conf file
|
||||
* that should be kept, remove file on disk.
|
||||
*/
|
||||
if (file_exists &&
|
||||
if (file_exists && !keep_conf_file &&
|
||||
((entry_statp->st_mode & S_IFMT) != (st.st_mode & S_IFMT)))
|
||||
(void)remove(entry_pname);
|
||||
|
||||
if (!force && (entry_type == AE_IFREG)) {
|
||||
buf = strchr(entry_pname, '.') + 1;
|
||||
assert(buf != NULL);
|
||||
if (file_exists && S_ISREG(st.st_mode)) {
|
||||
if (file_exists && (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) {
|
||||
/*
|
||||
* Handle configuration files. Check if current
|
||||
* entry is a configuration file and take action
|
||||
* if required. Skip packages that don't have
|
||||
* "conf_files" array on its XBPS_PKGPROPS
|
||||
* Handle configuration files.
|
||||
* Skip packages that don't have "conf_files"
|
||||
* array on its XBPS_PKGPROPS
|
||||
* dictionary.
|
||||
*/
|
||||
if (xbps_entry_is_a_conf_file(binpkg_filesd, buf)) {
|
||||
if (keep_conf_file) {
|
||||
if (xhp->unpack_cb != NULL)
|
||||
xucd.entry_is_conf = true;
|
||||
|
||||
rv = xbps_entry_install_conf_file(xhp,
|
||||
binpkg_filesd, pkg_filesd, entry,
|
||||
entry_pname, pkgver);
|
||||
entry_pname, pkgver, S_ISLNK(st.st_mode));
|
||||
if (rv == -1) {
|
||||
/* error */
|
||||
goto out;
|
||||
|
@ -165,9 +165,70 @@ tc4_body() {
|
||||
atf_check_equal $rval 0
|
||||
}
|
||||
|
||||
# 5th test: configuration file replaced with symlink on disk, modified on upgrade.
|
||||
# result: install new file as "<conf_file>.new-<version>".
|
||||
atf_test_case tc5
|
||||
|
||||
tc5_head() {
|
||||
atf_set "descr" "Tests for configuration file handling: on-disk replaced with symlink, upgrade modified"
|
||||
}
|
||||
|
||||
tc5_body() {
|
||||
mkdir repo
|
||||
cd repo
|
||||
mkdir pkg_a
|
||||
echo "fooblah" > pkg_a/cf1.conf
|
||||
chmod 644 pkg_a/cf1.conf
|
||||
xbps-create -A noarch -n a-0.1_1 -s "pkg a" --config-files "/cf1.conf" pkg_a
|
||||
atf_check_equal $? 0
|
||||
rm -rf pkg_a
|
||||
xbps-rindex -d -a $PWD/*.xbps
|
||||
atf_check_equal $? 0
|
||||
xbps-install -C null.conf -r rootdir --repository=$PWD -yvd a
|
||||
atf_check_equal $? 0
|
||||
|
||||
mv rootdir/cf1.conf rootdir/foobar.conf
|
||||
ln -sf foobar.conf rootdir/cf1.conf
|
||||
sed -e 's,fooblah,blahfoo,' -i rootdir/foobar.conf
|
||||
chmod 644 rootdir/foobar.conf
|
||||
|
||||
mkdir pkg_a
|
||||
echo "bazbar" > pkg_a/cf1.conf
|
||||
chmod 644 pkg_a/cf1.conf
|
||||
xbps-create -A noarch -n a-0.2_1 -s "pkg a" --config-files "/cf1.conf" pkg_a
|
||||
atf_check_equal $? 0
|
||||
|
||||
xbps-rindex -d -a $PWD/*.xbps
|
||||
atf_check_equal $? 0
|
||||
rm -rf pkg_a
|
||||
|
||||
xbps-install -C null.conf -r rootdir --repository=$PWD -yuvd
|
||||
atf_check_equal $? 0
|
||||
|
||||
ls -lsa rootdir
|
||||
test -h rootdir/cf1.conf
|
||||
atf_check_equal $? 0
|
||||
|
||||
result="$(cat rootdir/cf1.conf)"
|
||||
rval=1
|
||||
if [ "${result}" = "blahfoo" ]; then
|
||||
rval=0
|
||||
fi
|
||||
|
||||
echo "result: ${result}"
|
||||
echo "expected: blahfoo"
|
||||
atf_check_equal $rval 0
|
||||
rval=1
|
||||
if [ -s rootdir/cf1.conf.new-0.2_1 ]; then
|
||||
rval=0
|
||||
fi
|
||||
atf_check_equal $rval 0
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case tc1
|
||||
atf_add_test_case tc2
|
||||
atf_add_test_case tc3
|
||||
atf_add_test_case tc4
|
||||
atf_add_test_case tc5
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user