cache the pkgmk.conf settings to avoid repeated disk reads (FS#595)

fix the interaction between --install-root and 'runscripts yes'
This commit is contained in:
John McQuah 2023-06-09 21:11:34 -04:00
parent e504cf66d3
commit 8f71c4fe8b
7 changed files with 79 additions and 89 deletions

View File

@ -36,7 +36,8 @@ Configuration::Configuration( const std::string& configFile,
m_useRegex( false ),
m_followSoftdeps( false ),
m_makeCommand( "" ), m_addCommand( "" ),
m_removeCommand( "" ), m_runscriptCommand( "" )
m_removeCommand( "" ), m_runscriptCommand( "" ),
m_packageDir( "" ), m_compressionMode( "" )
{
}
@ -89,6 +90,25 @@ string Configuration::logFilePattern() const
return m_logFilePattern;
}
string Configuration::packageDir() const
{
string value = "";
char line[256];
string cmd = "eval " + m_packageDir + " && echo \"$PKGMK_PACKAGE_DIR\"";
FILE* p = popen(cmd.c_str(), "r");
if (p) {
fgets(line, 256, p);
value = StringHelper::stripWhiteSpace(line);
pclose(p);
}
return value;
}
string Configuration::compressionMode() const
{
return ( m_compressionMode == "" ) ? "gz" : m_compressionMode;
}
const list< pair<string, string> >& Configuration::rootList() const
{
@ -215,6 +235,32 @@ void Configuration::parseLine(const string& line, bool prepend)
}
}
bool Configuration::parsePkgmkConf(int readOrder)
{
string fileName = (readOrder == 1) ? "/etc/pkgmk.conf" : "/usr/bin/pkgmk";
FILE* fp = fopen(fileName.c_str(), "r");
if (!fp)
return false;
string s;
char line[256];
while (fgets(line, 256, fp)) {
s = StringHelper::stripWhiteSpace(getValueBefore(line,'#'));
if ( StringHelper::startsWith(s, "PKGMK_COMPRESSION_MODE=") &&
(readOrder==1 || m_compressionMode == "") ) {
m_compressionMode = s.substr(23);
StringHelper::replaceAll(m_compressionMode,"\"","");
StringHelper::replaceAll(m_compressionMode,"'","");
} else if ( StringHelper::startsWith(s, "PKGMK_PACKAGE_DIR=") &&
(readOrder==1 || m_packageDir == "" ) ) {
m_packageDir = s;
}
}
fclose(fp);
return ( m_compressionMode != "" && m_packageDir != "" );
}
bool Configuration::runScripts() const
{
return m_runScripts;

View File

@ -45,6 +45,8 @@ public:
bool useRegex() const;
bool followSoftdeps() const;
bool parsePkgmkConf(int readOrder);
void addConfig(const std::string& line,
bool configSet,
bool configPrepend);
@ -53,6 +55,8 @@ public:
std::string addCommand() const;
std::string removeCommand() const;
std::string runscriptCommand() const;
std::string packageDir() const;
std::string compressionMode() const;
private:
std::string m_configFile;
@ -80,6 +84,8 @@ private:
std::string m_removeCommand;
std::string m_runscriptCommand;
std::string m_packageDir;
std::string m_compressionMode;
void parseLine(const std::string& line, bool prepend=false);
};

View File

