Skip to content
Jakub Filak edited this page Sep 18, 2015 · 37 revisions

Revised Problem DBus API

The current DBus API is a C style set of functions but DBus is designed for objective APIs, therefore our API looks inconsistently and is hard to understand. User programmers cannot benefit from DBus binding generators because the API doesn't provide right features like DBus.Properties. The revised DBus API should utilize the best practices used for designing DBus API to provide natural and easy to use API.

Notes: https://github.com/abrt/abrt/issues/551

Development branch: https://github.com/abrt/abrt/tree/dbus_problems_service_v2

We need to port all abrt/libreport tools to use the D-Bus service to access problem data because we need more subtle access control (e.g. we need to prevent users from access to dmesg while keeping them able to report the problem)

Goals

  1. Get rid of direct file system access
  2. Let root own the problem directories
  3. Prevent regular users from access to some problem elements (var_log_messages, sosreport)
  4. Interpret some data (e.g. if not-reportable element exists the problem cannot be reported)
  • not-reportable -> cannot be reported
  • count -> complete problem
  • remote -> a problem from another machine
  • reported_to -> reported
  1. Enable reporting through D-Bus
  2. Get rid of implicit PolKit actions (GetAllProblems() needs authorization)
  • This goal requires to implement some session mechanism

Policy

  1. Avoid too many D-Bus round trips (use SIMD approach).
  2. Define the API extendable (return/accept the dictionary of variables).
  3. Do not force users to parse data.

Current API Consumers

abrt-applet * GetProblems() * GetInfo()

  • time
  • reported_to
  • uid
  • uuid
  • duphash
  • component
  • package
  • count
  • not-reportable
  • cmdline
  • environ (for GIO_LAUNCHED_DESKTOP_FILE and GIO_LAUNCHED_DESKTOP_FILE_PID)
  • pid
  • Crash

gnome-abrt * GetProblems() * GetForeignProblems() * GetInfo()

  • component
  • executable
  • cmdline
  • count
  • type
  • last_occurrence
  • time
  • reason
  • pkg_arch
  • pkg_epoch
  • pkg_name
  • pkg_release
  • pkg_version
  • environ (for GIO_LAUNCHED_DESKTOP_FILE and GIO_LAUNCHED_DESKTOP_FILE_PID)
  • pid
  • reported_to
  • GetProblemData()
  • ChownProblemDir()
  • DeleteProblem()

abrt-cli * GetProblems() * GetProblemData() * TestElementExists()

The DML API

org.freedesktop.Problems
  • method GetProblems() - The selectors are not needed - users should get all problem they can see (2015-04-27) - returns a list of org.freedesktop.Problems.Entry object paths - selector : list of tuples (Type, Variant) - we are not sure but we have to provide these selectors:

    • My : only current users problems
    • Others : all problems except my (or all problems without any exception)
    • UID = $NUMBER : (this could be achieved in different way -> on clients side, because we are going to drop support for methods such FindProblemByElementInTimeRange())
    • ONLY Complete
    • ONLY Reportable
    • message : a message describing the returned list, provides and explanation why the user see only the limited list of problems when autorization fails
  • method GetProblemData() - IN o - OUT a{s(sits)}} - returns the problem data for a single problem

  • method DeleteProblems($problem_object_path)

  • signal NewProblemDetected or keep the current name Crash - needs to have these arguments in case where all data members are accessible only to the problem owner and super user

    • ID
    • owner
    • component (2015-03-16 : unnecessary argument)
    • uuid : for the ignored problems feature (2015-03-16 : unnecessary argument)
    • duphash : for ignored problems feature (2015-03-16 : unnecessary argument)
    • Note: Crash signal works fine
org.freedesktop.Problems.Entry
  • implements org.freedesktop.DBus.Properties and provides these properties:

    id

    problem ID (file system path)

    uid

    some of the information may be accessible only to the owner or an administrator. (2015-03-16 only the owner and administrators have access to crash data)

    username

    translated uid

    type

    CCpp, Python, Kerneloops, Java, Ruby

    detected (UNIX timestamp)

    the first occurrence of the problem

    last_occurrence (UNIX timestamp)

    the last occurrence

    count

    a number of occurrences

    executable

    a file system path to affected/involved executable

    command_line_arguments

    command line arguments

    component

    package name for executable

    package

    sssss - full name, epoch, name, version, release

    uuid

    problem uuid

    duphash

    problem duphash

    reports

    a(sa{sv}) Title : { (URL,MSG,BTHASH) : string }

    resolution

    (not-reportable) - Tainted kernel, invalid path

    reason

    killed by signal, uncaught exception, ...

    backtrace

    almost all problems have backtrace

    comment

    user text

    is_remote

    true if the proble directory was processed by abrt-handle-upload

    is_reported

    this is not trivial because there might be many reports such as ABRT server or DUPHASH

    is_reportable

    this also depends on a type of the reporter (a user can report the problem via mailx or logger but cannot report the problem to Bugzilla)

    desktop_file

    the desktop file used to launch the application

    elements

    list of all element names

  • method ReadElements(in array of strings, in flags, out array of Variants)

  • method SaveElements(in dictionary of string:Variant entries)

  • method RemoveElements(in array of strings)

  • signal Changed - what happened - deleted, changed owner, changed data

Usage examples

abrt-applet: .. code:

create a proxy and populate the properties
popup the notificiation

abrt-cli list: .. code:

GetProblems()
    for each problem GetProblemData()
    print problem data

abrt-cli status: .. code:

GetProblems()
    for each problem create a proxy and populate the properties
        if not p.is_reported and p.last_occurrence lower than required minimum
            increment counter

abrt-retrace-client .. code:

