]> git.saurik.com Git - apt.git/blame_incremental - cmdline/apt-internal-planer.cc
eipp: implement Immediate-Configuration flag
[apt.git] / cmdline / apt-internal-planer.cc
... / ...
CommitLineData
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
3/* #####################################################################
4
5 cover around the internal solver to be able to run it like an external
6
7 ##################################################################### */
8 /*}}}*/
9// Include Files /*{{{*/
10#include <config.h>
11
12#include <apt-pkg/error.h>
13#include <apt-pkg/cmndline.h>
14#include <apt-pkg/init.h>
15#include <apt-pkg/cachefile.h>
16#include <apt-pkg/cacheset.h>
17#include <apt-pkg/strutl.h>
18#include <apt-pkg/edsp.h>
19#include <apt-pkg/fileutl.h>
20#include <apt-pkg/pkgsystem.h>
21#include <apt-pkg/configuration.h>
22#include <apt-pkg/packagemanager.h>
23#include <apt-pkg/prettyprinters.h>
24#include <apt-pkg/depcache.h>
25#include <apt-pkg/pkgcache.h>
26#include <apt-pkg/cacheiterators.h>
27
28#include <apt-private/private-output.h>
29#include <apt-private/private-cmndline.h>
30#include <apt-private/private-main.h>
31
32#include <string.h>
33#include <iostream>
34#include <sstream>
35#include <list>
36#include <string>
37#include <unistd.h>
38#include <cstdio>
39#include <stdlib.h>
40
41#include <apti18n.h>
42 /*}}}*/
43
44static bool ShowHelp(CommandLine &) /*{{{*/
45{
46 std::cout <<
47 _("Usage: apt-internal-planer\n"
48 "\n"
49 "apt-internal-planer is an interface to use the current internal\n"
50 "installation planer for the APT family like an external one,\n"
51 "for debugging or the like.\n");
52 return true;
53}
54 /*}}}*/
55APT_NORETURN static void DIE(std::string const &message) { /*{{{*/
56 std::cerr << "ERROR: " << message << std::endl;
57 _error->DumpErrors(std::cerr);
58 exit(EXIT_FAILURE);
59}
60 /*}}}*/
61static std::vector<aptDispatchWithHelp> GetCommands() /*{{{*/
62{
63 return {};
64}
65 /*}}}*/
66class PMOutput: public pkgPackageManager /*{{{*/
67{
68 FileFd &output;
69 bool const Debug;
70
71protected:
72 virtual bool Install(PkgIterator Pkg,std::string) APT_OVERRIDE
73 {
74 //std::cerr << "INSTALL: " << APT::PrettyPkg(&Cache, Pkg) << std::endl;
75 return EDSP::WriteSolutionStanza(output, "Install", Cache[Pkg].InstVerIter(Cache));
76 }
77 virtual bool Configure(PkgIterator Pkg) APT_OVERRIDE
78 {
79 //std::cerr << "CONFIGURE: " << APT::PrettyPkg(&Cache, Pkg) << " " << std::endl;
80 return EDSP::WriteSolutionStanza(output, "Configure", Cache[Pkg].InstVerIter(Cache));
81 }
82 virtual bool Remove(PkgIterator Pkg,bool) APT_OVERRIDE
83 {
84 //std::cerr << "REMOVE: " << APT::PrettyPkg(&Cache, Pkg) << " " << std::endl;
85 return EDSP::WriteSolutionStanza(output, "Remove", Pkg.CurrentVer());
86 }
87public:
88 PMOutput(pkgDepCache *Cache, FileFd &file) : pkgPackageManager(Cache), output(file),
89 Debug(_config->FindB("Debug::EDSP::WriteSolution", false))
90 {}
91
92 bool ApplyRequest(std::list<std::pair<std::string,EIPP::PKG_ACTION>> const &actions)
93 {
94 for (auto && a: actions)
95 {
96 auto const Pkg = Cache.FindPkg(a.first);
97 if (unlikely(Pkg.end() == true))
98 continue;
99 switch (a.second)
100 {
101 case EIPP::PKG_ACTION::NOOP:
102 break;
103 case EIPP::PKG_ACTION::INSTALL:
104 case EIPP::PKG_ACTION::REINSTALL:
105 FileNames[Pkg->ID] = "EIPP";
106 break;
107 case EIPP::PKG_ACTION::REMOVE:
108 break;
109 }
110 }
111 return true;
112 }
113};
114 /*}}}*/
115int main(int argc,const char *argv[]) /*{{{*/
116{
117 // we really don't need anything
118 DropPrivileges();
119
120 CommandLine CmdL;
121 ParseCommandLine(CmdL, APT_CMD::APT_INTERNAL_PLANER, &_config, NULL, argc, argv, &ShowHelp, &GetCommands);
122
123 // Deal with stdout not being a tty
124 if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
125 _config->Set("quiet","1");
126
127 if (_config->FindI("quiet", 0) < 1)
128 _config->Set("Debug::EIPP::WriteSolution", true);
129
130 _config->Set("APT::System", "Debian APT planer interface");
131 _config->Set("APT::Planer", "internal");
132 _config->Set("eipp::scenario", "/nonexistent/stdin");
133 FileFd output;
134 if (output.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
135 DIE("stdout couldn't be opened");
136 int const input = STDIN_FILENO;
137 SetNonBlock(input, false);
138
139 EDSP::WriteProgress(0, "Start up planer…", output);
140
141 if (pkgInitSystem(*_config,_system) == false)
142 DIE("System could not be initialized!");
143
144 EDSP::WriteProgress(1, "Read request…", output);
145
146 if (WaitFd(input, false, 5) == false)
147 DIE("WAIT timed out in the planer");
148
149 std::list<std::pair<std::string,EIPP::PKG_ACTION>> actions;
150 unsigned int flags;
151 if (EIPP::ReadRequest(input, actions, flags) == false)
152 DIE("Parsing the request failed!");
153 _config->Set("APT::Immediate-Configure", (flags & EIPP::Request::NO_IMMEDIATE_CONFIGURATION) == 0);
154 _config->Set("APT::Immediate-Configure-All", (flags & EIPP::Request::IMMEDIATE_CONFIGURATION_ALL) != 0);
155
156 EDSP::WriteProgress(5, "Read scenario…", output);
157
158 pkgCacheFile CacheFile;
159 if (CacheFile.Open(NULL, false) == false)
160 DIE("Failed to open CacheFile!");
161
162 EDSP::WriteProgress(50, "Apply request on scenario…", output);
163
164 if (EIPP::ApplyRequest(actions, CacheFile) == false)
165 DIE("Failed to apply request to depcache!");
166
167 EDSP::WriteProgress(60, "Call orderinstall on current scenario…", output);
168
169 //_config->Set("Debug::pkgOrderList", true);
170 //_config->Set("Debug::pkgPackageManager", true);
171 PMOutput PM(CacheFile, output);
172 if (PM.ApplyRequest(actions) == false)
173 DIE("Failed to apply request to packagemanager!");
174 pkgPackageManager::OrderResult const Res = PM.DoInstallPreFork();
175 switch (Res)
176 {
177 case pkgPackageManager::Completed:
178 EDSP::WriteProgress(100, "Done", output);
179 break;
180 case pkgPackageManager::Incomplete:
181 EDSP::WriteError("pm-incomplete", "Planer could only plan Incompletely", output);
182 case pkgPackageManager::Failed:
183 EDSP::WriteError("pm-failed", "Planer failed to find an order", output);
184 break;
185 }
186
187 return DispatchCommandLine(CmdL, {});
188}
189 /*}}}*/