@ -313,10 +313,10 @@ InstallTransaction::installPackage( const Package* package,
// -- pre-install
struct stat statData;
if ((parser->execPreInstall() || m_config->runScripts()) &&
stat((pkgdir + "/" + "pre-install").c_str(), &statData) == 0) {
Process preProc( runscriptCommand,
pkgdir + "/" + "pre-install",
fdlog );
stat((parser->installRoot() + pkgdir + "/" + "pre-install").c_str(),
&statData) == 0) {
Process preProc( runscriptCommand, parser->installRoot() + pkgdir
+ "/" + "pre-install", fdlog );
if (preProc.executeShell()) {
info.preState = FAILED;
} else {
@ -336,7 +336,7 @@ InstallTransaction::installPackage( const Package* package,
result = PKGMK_FAILURE;
} else {
// -- update
string pkgdest = getPkgmkPackageDir();
string pkgdest = m_config->packageDir();
if ( pkgdest != "" ) {
// TODO: don't manipulate pkgdir
pkgdir = pkgdest;
@ -374,7 +374,7 @@ InstallTransaction::installPackage( const Package* package,
args +=
package->name() + "#" +
package->version() + "-" +
package->release() + ".pkg.tar." + getPkgmkCompressionMode();
package->release() + ".pkg.tar." + m_config->compressionMode();
// - inform the user about what's happening
@ -421,14 +421,13 @@ InstallTransaction::installPackage( const Package* package,
} else {
// exec post install
if ((parser->execPostInstall() || m_config->runScripts() ) &&
stat((package->path() + "/" + package->name() +
"/" + "post-install").c_str(), &statData)
== 0) {
stat((parser->installRoot() + "/" + package->path() + "/"
+ package->name() + "/" + "post-install").c_str(),
&statData) == 0) {
// Work around the pkgdir variable change
Process postProc( runscriptCommand,
package->path() + "/" + package->name()+
"/" + "post-install",
fdlog );
Process postProc( runscriptCommand,
parser->installRoot() + "/" + package->path() + "/"
+ package->name() + "/post-install", fdlog );
if (postProc.executeShell()) {
info.postState = FAILED;
} else {
@ -679,64 +678,7 @@ InstallTransaction::calcDependencies( )
}
/*
* getPkgDest assumes that you're in the build directory already
*/
string InstallTransaction::getPkgmkSetting(const string& setting)
{
string value = "";
value = getPkgmkSettingFromFile(setting, "/etc/pkgmk.conf");
if (value.size() == 0) {
value = getPkgmkSettingFromFile(setting, "/usr/bin/pkgmk");
}
return value;
}
string InstallTransaction::getPkgmkSettingFromFile(const string& setting, const string& fileName)
{
FILE* fp = fopen(fileName.c_str(), "r");
if (!fp)
return "";
string candidate;
string s;
char line[256];
while (fgets(line, 256, fp)) {
s = StringHelper::stripWhiteSpace(line);
if (StringHelper::startsWith(s, setting + "=")) {
candidate = s;
}
}
fclose(fp);
string value = "";
if (candidate.length() > 0) {
string cmd = "eval " + candidate + " && echo $" + setting;
FILE* p = popen(cmd.c_str(), "r");
if (p) {
fgets(line, 256, p);
value = StringHelper::stripWhiteSpace(line);
pclose(p);
}
}
return value;
}
const list<string>& InstallTransaction::ignoredPackages() const
{
return m_ignoredPackages;
}
string InstallTransaction::getPkgmkPackageDir()
{
return getPkgmkSetting("PKGMK_PACKAGE_DIR");
}
string InstallTransaction::getPkgmkCompressionMode()
{
string value = getPkgmkSetting("PKGMK_COMPRESSION_MODE");
return value.size() ? value : "gz";
}

View File

@ -97,9 +97,6 @@ public:
const list< pair<string,string> >& missing() const;
const list< pair<string, InstallInfo> >& installError() const;
static string getPkgmkPackageDir();
static string getPkgmkCompressionMode();
private:
bool calculateDependencies();
void checkDependencies( bool greedy, const Package* package, int depends=-1 );
@ -110,10 +107,6 @@ private:
InstallInfo& info ) const;
bool isRequested(const string pname);
static string getPkgmkSetting(const string& setting);
static string getPkgmkSettingFromFile(const string& setting,
const string& fileName);
PkgDB* m_pkgDB;
DepResolver m_resolver;
const Repository* m_repo;

View File

@ -68,9 +68,9 @@ int Process::execute()
int status = 0;
if ( m_fdlog > 0 ) {
status = execLog(argc, argv);
status = execLog(argv);
} else {
status = exec(argc, argv);
status = exec(argv);
}
delete [] argv;
@ -78,7 +78,7 @@ int Process::execute()
}
int Process::execLog(const int argc, char** argv)
int Process::execLog(char** argv)
{
int status = 0;
int fdpipe[2];
@ -123,7 +123,7 @@ int Process::execLog(const int argc, char** argv)
}
int Process::exec(const int argc, char** argv)
int Process::exec(char** argv)
{
int status = 0;
pid_t pid = fork();

View File

@ -32,8 +32,8 @@ public:
private:
int exec(const int argc, char** argv);
int execLog(const int argc, char** argv);
int exec(char** argv);
int execLog(char** argv);
int execShell(const char* shell);
int execShellLog(const char* shell);

View File

@ -710,7 +710,7 @@ void PrtGet::executeTransaction( InstallTransaction& transaction,
break;
case InstallTransaction::PKGDEST_ERROR:
cout << m_appName << ": error changing to PKGDEST directory "
<< transaction.getPkgmkPackageDir() << endl;
<< m_config->packageDir() << endl;
failed = true;
break;
case InstallTransaction::PKGADD_FAILURE:
@ -857,6 +857,10 @@ void PrtGet::readConfig()
}
}
if (!m_config->parsePkgmkConf(1)) {
m_config->parsePkgmkConf(0);
}
const list< pair<char*, ArgParser::ConfigArgType> >& configData =
m_parser->configData();
list< pair<char*, ArgParser::ConfigArgType> >::const_iterator it =
@ -2240,18 +2244,17 @@ void PrtGet::dumpConfig()
cout.setf( ios::left, ios::adjustfield );
cout.width( 20 );
cout.fill( ' ' );
cout << "Pkgmk settings: " << m_config->logFilePattern() << endl;
cout << "Pkgmk settings: " << endl;
cout.setf( ios::left, ios::adjustfield );
cout.width( 20 );
cout.fill( ' ' );
cout << " Package dir: " << InstallTransaction::getPkgmkPackageDir()
cout << " Package dir: " << m_config->packageDir()
<< endl;
cout.setf( ios::left, ios::adjustfield );
cout.width( 20 );
cout.fill( ' ' );
cout << " Compression mode: "
<< InstallTransaction::getPkgmkCompressionMode() << endl;
cout << " Compression mode: " << m_config->compressionMode() << endl;
cout << endl;