for the given problem id create a proxy and NOT populate the properties
    p.GetTextElements(["os_info"]) -> ["os_info":"ID=fedora\nID_LIKE=fedora\n"]
    p.OpenElements(["coredump"]) -> ["coredump":fd]
    p.SaveTextElements(["backtrace":"free()", "vulnerability":"..."])

gnome-abrt view: .. code:

GetProblems()
    for each problem create a proxy and populate the properties and show the data

gnome-abrt Details: .. code:

Details -> GetProblemData()

gnome-abrt Delete: .. code:

Delete -> DeleteProblems(["p1", "p2"])

report-gtk .. code:

for the given problem id create a proxy and populate the properties
    show the initial screen
    p.SaveTextElements(["comment":"I'm a comment"])
    p.SaveElements(["screenshot1":fd1, "screencast1":fd2])
    GetProblemData() for the secrete information review

reproter-bugzilla .. code:

GetProblemData() for the given problem id (filter out elements from EXCLUDED_ELEMENTS env variable)
OpenElements() for the binary elements if configured
report the problem data

reporter-uploader .. code:

create a proxy for the given problem id
p.OpenElements([all elements]) -> [file descriptors]
create an archive and upload it

The API for Reporting

We can either wrap the entire reporting process in D-Bus calls, so we would need to wrap the Client API and few more things. In this scenario abrt-dbus runs libreport's reporters with root permissions, so there might be a security issue (any package can install an event definition file recognized by libreport and used to run custom scripts) which can be resolved by setting UID to caller's uid but this would prevent the reporters from direct file system access which we need for collect_* events. Or we can run the reporters in reporter's context and provide only the "Access" d-Bus API, but we run into the file system issue again.

The former scenario without using caller's uid has the opposite file system issue. The collect_* events need to be run in caller's context because those event scripts might want to make copies of configuration files from caller's home: https://github.com/abrt/abrt/blob/master/src/plugins/vimrc_event.conf

Lack of $HOME can be easily overcome by the following shell line

HOME=$(getent passwd "`cat uid`" | cut -d: -f6)

but some files system configurations don't allow root to access files in user's home.

The latter scenario is more secure but then we probably need two D-Bus services because of Cockpit where we have to enable problems reporting from a Javascript based web application. Hence, we need the actual D-Bus API providing data and sitting on 'System' bus and the new Reporting API opening Bugzilla bugs and sitting on 'Session' bus. However this scenario doesn't resolve the file system issue for collect_* events. These events are regular shell scripts using cp and redirecting of stdout to files in the problem directory. We need either to retain direct file system access or develop a command line helper which would mitigate the pain of not having the direct file system access.

Reporting API Reference

org.freedesktop.problems
Methods
  • PossibleWorkflows(problem_id) - returns a list of (wf_id, summary, description)
  • InitializeReporting(problem_id, wf_id) -> org.freedesktop.problems.ReportClient
org.freedesktop.problems.ReportClient
Methods
  • Run()
  • Terminate()
Properties
  • Events
  • SelectedEvent property -> org.freedesktop.problems.ReportEvent
  • ExcludedElements property
Signals
  • Prompt(message, Prompt path, int prompt_flags)
  • Alert(message)
  • Progress(message)
  • Finished(type = {event | process})
org.freedesktop.problems.Prompt
Properties
  • Flags (ASK, AKS_YES_NO, ASK_PASSWORD, ...)
Methods
  • Dismiss()
  • Reply(variant)
org.freedesktop.problems.ReportEvent
Properties
  • Name
  • DisplayName
  • RequiresItems
  • ExcludeItemsByDefault
  • IncludeItemsByDefault
  • ExcludeItemsAlways
  • ExcludeBinaryItems
  • MinimalRating
  • ReviewElements
  • Configuration
org.freedesktop.problems.ReportEventConfig
Properties
  • Name
  • Description

How to enable the Reporting API users to pass user's configuration to the reporting client.

Property "reports":

libreports 'repoted_to' contains known reports of a problem. Every report is stored in a form of a single line. Every 'reported_to' line is prefixed with "label" followed ":". We will use term 'title' instead of 'label. libreport recognizes three value types on lines of 'reported_to' element: 1. text message 2. URL (Bugzilla, e-mail, upload, RHSupport) 3. BTHASH (uReport)

One might presume the list will grow in the future with the growing number of report types and supported bug trackers. Hence the API should not have hard-coded types and should be able to easily start supporting new 'reported_to' types. This goal is in D-Bus APIs achieved by using dictionaries with the value of the type Variant and a string key (a{sv}).

Know keys:
  • MSG - a text description of the report
  • URL - an URL to the report
  • BTHASH - a global uReport identifier

The final type of the property 'reports' would be "a(sa{sv})".

Example:

file "reported_to":
Bugzilla: URL=https://bugzill.example.com/1000000 Bugzilla: URL=https://bugzill.example.com/1234567 email: URL=mailto://bugs@example-project.org ABRT Server: BTHASH=DEADBEFF81680083 RHTSupport: URL=https://support.corp.com/ticket=12345 MSG=New customer case 12345
property "reports":
[
( "Bugzilla",
{ "URL" : "https://bugzill.example.com/1000000" }

), ( "Bugzilla",

{ "URL" : "https://bugzill.example.com/1234567" },

), ( "email",

{ "URL" : "mailto://bugs@example-project.org" }

), ( "ABRT Server",

{ "BTHASH" : "DEADBEFF81680083" },

), ( "RHTSupport",

{ "URL" : "https://support.corp.com/ticket=12345",
"MSG" : "New customer case 12345" }

)

]

Note: We will not convert the format of reported_to to JSON and use it for storing solutions, because the solutions will have own element and the file reported_to is just a list of reports and should not be overloaded.

Clone this wiki locally