Skip to content

Commit 2de30e4

Browse files
committed
world_builder: add options to specify srpm source, output and where to take the releasepackages.lst file from
1 parent d0a10c5 commit 2de30e4

File tree

5 files changed

+359
-44
lines changed

5 files changed

+359
-44
lines changed

src/sgug-rpm-tools/Makefile.am

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ sgug_world_builder_SOURCES= \
99
installedrpm.hpp \
1010
sgug_dep_engine.hpp \
1111
specfile.hpp \
12+
standalonerpm.hpp \
13+
helpers.cpp \
14+
installedrpm.cpp \
1215
sgug_world_builder.cpp \
1316
specfile.cpp \
14-
installedrpm.cpp \
15-
helpers.cpp \
17+
standalonerpm.cpp \
1618
$(NULL)
1719

1820
sgug_minimal_computer_SOURCES= \
@@ -21,11 +23,13 @@ sgug_minimal_computer_SOURCES= \
2123
installedrpm.hpp \
2224
sgug_dep_engine.hpp \
2325
specfile.hpp \
24-
sgug_minimal_computer.cpp \
25-
specfile.cpp \
26-
installedrpm.cpp \
26+
standalonerpm.hpp \
2727
helpers.cpp \
28+
installedrpm.cpp \
2829
sgug_dep_engine.cpp \
30+
sgug_minimal_computer.cpp \
31+
specfile.cpp \
32+
standalonerpm.cpp \
2933
$(NULL)
3034

3135
AM_CFLAGS= \

src/sgug-rpm-tools/helpers.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ namespace sgug_rpm {
6666
0 == str.compare(str.size()-suf.size(), suf.size(), suf);
6767
}
6868

69+
inline bool str_starts_with( const std::string & str, const std::string & pre ) {
70+
return str.size() >= pre.size() &&
71+
0 == str.compare(0, pre.size(), pre);
72+
}
73+
6974
std::optional<std::pair<std::string,std::string> >
7075
find_package_providing_file( const std::string & required );
7176
std::optional<std::pair<std::string,std::string> >

src/sgug-rpm-tools/sgug_world_builder.cpp

Lines changed: 220 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
#include "helpers.hpp"
22
#include "specfile.hpp"
33
#include "installedrpm.hpp"
4+
#include "standalonerpm.hpp"
45
#include "dependencyset.hpp"
56

67
#include <iostream>
78
#include <fstream>
89
#include <filesystem>
910
#include <optional>
1011

12+
#include <rpm/header.h>
1113
#include <rpm/rpmcli.h>
1214
#include <rpm/rpmdb.h>
1315
#include <rpm/rpmds.h>
@@ -37,11 +39,42 @@ using std::filesystem::path;
3739

3840
namespace fs = std::filesystem;
3941

42+
static char * inputdir = NULL;
43+
static char * outputdir = NULL;
44+
static char * gitrootdir = NULL;
45+
4046
static struct poptOption optionsTable[] = {
4147
{
4248
NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
4349
"Common options for all rpm modes and executables",
4450
NULL },
51+
{
52+
"inputdir",
53+
'i',
54+
POPT_ARG_STRING,
55+
&inputdir,
56+
0,
57+
"Input directory where SRPM packages may be found",
58+
NULL
59+
},
60+
{
61+
"outputdir",
62+
'o',
63+
POPT_ARG_STRING,
64+
&outputdir,
65+
0,
66+
"Output directory where SRPM and RPM files will be placed",
67+
NULL
68+
},
69+
{
70+
"gitroot",
71+
'g',
72+
POPT_ARG_STRING,
73+
&gitrootdir,
74+
0,
75+
"RSE git repository directory containing releasepackages.lst",
76+
NULL
77+
},
4578
POPT_AUTOALIAS
4679
POPT_AUTOHELP
4780
POPT_TABLEEND
@@ -59,6 +92,60 @@ optional<string> calculate_expected_specfile_path( string sgug_rse_git_root,
5992
}
6093
}
6194

