From a2baf79a44e7f83eae94f1ad04799e3d83f553e1 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 23 May 2015 00:20:28 +0200 Subject: [PATCH] COPKGManager: optimize check size To calculate the required size for installation here we make a quasi-dry run, it is a bit awkward, but relatively specific, other solutions are welcome. We create a temporary test directory and fill it with downloaded or user uploaded package file. Then we unpack the package and change into temporary testing directory. The required size results from the size of generated folders and subfolders. TODO: size of dependencies are not really considered Origin commit data ------------------ Commit: https://github.com/neutrino-images/ni-neutrino/commit/cceef62661cf7bd484a11463246dd413ff288673 Author: Thilo Graf Date: 2015-05-23 (Sat, 23 May 2015) --- src/gui/opkg_manager.cpp | 84 ++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 629b3f021..4571480e3 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -57,6 +57,7 @@ /* later this can be changed to just "opkg" */ #define OPKG_CL "opkg-cl" #define OPKG_TMP_DIR "/tmp/.opkg" +#define OPKG_TEST_DIR OPKG_TMP_DIR "/test" #define OPKG_CL_CONFIG_OPTIONS " -V2 --tmp-dir=/tmp --cache=" OPKG_TMP_DIR @@ -76,6 +77,7 @@ enum OM_INSTALL, OM_STATUS, OM_CONFIGURE, + OM_DOWNLOAD, OM_MAX }; @@ -90,7 +92,8 @@ static const string pkg_types[OM_MAX] = OPKG_CL " info ", OPKG_CL OPKG_CL_CONFIG_OPTIONS " install ", OPKG_CL " status ", - OPKG_CL " configure " + OPKG_CL " configure ", + OPKG_CL " download " }; COPKGManager::COPKGManager(): opkg_conf('\t') @@ -98,7 +101,7 @@ COPKGManager::COPKGManager(): opkg_conf('\t') width = 80; //define default dest keys - string dest_defaults[] = {"/", OPKG_TMP_DIR, "/mnt"}; + string dest_defaults[] = {"/", OPKG_TEST_DIR, OPKG_TMP_DIR, "/mnt"}; for(size_t i=0; i> pkg_size; + string pkg_file = pkg_name; + string plain_pkg = getBaseName(pkg_file); - string status = getPkgInfo(pkg_name, "Status"); - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] Status of %s: %s\n", __func__, __LINE__, pkg_name.c_str(), status.c_str()); - - //get available size + //get available root fs size //TODO: Check writability! struct statfs root_fs; - statfs("/",&root_fs); + statfs("/", &root_fs); u_int64_t free_size = root_fs.f_bfree*root_fs.f_bsize; - //only for sure, it's more secure for users to abort installation if is available size too small + /* - * FIXME: Package size is not really the same like required/recommended size, because of unknown compression factor of package, possible options like cache, different tmp-dir size, - * size of required dependencies eg. are still not considered. - * Experience values are nearly to factor 2.1 to 2.5 related to package size. That's generously but not 100% sure! + * To calculate the required size for installation here we make a quasi-dry run, + * it is a bit awkward, but relatively specific, other solutions are welcome. + * We create a temporary test directory and fill it with downloaded or user uploaded package file. + * Then we unpack the package and change into temporary testing directory. + * The required size results from the size of generated folders and subfolders. + * TODO: size of dependencies are not really considered */ - float pkg_raw_size = float(pkg_size); - u_int64_t req_size = u_int64_t(pkg_raw_size*2.5); + CFileHelpers fh; + + //create test pkg dir + string tmp_dest = OPKG_TEST_DIR; + tmp_dest += "/package"; + fh.createDir(tmp_dest); + + //change into test dir + chdir(OPKG_TEST_DIR); + + //copy package into test dir + string tmp_dest_file = OPKG_TEST_DIR; + tmp_dest_file += "/" + plain_pkg; + if(!access( pkg_file.c_str(), F_OK)) //use local package + fh.copyFile(pkg_file.c_str(), tmp_dest_file.c_str(), 0644); + else + execCmd(pkg_types[OM_DOWNLOAD] + plain_pkg); //download package + + //unpack package into test dir + string ar = "ar -x " + plain_pkg; + execCmd(ar); + + //untar package into test directory + string untar_tar_cmd = "tar -xf "; + untar_tar_cmd += OPKG_TEST_DIR; + untar_tar_cmd += "/data.tar.gz -C " + tmp_dest; + execCmd(untar_tar_cmd); + + //get new current required minimal size from dry run test dir + u_int64_t req_size = fh.getDirSize(tmp_dest); + + //clean up + fh.removeDir(OPKG_TEST_DIR); + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Package: %s [required size=%lld (free size: %lld)]\n", __func__, __LINE__, pkg_name.c_str(), req_size, free_size); if (free_size < req_size){ - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%lld package size=%lld (recommended: %lld)\n", __func__, __LINE__, free_size, pkg_size, req_size); - //exit with false if package not installed, allready installed packages will be be removed before install, therefore it should be enough disk space available -// if (status.empty()) - return false; + //exit if required size too much + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%lld (recommended: %lld)\n", __func__, __LINE__, free_size, req_size); + return false; } return true; } @@ -475,8 +506,11 @@ int COPKGManager::showMenu() if (!access( "/tmp/.force_restart", F_OK)) exit_action = "restart"; //reboot stb: forced - if (!access( "/tmp/.reboot", F_OK)) - exit_action = "reboot"; + if (!access( "/tmp/.reboot", F_OK)){ + //ShowHint("", "Reboot ...", 300, 3); //TODO + g_RCInput->postMsg( NeutrinoMessages::REBOOT, 0); + res = menu_return::RETURN_EXIT_ALL; + } } delete menu; @@ -740,7 +774,7 @@ bool COPKGManager::installPackage(const string& pkg_name, string options, bool f showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + opts + pkg_name); }else{ if (force_configure) - execCmd(pkg_types[OM_CONFIGURE] + pkg_name, false, false); + execCmd(pkg_types[OM_CONFIGURE] + getBlankPkgName(pkg_name), false, false); installed = true; } }