Browse code

tdnf: Added skipconflicts and skipobsoletes options

Added skipconflicts and skipobsoletes options to check command
* skipconflicts : This will hide the conflicts problems from the report
* skipobsoletes : This will hide the obsoletes problems from the report

Change-Id: I15895caca1589dcdf7851c54730d6be1d8b30f1f
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/6885
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Keerthana K <keerthanak@vmware.com>
Reviewed-by: Ankit Jain <ankitja@vmware.com>

Ankit Jain authored on 2019/03/15 23:00:57
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,444 @@
0
+From 88c68bd4d5f9649afbc4080dd18784d4f24ad491 Mon Sep 17 00:00:00 2001
1
+From: Ankit Jain <ankitja@vmware.com>
2
+Date: Wed, 6 Mar 2019 01:46:22 +0530
3
+Subject: [PATCH] tdnf: Added options skipconflicts, skipobsoletes to check
4
+ command
5
+
6
+Option Added to check command:
7
+------------------------------
8
+--skipconflicts: "tdnf check --skipconflicts" will hide the
9
+conflict problems from the report and display it.
10
+
11
+--skipobsoletes: "tdnf check --skipobsoletes" will hide the
12
+obsoletes problems from the report and display it
13
+
14
+If both options are given to check command, then it will display
15
+the problems except conflicts and obsoletes problems
16
+
17
+Additional Change:
18
+-----------------
19
+* replaced existing getopt_long call with getopt_long_only
20
+Issue with getopt_long:
21
+----------------------
22
+** "tdnf check --sk" , it will parse --sk as --skipconflicts
23
+*** --skip also it will parse as --skipconflicts as it occurs first in list
24
+
25
+Fix with getopt_long_only:
26
+-------------------------
27
+** "tdnf check --skip" will give command error
28
+*** --skipc will parse as --skipconflicts
29
+*** --skipo will parse as --skipobsoletes
30
+
31
+To differentiate between --skipconflicts and --skipobsoletes
32
+replaced getopt_long with getopt_long_only
33
+
34
+Testing:
35
+-------
36
+1) Added check.at under tests directory for "make check"
37
+2) Executed TDNF tests to verify the changes
38
+3) Executed PMD tests to verify the chnages
39
+
40
+Change-Id: I8055d0ea3de6d46f80b7d6c8144f2637413ae917
41
+---
42
+ client/api.c              | 70 ++++++++++++++++++++++++++++++++++++++++++++++-
43
+ client/goal.c             |  4 ++-
44
+ client/prototypes.h       |  6 ++++
45
+ include/tdnftypes.h       |  8 ++++++
46
+ solv/prototypes.h         |  3 +-
47
+ solv/tdnfpackage.c        | 66 ++++++++++++++++++++++++++++++++++++++++----
48
+ tests/check.at            | 53 +++++++++++++++++++++++++++++++++++
49
+ tests/testsuite.at        |  1 +
50
+ tools/cli/lib/parseargs.c | 22 ++++++++++++++-
51
+ 9 files changed, 223 insertions(+), 10 deletions(-)
52
+ create mode 100644 tests/check.at
53
+
54
+diff --git a/client/api.c b/client/api.c
55
+index 6b06232..11c6c6a 100644
56
+--- a/client/api.c
57
+@@ -168,6 +168,71 @@ error:
58
+     goto cleanup;
59
+ }
60
+ 
61
++/**
62
++ * Use case : tdnf check --skipconflicts --skipobsoletes
63
++ *            tdnf check --skipconflicts
64
++ *            tdnf check --skipobsoletes
65
++ *            tdnf check
66
++ * Description: This will verify if "tdnf check" command
67
++ *              is given with --skipconflicts or --skipobsoletes
68
++ *              or with both option, then set the problem type
69
++ *              variable accordingly.
70
++ * Arguments:
71
++ *     pTdnf: Handler for TDNF command
72
++ *     pdwSkipProblem: enum value which tells which kind of problem is set
73
++ *
74
++ * Return:
75
++ *         0 : if success
76
++ *         non zero: if error occurs
77
++ *
78
++ */
79
++uint32_t
80
++TDNFGetSkipProblemOption(
81
++    PTDNF pTdnf,
82
++    TDNF_SKIPPROBLEM_TYPE *pdwSkipProblem
83
++    )
84
++{
85
++    uint32_t dwError = 0;
86
++    PTDNF_CMD_OPT pSetOpt = NULL;
87
++    TDNF_SKIPPROBLEM_TYPE dwSkipProblem = SKIPPROBLEM_NONE;
88
++
89
++    if(!pTdnf || !pTdnf->pArgs || !pdwSkipProblem)
90
++    {
91
++        dwError = ERROR_TDNF_INVALID_PARAMETER;
92
++        BAIL_ON_TDNF_ERROR(dwError);
93
++    }
94
++
95
++    if (!strcasecmp(pTdnf->pArgs->ppszCmds[0], "check"))
96
++    {
97
++      pSetOpt = pTdnf->pArgs->pSetOpt;
98
++
99
++      while(pSetOpt)
100
++      {
101
++          if(pSetOpt->nType == CMDOPT_KEYVALUE &&
102
++            !strcasecmp(pSetOpt->pszOptName, "skipconflicts"))
103
++          {
104
++              dwSkipProblem |= SKIPPROBLEM_CONFLICTS;
105
++          }
106
++          if(pSetOpt->nType == CMDOPT_KEYVALUE &&
107
++           !strcasecmp(pSetOpt->pszOptName, "skipobsoletes"))
108
++          {
109
++             dwSkipProblem |= SKIPPROBLEM_OBSOLETES;
110
++          }
111
++          pSetOpt = pSetOpt->pNext;
112
++      }
113
++    }
114
++    *pdwSkipProblem = dwSkipProblem;
115
++cleanup:
116
++    return dwError;
117
++
118
++error:
119
++    if(pdwSkipProblem)
120
++    {
121
++       *pdwSkipProblem = SKIPPROBLEM_NONE;
122
++    }
123
++    goto cleanup;
124
++}
125
++
126
+ //check a local rpm folder for dependency issues.
127
+ uint32_t
128
+ TDNFCheckLocalPackages(
129
+@@ -187,6 +252,7 @@ TDNFCheckLocalPackages(
130
+     int nLen = 0;
131
+     int nLenRpmExt = 0;
132
+     Pool *pCmdLinePool = NULL;
133
++    TDNF_SKIPPROBLEM_TYPE dwSkipProblem = SKIPPROBLEM_NONE;
134
+ 
135
+     if(!pTdnf || !pTdnf->pSack || !pTdnf->pSack->pPool || !pszLocalPath)
136
+     {
137
+@@ -261,7 +327,9 @@ TDNFCheckLocalPackages(
138
+ 
139
+     if (solver_solve(pSolv, &queueJobs) != 0)
140
+     {
141
+-        dwError = SolvReportProblems(pSolv);
142
++        dwError = TDNFGetSkipProblemOption(pTdnf, &dwSkipProblem);
143
++        BAIL_ON_TDNF_ERROR(dwError);
144
++        dwError = SolvReportProblems(pSolv, dwSkipProblem);
145
+         BAIL_ON_TDNF_ERROR(dwError);
146
+ 
147
+         //Fail the check
148
+diff --git a/client/goal.c b/client/goal.c
149
+index 5e0930d..0f36e0b 100644
150
+--- a/client/goal.c
151
+@@ -305,6 +305,7 @@ TDNFGoal(
152
+     uint32_t dwError = 0;
153
+ 
154
+     PTDNF_SOLVED_PKG_INFO pInfoTemp = NULL;
155
++    TDNF_SKIPPROBLEM_TYPE dwSkipProblem = SKIPPROBLEM_NONE;
156
+     Solver *pSolv = NULL;
157
+     Transaction *pTrans = NULL;
158
+     Queue queueJobs = {0};
159
+@@ -433,7 +434,8 @@ cleanup:
160
+ error:
161
+     if(nProblems > 0 && pSolv)
162
+     {
163
+-       SolvReportProblems(pSolv);
164
++       TDNFGetSkipProblemOption(pTdnf, &dwSkipProblem);
165
++       SolvReportProblems(pSolv, dwSkipProblem);
166
+     }
167
+     TDNF_SAFE_FREE_MEMORY(pInfoTemp);
168
+     if(ppInfo)
169
+diff --git a/client/prototypes.h b/client/prototypes.h
170
+index 7bfb714..23b378e 100644
171
+--- a/client/prototypes.h
172
+@@ -853,3 +853,9 @@ TDNFValidateCmdArgs(
173
+ uint32_t
174
+ TDNFIsInitialized(
175
+     );
176
++
177
++uint32_t
178
++TDNFGetSkipProblemOption(
179
++    PTDNF pTdnf,
180
++    TDNF_SKIPPROBLEM_TYPE *pdwSkipProblem
181
++    );
182
+diff --git a/include/tdnftypes.h b/include/tdnftypes.h
183
+index f2fbdb5..d384f1c 100644
184
+--- a/include/tdnftypes.h
185
+@@ -136,6 +136,14 @@ typedef enum
186
+     CMDOPT_DISABLEREPO
187
+ }TDNF_CMDOPT_TYPE;
188
+ 
189
++// skip problem type
190
++typedef enum
191
++{
192
++    SKIPPROBLEM_NONE=0,
193
++    SKIPPROBLEM_CONFLICTS,
194
++    SKIPPROBLEM_OBSOLETES
195
++}TDNF_SKIPPROBLEM_TYPE;
196
++
197
+ typedef struct _TDNF_ *PTDNF;
198
+ 
199
+ typedef struct _TDNF_PKG_INFO
200
+diff --git a/solv/prototypes.h b/solv/prototypes.h
201
+index 2484649..f262b0b 100644
202
+--- a/solv/prototypes.h
203
+@@ -459,7 +459,8 @@ SolvLoadRepomdUpdateinfo(
204
+ 
205
+ uint32_t
206
+ SolvReportProblems(
207
+-    Solver* pSolv
208
++    Solver* pSolv,
209
++    TDNF_SKIPPROBLEM_TYPE dwSkipProblem
210
+     );
211
+ 
212
+ uint32_t
213
+diff --git a/solv/tdnfpackage.c b/solv/tdnfpackage.c
214
+index 9631cde..012196c 100644
215
+--- a/solv/tdnfpackage.c
216
+@@ -1507,15 +1507,45 @@ error:
217
+     goto cleanup;
218
+ }
219
+ 
220
++/**
221
++ * Description: This function should check problem type and
222
++ *              skipProblemType if both matches then return true
223
++ *              else return false
224
++ * Arguments:
225
++ *        SolverRuleinfo : Solver problem type
226
++ *        TDNF_SKIPPROBLEM_TYPE: user specified problem type
227
++ * Return:
228
++ *      1 : if solver problem type and user specified problem matches
229
++ *      0 : if not matches
230
++ */
231
++static uint32_t
232
++__should_skip(
233
++    SolverRuleinfo type,
234
++    TDNF_SKIPPROBLEM_TYPE dwSkipProblem
235
++    )
236
++{
237
++    uint32_t dwResult = 0;
238
++    if (((dwSkipProblem == SKIPPROBLEM_CONFLICTS) && (type == SOLVER_RULE_PKG_CONFLICTS)) ||
239
++        ((dwSkipProblem == SKIPPROBLEM_OBSOLETES) && (type == SOLVER_RULE_PKG_OBSOLETES)) ||
240
++        ((dwSkipProblem == (SKIPPROBLEM_CONFLICTS | SKIPPROBLEM_OBSOLETES)) && ((type == SOLVER_RULE_PKG_OBSOLETES) || (type == SOLVER_RULE_PKG_CONFLICTS))))
241
++    {
242
++        dwResult = 1;
243
++    }
244
++    return dwResult;
245
++}
246
++
247
+ uint32_t
248
+ SolvReportProblems(
249
+-    Solver* pSolv
250
++    Solver* pSolv,
251
++    TDNF_SKIPPROBLEM_TYPE dwSkipProblem
252
+     )
253
+ {
254
+     uint32_t dwError = 0;
255
++    uint32_t dwSkipProbCount = 0;
256
+     int i = 0;
257
++    int j = 0;
258
+     int nCount = 0;
259
+-    Id dwProbrlemId = 0;
260
++    Id dwProblemId = 0;
261
+     Id dwSource = 0;
262
+     Id dwTarget = 0;
263
+     Id dwDep = 0;
264
+@@ -1530,18 +1560,42 @@ SolvReportProblems(
265
+     }
266
+ 
267
+     nCount = solver_problem_count(pSolv);
268
++    /**
269
++     * Below condition check is added to count the number of skip problems
270
++     * */
271
++    if((nCount > 0) && (dwSkipProblem != SKIPPROBLEM_NONE))
272
++    {
273
++        for( i = 1; i <= nCount; ++i)
274
++        {
275
++            dwProblemId = solver_findproblemrule(pSolv, i);
276
++            type = solver_ruleinfo(
277
++                       pSolv,
278
++                       dwProblemId,
279
++                       &dwSource,&dwTarget,
280
++                       &dwDep);
281
++            if (__should_skip(type, dwSkipProblem))
282
++            {
283
++                dwSkipProbCount++;
284
++            }
285
++        }
286
++    }
287
++
288
+     if(nCount > 0)
289
+     {
290
+-        fprintf(stderr, "Found %d problem(s) while resolving\n", nCount);
291
++        fprintf(stderr, "Found %d problem(s) while resolving\n", nCount - dwSkipProbCount);
292
+         for( i = 1; i <= nCount; ++i)
293
+         {
294
+-            dwProbrlemId = solver_findproblemrule(pSolv, i);
295
++            dwProblemId = solver_findproblemrule(pSolv, i);
296
+             type = solver_ruleinfo(
297
+                        pSolv,
298
+-                       dwProbrlemId,
299
++                       dwProblemId,
300
+                        &dwSource,&dwTarget,
301
+                        &dwDep);
302
+ 
303
++            if (__should_skip(type, dwSkipProblem))
304
++            {
305
++                continue;
306
++            }
307
+             pszProblem = solver_problemruleinfo2str(
308
+                              pSolv,
309
+                              type,
310
+@@ -1549,7 +1603,7 @@ SolvReportProblems(
311
+                              dwTarget,
312
+                              dwDep);
313
+ 
314
+-            fprintf(stderr, "%d. %s\n", i, pszProblem);
315
++            fprintf(stderr, "%d. %s\n", ++j, pszProblem);
316
+             pszProblem = NULL;
317
+         }
318
+     }
319
+diff --git a/tests/check.at b/tests/check.at
320
+new file mode 100644
321
+index 0000000..17b54dd
322
+--- /dev/null
323
+@@ -0,0 +1,53 @@
324
++#
325
++# Copyright (C) 2015 VMware, Inc. All Rights Reserved.
326
++#
327
++# Licensed under the GNU Lesser General Public License v2.1 (the "License");
328
++# you may not use this file except in compliance with the License. The terms
329
++# of the License are located in the COPYING file of this distribution.
330
++#
331
++
332
++AT_BANNER(tdnf check tests)
333
++
334
++# Test tdnf check commands
335
++AT_SETUP([check])
336
++AT_KEYWORDS([check])
337
++AT_CHECK([
338
++TDNF_CHROOT_CLEAN
339
++TDNF_CHROOT_INIT
340
++TDNF_BUILD_INSTALL_RPMS
341
++TDNF_CLI_W_CHROOT check
342
++],
343
++[0],
344
++[ignore],
345
++[ignore])
346
++AT_CLEANUP
347
++
348
++AT_SETUP([check skipconflicts])
349
++AT_KEYWORDS([check])
350
++AT_CHECK([
351
++TDNF_CLI_W_CHROOT check --skipconflicts
352
++],
353
++[0],
354
++[ignore],
355
++[ignore])
356
++AT_CLEANUP
357
++
358
++AT_SETUP([check skipobsoletes])
359
++AT_KEYWORDS([check])
360
++AT_CHECK([
361
++TDNF_CLI_W_CHROOT check --skipobsoletes
362
++],
363
++[0],
364
++[ignore],
365
++[ignore])
366
++AT_CLEANUP
367
++
368
++AT_SETUP([check skipconflicts skipobsoletes])
369
++AT_KEYWORDS([check])
370
++AT_CHECK([
371
++TDNF_CLI_W_CHROOT check --skipconflicts --skipobsoletes
372
++],
373
++[0],
374
++[ignore],
375
++[ignore])
376
++AT_CLEANUP
377
+diff --git a/tests/testsuite.at b/tests/testsuite.at
378
+index 7c929d1..7a38d67 100644
379
+--- a/tests/testsuite.at
380
+@@ -15,4 +15,5 @@ m4_include([update.at])
381
+ m4_include([downgrade.at])
382
+ m4_include([whatprovides.at])
383
+ m4_include([check-local.at])
384
++m4_include([check.at])
385
+ m4_include([updateinfo.at])
386
+diff --git a/tools/cli/lib/parseargs.c b/tools/cli/lib/parseargs.c
387
+index 24311b1..c9f353d 100644
388
+--- a/tools/cli/lib/parseargs.c
389
+@@ -54,6 +54,8 @@ static struct option pstOptions[] =
390
+     {"security",      no_argument, 0, 0},                  //--security
391
+     {"sec-severity",  required_argument, 0, 0},            //--sec-severity
392
+     {"reboot-required", no_argument, 0, 0},                //--reboot-required
393
++    {"skipconflicts", no_argument, 0, 0},                  //--skipconflicts to skip conflict problems
394
++    {"skipobsoletes", no_argument, 0, 0},                  //--skipobsoletes to skip obsolete problems
395
+     {0, 0, 0, 0}
396
+ };
397
+ 
398
+@@ -87,7 +89,7 @@ TDNFCliParseArgs(
399
+     while (1)
400
+     {
401
+ 
402
+-            nOption = getopt_long (
403
++            nOption = getopt_long_only (
404
+                           argc,
405
+                           argv,
406
+                           "46bCc:d:e:hi:qvxy",
407
+@@ -351,6 +353,24 @@ ParseOption(
408
+                       &pCmdArgs->pszReleaseVer);
409
+         BAIL_ON_CLI_ERROR(dwError);
410
+     }
411
++    else if(!strcasecmp(pszName, "skipconflicts"))
412
++    {
413
++        dwError = AddSetOptWithValues(
414
++                      pCmdArgs,
415
++                      CMDOPT_KEYVALUE,
416
++                      pszName,
417
++                      "1");
418
++        BAIL_ON_CLI_ERROR(dwError);
419
++    }
420
++    else if(!strcasecmp(pszName, "skipobsoletes"))
421
++    {
422
++        dwError = AddSetOptWithValues(
423
++                      pCmdArgs,
424
++                      CMDOPT_KEYVALUE,
425
++                      pszName,
426
++                      "1");
427
++        BAIL_ON_CLI_ERROR(dwError);
428
++    }
429
+     else if(!strcasecmp(pszName, "setopt"))
430
+     {
431
+         if(!optarg)
432
+-- 
433
+2.7.4
434
+
... ...
@@ -4,7 +4,7 @@
4 4
 Summary:        dnf/yum equivalent using C libs
5 5
 Name:           tdnf
6 6
 Version:        2.0.0
7
-Release:        9%{?dist}
7
+Release:        10%{?dist}
8 8
 Vendor:         VMware, Inc.
9 9
 Distribution:   Photon
10 10
 License:        LGPLv2.1,GPLv2
... ...
@@ -41,6 +41,7 @@ Patch5:         tdnf-fix-curl-status-type.patch
41 41
 Patch6:         tdnf-fix-error-no-repo.patch
42 42
 Patch7:         tdnf-refresh-mkcache.patch
43 43
 Patch8:         tdnf-fix-gpgcheck.patch
44
+Patch9:         tdnf-added-skip-options-to-check.patch
44 45
 
45 46
 %description
46 47
 tdnf is a yum/dnf equivalent which uses libsolv and libcurl
... ...
@@ -72,6 +73,7 @@ Library providing cli libs for tdnf like clients.
72 72
 %patch6 -p1
73 73
 %patch7 -p1
74 74
 %patch8 -p1
75
+%patch9 -p1
75 76
 
76 77
 %build
77 78
 autoreconf -i
... ...
@@ -172,6 +174,8 @@ systemctl try-restart tdnf-cache-updateinfo.timer >/dev/null 2>&1 || :
172 172
     %{_libdir}/libtdnfcli.so.*
173 173
 
174 174
 %changelog
175
+*   Fri Mar 15 2019 Ankit Jain <ankitja@vmware.com> 2.0.0-10
176
+-   Added skipconflicts and skipobsoletes to check command.
175 177
 *   Thu Mar 14 2019 Keerthana K <keerthanak@vmware.com> 2.0.0-9
176 178
 -   GPGCheck fix on RPM version 4.14.2
177 179
 *   Mon Mar 04 2019 Keerthana K <keerthanak@vmware.com> 2.0.0-8