95+
optional<string> find_srpm_for_package( bool verbose,
96+
string sgug_rse_srpm_archive_root,
97+
string srpm_name )
98+
{
99+
path candidate_path = std::filesystem::path(sgug_rse_srpm_archive_root);
100+
if( verbose ) {
101+
cout << "# Looking for " << srpm_name << " under " << candidate_path << endl;
102+
}
103+
if( fs::exists(candidate_path) && fs::is_directory(candidate_path)) {
104+
vector<path> candidates;
105+
for( const auto & entry : fs::directory_iterator(candidate_path)) {
106+
path entry_path = entry.path();
107+
string entry_filename = entry_path.filename();
108+
// if( verbose ) {
109+
// cout << "# Looking for " << srpm_name << " at " << entry_filename <<
110+
// endl;
111+
// }
112+
if((!fs::is_directory(entry_path)) &&
113+
sgug_rpm::str_starts_with(entry_filename,srpm_name) &&
114+
sgug_rpm::str_ends_with(entry_filename, ".src.rpm") ) {
115+
candidates.push_back(entry_path);
116+
if( verbose ) {
117+
cout << "# Found candidate: " << entry_filename << endl;
118+
}
119+
}
120+
121+
}
122+
if(candidates.size() > 0) {
123+
for( const path & cp : candidates ) {
124+
sgug_rpm::standalonerpm sarpm;
125+
string canonical_filename = fs::canonical(cp);
126+
if( sgug_rpm::read_standalonerpm( verbose, canonical_filename,
127+
sarpm ) ) {
128+
if( sarpm.get_name() == srpm_name ) {
129+
return {cp.filename()};
130+
}
131+
else if(verbose) {
132+
cout << "# Examined " << canonical_filename <<
133+
" but failed match of package name" << endl;
134+
}
135+
}
136+
else if(verbose) {
137+
cerr << "# Couldn't open " << canonical_filename << endl;
138+
}
139+
}
140+
}
141+
142+
return {};
143+
}
144+
else {
145+
return {};
146+
}
147+
}
148+
62149
int main(int argc, char**argv)
63150
{
64151
vector<sgug_rpm::specfile> valid_specfiles;
@@ -71,17 +158,40 @@ int main(int argc, char**argv)
71158
exit(EXIT_FAILURE);
72159
}
73160

161+
// Check we have outputdir and gitrootdir
162+
if( inputdir == NULL || outputdir == NULL || gitrootdir == NULL ) {
163+
cerr << "inputdir, outputdir and gitrootdir must be passed" << endl;
164+
exit(EXIT_FAILURE);
165+
}
166+
path inputdir_p = {inputdir};
167+
path outputdir_p = {outputdir};
168+
path gitrootdir_p = {gitrootdir};
169+
74170
bool verbose = popt_context.verbose;
75171

76172
sgug_rpm::progress_printer pprinter;
77173

174+
path inputsrpm_p = inputdir_p;
175+
path buildprogress_p = outputdir_p / "PROGRESS";
176+
path outputsrpm_p = outputdir_p / "SRPMS";
177+
path outputrpm_p = outputdir_p / "RPMS";
178+
179+
/*
78180
string sgug_rse_git_root = "/usr/people/dan/Sources/GitClones/sgug-rse.git";
79-
string sgug_rse_srpm_archive_root = "/usr/people/dan/Temp/srpmfetches0.0.6";
181+
string build_progress_dir = "/usr/people/dan/Temp/build0.0.6round2/PROGRESS";
182+
string sgug_rse_srpm_archive_root = "/usr/people/dan/Temp/build0.0.6round1/SRPMS";
183+
string sgug_rse_srpm_output_root = "/usr/people/dan/Temp/build0.0.6round2/SRPMS";
184+
string sgug_rse_rpm_output_root = "/usr/people/dan/Temp/build0.0.6round2/RPMS";
185+
*/
80186

81187
cout << "# Reading spec files..." << endl;
82188

