Hello,

As cboltz suggested it'd be nice to have a 2-way merge feature in
aa-mergeprof. Here's the patch that does the same.

This patch modifies aa-mergeprof to:
-allow users to merge two profiles (2-way merge) using aa-mergeprof by
making the third profile optional
-re-enable code that cleaned up base and other profile and using it in
deleted count (was disabled due to pyflakes thinking it was unused)

Testing: Some basic comparative testing between the 3-way merge hack
(as used by cboltz) and the new 2-way merge.

To-Do: Add some tests for aa-mergeprof

=== modified file 'utils/aa-mergeprof'
--- utils/aa-mergeprof    2014-07-27 22:24:26 +0000
+++ utils/aa-mergeprof    2014-07-28 10:17:46 +0000
@@ -25,26 +25,31 @@
 from apparmor.translations import init_translation
 _ = init_translation()

-parser = argparse.ArgumentParser(description=_('Perform a 3way merge
on the given profiles'))
+parser = argparse.ArgumentParser(description=_('Perform a 2-way or
3-way merge on the given profiles'))
 parser.add_argument('mine', type=str, help=_('your profile'))
 parser.add_argument('base', type=str, help=_('base profile'))
-parser.add_argument('other', type=str, help=_('other profile'))
+parser.add_argument('other', nargs='?', type=str, help=_('other profile'))
 parser.add_argument('-d', '--dir', type=str, help=_('path to profiles'))
 parser.add_argument('-a', '--auto', action='store_true',
help=_('Automatically merge profiles, exits incase of *x conflicts'))
 args = parser.parse_args()

+# 2-way merge or 3-way merge based on number of params
+merge_mode = 2 if args.other == None else 3
+
+print(_('Running tool in %s-way merge mode')%merge_mode)
+
 profiles = [args.mine, args.base, args.other]

-
 def main():
     mergeprofiles = Merge(profiles)
     #Get rid of common/superfluous stuff
     mergeprofiles.clear_common()

     if not args.auto:
-        mergeprofiles.ask_the_questions('other')
+        if merge_mode == 3:
+            mergeprofiles.ask_the_questions('other')

-        mergeprofiles.clear_common()
+            mergeprofiles.clear_common()

         mergeprofiles.ask_the_questions('base')

@@ -84,13 +89,13 @@
         self.reset()

         #Read and parse other profile and save profile data, include
data from it and reset them
-        apparmor.aa.read_profile(other, True)
-        self.other = cleanprofile.Prof(other)
-
-        self.reset()
+        if merge_mode == 3:
+            apparmor.aa.read_profile(other, True)
+            self.other = cleanprofile.Prof(other)
+            self.reset()

         #Read and parse user profile
-        apparmor.aa.read_profile(profiles[0], True)
+        apparmor.aa.read_profile(user, True)
         self.user = cleanprofile.Prof(user)

     def reset(self):
@@ -102,17 +107,20 @@

     def clear_common(self):
         deleted = 0
-        #Remove off the parts in other profile which are
common/superfluous from user profile
-        user_other = cleanprofile.CleanProf(False, self.user, self.other)
-        deleted += user_other.compare_profiles()
+
+        if merge_mode == 3:
+            #Remove off the parts in other profile which are
common/superfluous from user profile
+            user_other = cleanprofile.CleanProf(False, self.user, self.other)
+            deleted += user_other.compare_profiles()

         #Remove off the parts in base profile which are
common/superfluous from user profile
         user_base = cleanprofile.CleanProf(False, self.user, self.base)
         deleted += user_base.compare_profiles()

-        #Remove off the parts in other profile which are
common/superfluous from base profile
-        # base_other = cleanprofile.CleanProf(False, self.base,
self.other)  # XXX base_other not used?
-        deleted += user_base.compare_profiles()
+        if merge_mode == 3:
+            #Remove off the parts in other profile which are
common/superfluous from base profile
+            base_other = cleanprofile.CleanProf(False, self.base, self.other)
+            deleted += base_other.compare_profiles()

     def conflict_mode(self, profile, hat, allow, path, mode,
new_mode, old_mode):
         m = new_mode
@@ -490,7 +498,7 @@
                                     done = True
                                     match = apparmor.aa.re_match_include(path)
                                     if match:
-                                        inc = match
+                                        inc = match
                                         deleted = 0
                                         deleted =
apparmor.aa.delete_duplicates(self.user.aa[profile][hat], inc)

self.user.aa[profile][hat]['include'][inc] =  True
@@ -561,7 +569,7 @@
 #                                                 ynprompt = _('The
specified path does not match this log entry:\n\n  Log Entry: %s\n
Entered Path:  %s\nDo you really want to use this path?') % (path,ans)
 #                                                 key =
aaui.UI_YesNo(ynprompt, 'n')
 #                                                 if key == 'n':
-#                                                     continue
+#                                                     continue
                                         apparmor.aa.user_globs.append(ans)
                                         options.append(ans)
                                         default_option = len(options)

Regards,

Kshitij Gupta

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to