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