189+
std::ifstream input( fs::canonical(gitrootdir_p / "releasepackages.lst") );
190+
191+
192+
vector<string> names_in;
83193
string curline;
84-
for( string line; std::getline(cin, line); ) {
194+
for( string line; std::getline(input, line); ) {
85195
// Skip comments + empty lines
86196
if( line.length() == 0 || line[0] == '#' ) {
87197
continue;
@@ -90,12 +200,16 @@ int main(int argc, char**argv)
90200
// a) a specfile
91201
// b) an SRPM we can install that matches
92202
string package_name = line;
203+
names_in.push_back(package_name);
204+
}
205+
206+
for( string & package_name : names_in ) {
93207
optional<string> expected_specfile_path_opt =
94-
calculate_expected_specfile_path( sgug_rse_git_root,
208+
calculate_expected_specfile_path( gitrootdir_p,
95209
package_name );
96210
if( !expected_specfile_path_opt ) {
97211
cerr << "Missing spec for " << package_name << endl;
98-
cerr << "Looked under " << sgug_rse_git_root << "/packages/" <<
212+
cerr << "Looked under " << gitrootdir_p << "/packages/" <<
99213
package_name << "/SPECS/" << package_name << ".spec" << endl;
100214
exit(EXIT_FAILURE);
101215
}
@@ -114,6 +228,8 @@ int main(int argc, char**argv)
114228
else {
115229
failed_specfiles.push_back( package_name );
116230
}
231+
// Quick hack while testing, only do the first one
232+
//break;
117233
}
118234

119235
size_t num_specs = valid_specfiles.size();
@@ -136,35 +252,25 @@ int main(int argc, char**argv)
136252
for( const string & failed_fn : failed_specfiles ) {
137253
cout<< "# " << failed_fn << endl;
138254
}
255+
exit(EXIT_FAILURE);
139256
}
140257

141-
exit(1);
142-
// GOT HERE
143-
144-
// Now we work out for each of the rpms
145-
// (a) If such an RPM is installed
258+
vector<sgug_rpm::specfile> specs_to_rebuild = valid_specfiles;
146259

147-
vector<sgug_rpm::specfile> specs_to_rebuild;
260+
cout << "# Checking availability of SRPMs for packages..." << endl;
261+
unordered_map<string,string> package_to_srpm_map;
148262

149-
cout << "# Checking for installed packages and dependencies..." << endl;
150-
151-
for( const sgug_rpm::specfile & specfile: valid_specfiles ) {
152-
//cout << "# Walking spec " << specfile.get_name() << endl;
153-
size_t num_valid_rpms = 0;
154-
bool found_installed_package = false;
155-
for( const string & pkg : specfile.get_packages() ) {
156-
sgug_rpm::installedrpm foundrpm;
157-
bool valid_rpm = sgug_rpm::read_installedrpm( verbose, pkg, foundrpm );
158-
if( valid_rpm ) {
159-
found_installed_package = true;
160-
}
161-
}
162-
pprinter.accept_progress();
163-
if( found_installed_package ) {
164-
specs_to_rebuild.emplace_back(specfile);
263+
for( const sgug_rpm::specfile & specfile : valid_specfiles ) {
264+
const string & srpm_name = specfile.get_name();
265+
cout << "# Looking for srpm " << srpm_name << endl;
266+
optional<string> found_srpm_opt =
267+
find_srpm_for_package( verbose, inputsrpm_p, srpm_name );
268+
if( !found_srpm_opt ) {
269+
cerr << "Unable to find SRPM for " << srpm_name << endl;
270+
exit(EXIT_FAILURE);
165271
}
272+
package_to_srpm_map[srpm_name] = *found_srpm_opt;
166273
}
167-
pprinter.reset();
168274

169275
cout << "# Writing worldrebuilder.sh..." << endl;
170276

@@ -178,21 +284,96 @@ int main(int argc, char**argv)
178284
worldrebuilderfile.open("worldrebuilder.sh");
179285
worldrebuilderfile << "#!/usr/sgug/bin/bash" << endl;
180286
worldrebuilderfile << "# This script should be run as your user!" << endl;
181-
worldrebuilderfile << "mkdir -p ~/rpmbuild/PROGRESS" << endl;
287+
worldrebuilderfile << "echo 'This script is SUPER DESTRUCTIVE.'" << endl;
288+
worldrebuilderfile << "echo 'So you must edit it which confirms you'" << endl;
289+
worldrebuilderfile << "echo 'agree with what it will do.'" << endl;
290+
worldrebuilderfile << "exit 1" << endl;
291+
worldrebuilderfile << "# Some useful variables" << endl;
292+
worldrebuilderfile << "build_progress_dir=" << buildprogress_p << endl;
293+
worldrebuilderfile << "sgug_rse_srpm_archive_root=" << inputsrpm_p << endl;
294+
worldrebuilderfile << "sgug_rse_git_root=" << gitrootdir_p << endl;
295+
worldrebuilderfile << "sgug_rse_srpm_output_root=" << outputsrpm_p << endl;
296+
worldrebuilderfile << "sgug_rse_rpm_output_root=" << outputrpm_p << endl;
297+
298+
worldrebuilderfile << "ORIG_WD=`pwd`" << endl;
299+
worldrebuilderfile << "cleanUpDirs () {" << endl;
300+
worldrebuilderfile << " rm -rf ~/rpmbuild" << endl;
301+
worldrebuilderfile << " mkdir -p ~/rpmbuild/BUILD" << endl;
302+
worldrebuilderfile << " mkdir -p ~/rpmbuild/BUILDROOT" << endl;
303+
worldrebuilderfile << " mkdir -p ~/rpmbuild/RPMS" << endl;
304+
worldrebuilderfile << " mkdir -p ~/rpmbuild/SOURCES" << endl;
305+
worldrebuilderfile << " mkdir -p ~/rpmbuild/SPECS" << endl;
306+
worldrebuilderfile << " mkdir -p ~/rpmbuild/SRPMS" << endl;
307+
worldrebuilderfile << " mkdir -p $build_progress_dir" << endl;
308+
worldrebuilderfile << " mkdir -p $sgug_rse_srpm_output_root" << endl;
309+
worldrebuilderfile << " mkdir -p $sgug_rse_rpm_output_root/noarch" << endl;
310+
worldrebuilderfile << " mkdir -p $sgug_rse_rpm_output_root/mips" << endl;
311+
worldrebuilderfile << "}" << endl;
312+
worldrebuilderfile << "installSrpm () {" << endl;
313+
worldrebuilderfile << " packageSrpmfile=$1" << endl;
314+
worldrebuilderfile << " rpm -ivh $packageSrpmfile" << endl;
315+
worldrebuilderfile << "}" << endl;
316+
worldrebuilderfile << "copySgugGitPackage () {" << endl;
317+
worldrebuilderfile << " sgugGitPackageRoot=$1" << endl;
318+
worldrebuilderfile << " cp -r $sgugGitPackageRoot/* ~/rpmbuild/" << endl;
319+
worldrebuilderfile << "}" << endl;
320+
worldrebuilderfile << "rpmbuildPackage () {" << endl;
321+
worldrebuilderfile << " packageName=$1" << endl;
322+
worldrebuilderfile << " cd ~/rpmbuild/SPECS" << endl;
323+
worldrebuilderfile << " rpmbuild -ba \"$packageName.spec\" --nocheck" << endl;
324+
worldrebuilderfile << " rpmrc=$?" << endl;
325+
worldrebuilderfile << " cd $ORIG_WD" << endl;
326+
worldrebuilderfile << " return $rpmrc" << endl;
327+
worldrebuilderfile << "}" << endl;
328+
worldrebuilderfile << "archiveBuiltArtefacts () {" << endl;
329+
worldrebuilderfile << " mv ~/rpmbuild/SRPMS/* $sgug_rse_srpm_output_root/" << endl;
330+
worldrebuilderfile << " if [[ -e ~/rpmbuild/RPMS/noarch ]]; then" << endl;
331+
worldrebuilderfile << " mv ~/rpmbuild/RPMS/noarch/* $sgug_rse_rpm_output_root/noarch/" << endl;
332+
worldrebuilderfile << " fi" << endl;
333+
worldrebuilderfile << " if [[ -e ~/rpmbuild/RPMS/mips ]]; then" << endl;
334+
worldrebuilderfile << " mv ~/rpmbuild/RPMS/mips/* $sgug_rse_rpm_output_root/mips/" << endl;
335+
worldrebuilderfile << " fi" << endl;
336+
worldrebuilderfile << "}" << endl;
337+
worldrebuilderfile << "doPackageBuild () {" << endl;
338+
worldrebuilderfile << " packageName=$1" << endl;
339+
worldrebuilderfile << " packageSrpm=$2" << endl;
340+
worldrebuilderfile << " startedFilename=\"$build_progress_dir/$packageName.started\"" << endl;
341+
worldrebuilderfile << " failedFilename=\"$build_progress_dir/$packageName.failed\"" << endl;
342+
worldrebuilderfile << " successFilename=\"$build_progress_dir/$packageName.success\"" << endl;
343+
worldrebuilderfile << " if [[ -e $startedFilename ]]; then" << endl;
344+
worldrebuilderfile << " echo \"$packageName was previously started. Skipping.\"" << endl;
345+
worldrebuilderfile << " else" << endl;
346+
worldrebuilderfile << " cleanUpDirs" << endl;
347+
worldrebuilderfile << " touch $startedFilename" << endl;
348+
worldrebuilderfile << " installSrpm \"$sgug_rse_srpm_archive_root/$packageSrpm\"" << endl;
349+
worldrebuilderfile << " copySgugGitPackage \"$sgug_rse_git_root/packages/$packageName\"" << endl;
350+
worldrebuilderfile << " rpmbuildPackage \"$packageName\"" << endl;
351+
worldrebuilderfile << " packageBuildStatus=$?" << endl;
352+
worldrebuilderfile << " if [[ $packageBuildStatus -ne 0 ]]; then" << endl;
353+
worldrebuilderfile << " touch $failedFilename" << endl;
354+
worldrebuilderfile << " else" << endl;
355+
worldrebuilderfile << " archiveBuiltArtefacts" << endl;
356+
worldrebuilderfile << " touch $successFilename" << endl;
357+
worldrebuilderfile << " fi" << endl;
358+
worldrebuilderfile << " fi" << endl;
359+
worldrebuilderfile << "}" << endl;
360+
worldrebuilderfile << "# The package list..." << endl;
182361

183362
for( const sgug_rpm::specfile & spec : specs_to_rebuild ) {
184363
const string & name = spec.get_name();
185-
worldrebuilderfile << "# Must rebuild: " << name << endl;
186-
worldrebuilderfile << "touch ~/rpmbuild/PROGRESS/" << name << ".start" <<
187-
endl;
188-
worldrebuilderfile << "rpmbuild -ba " << name << ".spec --nocheck" <<
189-
endl;
190-
worldrebuilderfile << "if [[ $? -ne 0 ]]; then" << endl;
191-
worldrebuilderfile << " touch ~/rpmbuild/PROGRESS/" << name <<
192-
".failed" << endl;
193-
worldrebuilderfile << "fi" << endl;
194-
worldrebuilderfile << "touch ~/rpmbuild/PROGRESS/" << name << ".done" <<
195-
endl;
364+
const string & srpm = package_to_srpm_map[name];
365+
worldrebuilderfile << "doPackageBuild '" << name << "' '" <<
366+
srpm << "'" << endl;
367+
// worldrebuilderfile << "touch ~/rpmbuild/PROGRESS/" << name << ".start" <<
368+
// endl;
369+
// worldrebuilderfile << "rpmbuild -ba " << name << ".spec --nocheck" <<
370+
// endl;
371+
// worldrebuilderfile << "if [[ $? -ne 0 ]]; then" << endl;
372+
// worldrebuilderfile << " touch ~/rpmbuild/PROGRESS/" << name <<
373+
// ".failed" << endl;
374+
// worldrebuilderfile << "fi" << endl;
375+
// worldrebuilderfile << "touch ~/rpmbuild/PROGRESS/" << name << ".done" <<
376+
// endl;
196377
}
197378

198379
worldrebuilderfile.close();

0 commit comments

Comments
 (0)