[apparmor] [utils] proposed redesign for mergeprof
Kshitij Gupta
kgupta8592 at gmail.com
Thu Sep 4 21:02:04 UTC 2014
Hello,
Seems I sent out that patch a bit early, a secondary consolidated
patch which fixes (hopefully) the issue multiple profiles in a file is
attached.
(Brace a for loop is removed resulting in a huge diff due to the indent change).
Note: I've allowed the debug messages to be there for the sake of clarity.
Regards,
Kshitij Gupta
On Fri, Sep 5, 2014 at 12:19 AM, Kshitij Gupta <kgupta8592 at gmail.com> wrote:
> Hello,
>
> Version -1:
>
> Changes to facilitate 2-way merge (maybe also 3-way) of multiple
> profiles as discussed on IRC ( which someone had to summarize for ml
> ;-))
>
> The proposal:
> - moves reset method to reset_aa function
> - modifies message displayed to user
> - allows processing of multiple files in 2-way merge
> - disables 3-way merge till new syntax has been decided
>
> The changes reflect the approach of providing arbitrary number of
> files using wildcards or explicitly. This makes it necessary to define
> a way to distinguish the files for base and other case to be used in
> 3-way merge.
> @cboltz Any ideas are welcome!
>
> The changes map the profiles in the given files to their respective
> files in the local directory specified using -d. Then the merges take
> place profile-wise. There are some cases with this approach with
> multiple profiles in a file where unnecessary questions are asked not
> relevant to the other profile.
>
> === modified file 'utils/aa-mergeprof'
> --- utils/aa-mergeprof 2014-09-03 23:49:47 +0000
> +++ utils/aa-mergeprof 2014-09-04 18:33:34 +0000
> @@ -26,19 +26,19 @@
> from apparmor.translations import init_translation
> _ = init_translation()
>
> -parser = argparse.ArgumentParser(description=_('Perform a 2-way or
> 3-way merge on the given profiles'),
> +parser = argparse.ArgumentParser(description=_('Perform a 2-way or
> 3-way merge on the given profiles'),
> epilog='WARNING: the arguments will change in a future version!')
> -parser.add_argument('mine', type=str, help=_('your profile'))
> -parser.add_argument('base', type=str, help=_('base profile'))
> -parser.add_argument('other', nargs='?', type=str, help=_('other profile'))
> +parser.add_argument('files', nargs='+', type=str, help=_('base 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()
>
> +args.other = None
> # 2-way merge or 3-way merge based on number of params
> -merge_mode = 2 if args.other == None else 3
> +merge_mode = 2 #if args.other == None else 3
>
> -profiles = [args.mine, args.base, args.other]
> +profiles = [args.files, [args.other]]
>
> profiledir = args.dir
> if profiledir:
> @@ -46,9 +46,78 @@
> if not os.path.isdir(apparmor.aa.profile_dir):
> raise apparmor.AppArmorException(_("%s is not a directory.")
> %profiledir)
>
> +def reset_aa():
> + apparmor.aa.aa = apparmor.aa.hasher()
> + apparmor.aa.filelist = apparmor.aa.hasher()
> + apparmor.aa.include = dict()
> + apparmor.aa.existing_profiles = apparmor.aa.hasher()
> + apparmor.aa.original_aa = apparmor.aa.hasher()
> +
> +def find_profiles_from_files(files):
> + profile_to_filename = dict()
> + for file_name in files:
> + apparmor.aa.read_profile(file_name, True)
> + for profile_name in apparmor.aa.filelist[file_name]['profiles'].keys():
> + profile_to_filename[profile_name] = file_name
> + reset_aa()
> +
> + return profile_to_filename
> +
> +def find_files_from_profiles(profiles):
> + profile_to_filename = dict()
> + apparmor.aa.read_profiles()
> +
> + for profile_name in profiles:
> + profile_to_filename[profile_name] =
> apparmor.aa.get_profile_filename(profile_name)
> +
> + reset_aa()
> +
> + return profile_to_filename
>
> def main():
> - mergeprofiles = Merge(profiles)
> + profiles_to_merge = set()
> +
> + base_files, other_files = profiles
> +
> + base_profile_to_file = find_profiles_from_files(base_files)
> +
> + profiles_to_merge =
> profiles_to_merge.union(set(base_profile_to_file.keys()))
> +
> + other_profile_to_file = dict()
> +
> + if merge_mode == 3:
> + other_profile_to_file = find_profiles_from_files(other_files)
> + profiles_to_merge.add(other_profile_to_file.keys())
> +
> + user_profile_to_file = find_files_from_profiles(profiles_to_merge)
> +
> + print(base_files,"\n",other_files)
> + print(base_profile_to_file,"\n",other_profile_to_file,"\n",user_profile_to_file)
> + print(profiles_to_merge)
> +
> + for profile_name in profiles_to_merge:
> + user_file = user_profile_to_file[profile_name]
> + base_file = base_profile_to_file.get(profile_name, None)
> + other_file = None
> +
> + if merge_mode == 3:
> + other_file = other_profile_to_file.get(profile_name, None)
> +
> + if base_file == None:
> + if other_file == None:
> + continue
> +
> + act([user_file, other_file, None], 2, profile_name)
> + else:
> + if other_file == None:
> + act([user_file, base_file, None], 2, profile_name)
> + else:
> + act([user_file, base_file, other_file], 3, profile_name)
> +
> + reset_aa()
> +
> +def act(files, merge_mode, merging_profile):
> + mergeprofiles = Merge(files)
> #Get rid of common/superfluous stuff
> mergeprofiles.clear_common()
>
> @@ -62,10 +131,10 @@
> mergeprofiles.ask_the_questions('base')
>
> q = apparmor.aa.hasher()
> - q['title'] = 'Changed Local Profiles'
> + q['title'] = _('Changes for Local Profile: %s')%(merging_profile)
> q['headers'] = []
> - q['explanation'] = _('The following local profiles were
> changed. Would you like to save them?')
> - q['functions'] = ['CMD_SAVE_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ABORT']
> + q['explanation'] = _('Would you like to save them?')
> + q['functions'] = ['CMD_SAVE_CHANGES', 'CMD_VIEW_CHANGES',
> 'CMD_ABORT', 'CMD_IGNORE_ENTRY']
> q['default'] = 'CMD_VIEW_CHANGES'
> q['options'] = []
> q['selected'] = 0
> @@ -84,6 +153,8 @@
> #oldprofile =
> apparmor.serialize_profile(apparmor.original_aa[program], program, '')
> newprofile =
> apparmor.aa.serialize_profile(mergeprofiles.user.aa[program], program,
> '')
>
> apparmor.aa.display_changes_with_comments(mergeprofiles.user.filename,
> newprofile)
> + elif ans == 'CMD_IGNORE_ENTRY':
> + break
>
>
> class Merge(object):
> @@ -94,25 +165,18 @@
> apparmor.aa.read_profile(base, True)
> self.base = cleanprofile.Prof(base)
>
> - self.reset()
> + reset_aa()
>
> #Read and parse other profile and save profile data, include
> data from it and reset them
> if merge_mode == 3:
> apparmor.aa.read_profile(other, True)
> self.other = cleanprofile.Prof(other)
> - self.reset()
> + reset_aa()
>
> #Read and parse user profile
> apparmor.aa.read_profile(user, True)
> self.user = cleanprofile.Prof(user)
>
> - def reset(self):
> - apparmor.aa.aa = apparmor.aa.hasher()
> - apparmor.aa.filelist = apparmor.aa.hasher()
> - apparmor.aa.include = dict()
> - apparmor.aa.existing_profiles = apparmor.aa.hasher()
> - apparmor.aa.original_aa = apparmor.aa.hasher()
> -
> def clear_common(self):
> deleted = 0
>
>
>
> Regards,
> Kshitij Gupta
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mergeprof2.patch
Type: text/x-patch
Size: 61581 bytes
Desc: not available
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20140905/00608d0c/attachment-0001.bin>
More information about the AppArmor
mailing list