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_is_a_conf_file(xbps_dictionary_t, const char *);
|
||||||
int HIDDEN xbps_entry_install_conf_file(struct xbps_handle *, xbps_dictionary_t,
|
int HIDDEN xbps_entry_install_conf_file(struct xbps_handle *, xbps_dictionary_t,
|
||||||
xbps_dictionary_t, struct archive_entry *, const char *,
|
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,
|
int HIDDEN xbps_repository_find_deps(struct xbps_handle *, xbps_array_t,
|
||||||
xbps_dictionary_t);
|
xbps_dictionary_t);
|
||||||
xbps_dictionary_t HIDDEN xbps_find_virtualpkg_in_conf(struct xbps_handle *,
|
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,
|
xbps_dictionary_t pkg_filesd,
|
||||||
struct archive_entry *entry,
|
struct archive_entry *entry,
|
||||||
const char *entry_pname,
|
const char *entry_pname,
|
||||||
const char *pkgver)
|
const char *pkgver,
|
||||||
|
bool symlink)
|
||||||
{
|
{
|
||||||
xbps_object_t obj, obj2;
|
xbps_object_t obj, obj2;
|
||||||
xbps_object_iterator_t iter, iter2;
|
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",
|
xbps_dbg_printf(xhp, "%s: processing conf_file %s\n",
|
||||||
pkgver, entry_pname);
|
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>.
|
* Install it as file.new-<version>.
|
||||||
*/
|
*/
|
||||||
version = xbps_pkg_version(pkgver);
|
version = xbps_pkg_version(pkgver);
|
||||||
|
@ -87,7 +87,7 @@ unpack_archive(struct xbps_handle *xhp,
|
|||||||
const char *file, *entry_pname, *transact, *binpkg_pkgver;
|
const char *file, *entry_pname, *transact, *binpkg_pkgver;
|
||||||
char *pkgname, *buf;
|
char *pkgname, *buf;
|
||||||
int ar_rv, rv, error, entry_type, flags;
|
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;
|
bool skip_extract, force, xucd_stats;
|
||||||
uid_t euid;
|
uid_t euid;
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ unpack_archive(struct xbps_handle *xhp,
|
|||||||
* doesn't match, in that case overwrite the file.
|
* doesn't match, in that case overwrite the file.
|
||||||
* Otherwise skip extracting it.
|
* Otherwise skip extracting it.
|
||||||
*/
|
*/
|
||||||
skip_extract = file_exists = false;
|
skip_extract = file_exists = keep_conf_file = false;
|
||||||
if (lstat(entry_pname, &st) == 0)
|
if (lstat(entry_pname, &st) == 0)
|
||||||
file_exists = true;
|
file_exists = true;
|
||||||
/*
|
/*
|
||||||
@ -303,32 +303,41 @@ unpack_archive(struct xbps_handle *xhp,
|
|||||||
"it's preserved.\n", pkgver, entry_pname);
|
"it's preserved.\n", pkgver, entry_pname);
|
||||||
continue;
|
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
|
* 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)))
|
((entry_statp->st_mode & S_IFMT) != (st.st_mode & S_IFMT)))
|
||||||
(void)remove(entry_pname);
|
(void)remove(entry_pname);
|
||||||
|
|
||||||
if (!force && (entry_type == AE_IFREG)) {
|
if (!force && (entry_type == AE_IFREG)) {
|
||||||
buf = strchr(entry_pname, '.') + 1;
|
if (file_exists && (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) {
|
||||||
assert(buf != NULL);
|
|
||||||
if (file_exists && S_ISREG(st.st_mode)) {
|
|
||||||
/*
|
/*
|
||||||
* Handle configuration files. Check if current
|
* Handle configuration files.
|
||||||
* entry is a configuration file and take action
|
* Skip packages that don't have "conf_files"
|
||||||
* if required. Skip packages that don't have
|
* array on its XBPS_PKGPROPS
|
||||||
* "conf_files" array on its XBPS_PKGPROPS
|
|
||||||
* dictionary.
|
* dictionary.
|
||||||
*/
|
*/
|
||||||
if (xbps_entry_is_a_conf_file(binpkg_filesd, buf)) {
|
if (keep_conf_file) {
|
||||||
if (xhp->unpack_cb != NULL)
|
if (xhp->unpack_cb != NULL)
|
||||||
xucd.entry_is_conf = true;
|
xucd.entry_is_conf = true;
|
||||||
|
|
||||||
rv = xbps_entry_install_conf_file(xhp,
|
rv = xbps_entry_install_conf_file(xhp,
|
||||||
binpkg_filesd, pkg_filesd, entry,
|
binpkg_filesd, pkg_filesd, entry,
|
||||||
entry_pname, pkgver);
|
entry_pname, pkgver, S_ISLNK(st.st_mode));
|
||||||
if (rv == -1) {
|
if (rv == -1) {
|
||||||
/* error */
|
/* error */
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -165,9 +165,70 @@ tc4_body() {
|
|||||||
atf_check_equal $rval 0
|
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_init_test_cases() {
|
||||||
atf_add_test_case tc1
|
atf_add_test_case tc1
|
||||||
atf_add_test_case tc2
|
atf_add_test_case tc2
|
||||||
atf_add_test_case tc3
|
atf_add_test_case tc3
|
||||||
atf_add_test_case tc4
|
atf_add_test_case tc4
|
||||||
|
atf_add_test_case tc5
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user