Merge lp:~larryprice/libertine/liblibertine-plus-libertined into lp:libertine

Proposed by Larry Price
Status: Merged
Approved by: Larry Price
Approved revision: 370
Merged at revision: 388
Proposed branch: lp:~larryprice/libertine/liblibertine-plus-libertined
Merge into: lp:libertine
Diff against target: 2613 lines (+717/-723)
49 files modified
CMakeLists.txt (+1/-1)
cmake/FindGObjectIntrospection.cmake (+0/-61)
cmake/ListOperations.cmake (+0/-18)
cmake/UseGObjectIntrospection.cmake (+0/-102)
common/LibertineConfig.cpp (+1/-9)
data/CMakeLists.txt (+1/-1)
data/com.canonical.libertine.Service.service (+1/-1)
debian/changelog (+7/-0)
debian/control (+23/-17)
debian/gir1.2-libertine.install (+0/-2)
debian/libertine-tools.install (+0/-2)
debian/libertined.install (+3/-0)
debian/python3-libertine.install (+0/-1)
debian/rules (+1/-1)
liblibertine/CMakeLists.txt (+3/-30)
liblibertine/libertine.cpp (+20/-164)
liblibertine/libertine.h (+4/-4)
liblibertine/libertined.cpp (+199/-0)
liblibertine/libertined.h (+25/-0)
python/libertine/ChrootContainer.py (+6/-7)
python/libertine/ContainersConfig.py (+9/-0)
python/libertine/Libertine.py (+43/-21)
python/libertine/LxcContainer.py (+4/-5)
python/libertine/LxdContainer.py (+13/-13)
python/libertine/service/apt.py (+2/-6)
python/libertine/service/container.py (+29/-5)
python/libertine/service/manager.py (+8/-1)
python/libertine/service/progress.py (+3/-3)
python/libertine/service/task_dispatcher.py (+8/-5)
python/libertine/service/tasks/__init__.py (+4/-2)
python/libertine/service/tasks/base_task.py (+2/-4)
python/libertine/service/tasks/container_info_task.py (+21/-5)
python/libertine/service/tasks/list_app_ids_task.py (+35/-0)
python/libertine/service/tasks/list_apps_task.py (+8/-4)
python/libertine/service/tasks/list_task.py (+6/-4)
python/libertine/utils.py (+15/-36)
snapcraft.yaml (+13/-1)
tests/integration/test_libertine_service.py (+26/-16)
tests/unit/service/tasks/CMakeLists.txt (+1/-0)
tests/unit/service/tasks/test_container_info_task.py (+14/-2)
tests/unit/service/tasks/test_list_app_ids_task.py (+59/-0)
tests/unit/service/tasks/test_list_task.py (+8/-6)
tests/unit/service/test_apt.py (+37/-45)
tests/unit/service/test_container.py (+36/-42)
tests/unit/service/test_task_dispatcher.py (+14/-7)
tests/unit/test_libertine_container.py (+2/-1)
tests/unit/test_libertine_gir.py (+0/-65)
tools/libertine-container-manager (+1/-2)
tools/libertine-lxc-manager (+1/-1)
To merge this branch: bzr merge lp:~larryprice/libertine/liblibertine-plus-libertined
Reviewer Review Type Date Requested Status
Libertine CI Bot continuous-integration Approve
Christopher Townsend Approve
Review via email: mp+315495@code.launchpad.net

Commit message

Refactor liblibertine as a client wrapper for libertined.

Description of the change

Refactor liblibertine as a client wrapper for libertined.

To post a comment you must log in.
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:361
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/346/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/675
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/552
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/552
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/552
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/552
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/685
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/666
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/666/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/666
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/666/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/666
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/666/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/666
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/666/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/346/rebuild

review: Approve (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:362
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/350/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/682
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/559
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/559
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/559
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/559
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/692
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/673
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/673/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/673
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/673/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/673
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/673/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/673
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/673/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/350/rebuild

review: Approve (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:363
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/351/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/684
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/561
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/561
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/561
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/561
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/694
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/675
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/675/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/675
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/675/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/675
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/675/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/675
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/675/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/351/rebuild

review: Approve (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:364
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/352/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/685
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/562
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/562
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/562
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/562
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/695
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/676
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/676/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/676
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/676/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/676
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/676/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/676
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/676/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/352/rebuild

review: Approve (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:365
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/353/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/686
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/563
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/563
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/563
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/563
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/696
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/677
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/677/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/677
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/677/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/677
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/677/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/677
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/677/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/353/rebuild

review: Approve (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:366
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/354/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/687
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/564
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/564
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/564
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/564
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/697
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/678
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/678/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/678
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/678/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/678
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/678/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/678
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/678/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/354/rebuild

review: Approve (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:366
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/355/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/688
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/565
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/565
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/565
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/565
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/698
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/679
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/679/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/679
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/679/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/679
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/679/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/679
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/679/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/355/rebuild

review: Approve (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:367
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/356/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/689
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/566
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/566
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/566
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/566
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/699
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/680
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/680/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/680
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/680/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/680
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/680/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/680
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/680/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/356/rebuild

review: Approve (continuous-integration)
Revision history for this message
Christopher Townsend (townsend) wrote :

Ok, this looks good. +1

When we land this in the next release, we'll need to get python3-libertine promoted to main and libertined will be in main.

review: Approve
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:369
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/357/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/692
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/567
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/567
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/567
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/567
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/702
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/683
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/683/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/683
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/683/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/683
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/683/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/683
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/683/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/357/rebuild

review: Approve (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
370. By Larry Price

add a try-except to the dbus session var method

Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:370
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/358/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/694
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/568
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=zesty,testname=default/568
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/568
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=zesty,testname=default/568
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/704
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/685
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/685
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=zesty/685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/685
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/685
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=zesty/685/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/358/rebuild

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2017-01-13 20:11:25 +0000
+++ CMakeLists.txt 2017-01-27 18:57:35 +0000
@@ -7,7 +7,6 @@
7set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}")7set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}")
88
9find_package(PkgConfig REQUIRED)9find_package(PkgConfig REQUIRED)
10find_package(GObjectIntrospection REQUIRED)
11include(GNUInstallDirs)10include(GNUInstallDirs)
12include(CheckIncludeFile)11include(CheckIncludeFile)
13include(CheckFunctionExists)12include(CheckFunctionExists)
@@ -17,6 +16,7 @@
17include_directories(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR})16include_directories(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR})
1817
19find_package(Qt5Core REQUIRED)18find_package(Qt5Core REQUIRED)
19find_package(Qt5DBus REQUIRED)
20find_package(Qt5Gui REQUIRED)20find_package(Qt5Gui REQUIRED)
21find_package(Qt5Quick REQUIRED)21find_package(Qt5Quick REQUIRED)
22find_package(Qt5Widgets REQUIRED)22find_package(Qt5Widgets REQUIRED)
2323
=== removed directory 'cmake'
=== removed file 'cmake/FindGObjectIntrospection.cmake'
--- cmake/FindGObjectIntrospection.cmake 2015-08-17 20:42:31 +0000
+++ cmake/FindGObjectIntrospection.cmake 1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
1# - try to find gobject-introspection
2#
3# Once done this will define
4#
5# INTROSPECTION_FOUND - system has gobject-introspection
6# INTROSPECTION_SCANNER - the gobject-introspection scanner, g-ir-scanner
7# INTROSPECTION_COMPILER - the gobject-introspection compiler, g-ir-compiler
8# INTROSPECTION_GENERATE - the gobject-introspection generate, g-ir-generate
9# INTROSPECTION_GIRDIR
10# INTROSPECTION_TYPELIBDIR
11# INTROSPECTION_CFLAGS
12# INTROSPECTION_LIBS
13#
14# Copyright (C) 2010, Pino Toscano, <pino@kde.org>
15#
16# Redistribution and use is allowed according to the terms of the BSD license.
17# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
18
19macro(_GIR_GET_PKGCONFIG_VAR _outvar _varname)
20 execute_process(
21 COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=${_varname} gobject-introspection-1.0
22 OUTPUT_VARIABLE _result
23 RESULT_VARIABLE _null
24 )
25
26 if (_null)
27 else()
28 string(REGEX REPLACE "[\r\n]" " " _result "${_result}")
29 string(REGEX REPLACE " +$" "" _result "${_result}")
30 separate_arguments(_result)
31 set(${_outvar} ${_result} CACHE INTERNAL "")
32 endif()
33endmacro(_GIR_GET_PKGCONFIG_VAR)
34
35find_package(PkgConfig)
36if(PKG_CONFIG_FOUND)
37 if(PACKAGE_FIND_VERSION_COUNT GREATER 0)
38 set(_gir_version_cmp ">=${PACKAGE_FIND_VERSION}")
39 endif()
40 pkg_check_modules(_pc_gir gobject-introspection-1.0${_gir_version_cmp})
41 if(_pc_gir_FOUND)
42 set(INTROSPECTION_FOUND TRUE)
43 _gir_get_pkgconfig_var(INTROSPECTION_SCANNER "g_ir_scanner")
44 _gir_get_pkgconfig_var(INTROSPECTION_COMPILER "g_ir_compiler")
45 _gir_get_pkgconfig_var(INTROSPECTION_GENERATE "g_ir_generate")
46 _gir_get_pkgconfig_var(INTROSPECTION_GIRDIR "girdir")
47 _gir_get_pkgconfig_var(INTROSPECTION_TYPELIBDIR "typelibdir")
48 set(INTROSPECTION_CFLAGS "${_pc_gir_CFLAGS}")
49 set(INTROSPECTION_LIBS "${_pc_gir_LIBS}")
50 endif()
51endif()
52
53mark_as_advanced(
54 INTROSPECTION_SCANNER
55 INTROSPECTION_COMPILER
56 INTROSPECTION_GENERATE
57 INTROSPECTION_GIRDIR
58 INTROSPECTION_TYPELIBDIR
59 INTROSPECTION_CFLAGS
60 INTROSPECTION_LIBS
61)
620
=== removed file 'cmake/ListOperations.cmake'
--- cmake/ListOperations.cmake 2015-08-17 20:42:31 +0000
+++ cmake/ListOperations.cmake 1970-01-01 00:00:00 +0000
@@ -1,18 +0,0 @@
1
2macro(list_prefix _outvar _listvar _prefix)
3 set(${_outvar})
4 foreach(_item IN LISTS ${_listvar})
5 list(APPEND ${_outvar} ${_prefix}${_item})
6 endforeach()
7endmacro(list_prefix)
8
9macro(list_make_absolute _outvar _listvar _prefix)
10 set(${_outvar})
11 foreach(_item IN LISTS ${_listvar})
12 if(IS_ABSOLUTE ${_item})
13 list(APPEND ${_outvar} ${_item})
14 else()
15 list(APPEND ${_outvar} ${_prefix}${_item})
16 endif()
17 endforeach()
18endmacro(list_make_absolute)
190
=== removed file 'cmake/UseGObjectIntrospection.cmake'
--- cmake/UseGObjectIntrospection.cmake 2015-08-17 20:42:31 +0000
+++ cmake/UseGObjectIntrospection.cmake 1970-01-01 00:00:00 +0000
@@ -1,102 +0,0 @@
1# Copyright (C) 2010, Pino Toscano, <pino@kde.org>
2#
3# Redistribution and use is allowed according to the terms of the BSD license.
4# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
5
6include(ListOperations)
7
8macro(_gir_list_prefix _outvar _listvar _prefix)
9 set(${_outvar})
10 foreach(_item IN LISTS ${_listvar})
11 list(APPEND ${_outvar} ${_prefix}${_item})
12 endforeach()
13endmacro(_gir_list_prefix)
14
15macro(gir_add_introspections introspections_girs)
16
17 foreach(gir IN LISTS ${introspections_girs})
18
19 set(_gir_name "${gir}")
20
21 ## Transform the gir filename to something which can reference through a variable
22 ## without automake/make complaining, eg Gtk-2.0.gir -> Gtk_2_0_gir
23 string(REPLACE "-" "_" _gir_name "${_gir_name}")
24 string(REPLACE "." "_" _gir_name "${_gir_name}")
25
26 # Namespace and Version is either fetched from the gir filename
27 # or the _NAMESPACE/_VERSION variable combo
28 set(_gir_namespace "${${_gir_name}_NAMESPACE}")
29 if (_gir_namespace STREQUAL "")
30 string(REGEX REPLACE "([^-]+)-.*" "\\1" _gir_namespace "${gir}")
31 endif ()
32 set(_gir_version "${${_gir_name}_VERSION}")
33 if (_gir_version STREQUAL "")
34 string(REGEX REPLACE ".*-([^-]+).gir" "\\1" _gir_version "${gir}")
35 endif ()
36
37 # _PROGRAM is an optional variable which needs it's own --program argument
38 set(_gir_program "${${_gir_name}_PROGRAM}")
39 if (NOT _gir_program STREQUAL "")
40 set(_gir_program "--program=${_gir_program}")
41 endif ()
42
43 # Variables which provides a list of things
44 _gir_list_prefix(_gir_libraries ${_gir_name}_LIBS "--library=")
45 _gir_list_prefix(_gir_packages ${_gir_name}_PACKAGES "--pkg=")
46 _gir_list_prefix(_gir_includes ${_gir_name}_INCLUDES "--include=")
47 _gir_list_prefix(_gir_export_packages ${_gir_name}_EXPORT_PACKAGES "--pkg-export=")
48
49 # Reuse the LIBTOOL variable from by automake if it's set
50 set(_gir_libtool "--no-libtool")
51
52 add_custom_command(
53 COMMAND ${INTROSPECTION_SCANNER}
54 ${INTROSPECTION_SCANNER_ARGS}
55 --quiet
56 --warn-all
57 --namespace=${_gir_namespace}
58 --nsversion=${_gir_version}
59 ${_gir_libtool}
60 ${_gir_program}
61 ${_gir_libraries}
62 ${_gir_packages}
63 ${_gir_includes}
64 ${_gir_export_packages}
65 ${${_gir_name}_SCANNERFLAGS}
66 ${${_gir_name}_CFLAGS}
67 ${${_gir_name}_FILES}
68 --output ${CMAKE_CURRENT_BINARY_DIR}/${gir}
69 DEPENDS ${${_gir_name}_FILES}
70 ${${_gir_name}_LIBS}
71 OUTPUT ${gir}
72 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
73 VERBATIM
74 )
75 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${gir} DESTINATION share/gir-1.0)
76
77 string(REPLACE ".gir" ".typelib" _typelib "${gir}")
78 add_custom_command(
79 COMMAND ${INTROSPECTION_COMPILER}
80 ${INTROSPECTION_COMPILER_ARGS}
81 --includedir=.
82 ${CMAKE_CURRENT_BINARY_DIR}/${gir}
83 -o ${CMAKE_CURRENT_BINARY_DIR}/${_typelib}
84 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${gir}
85 OUTPUT ${_typelib}
86 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
87 )
88 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_typelib} DESTINATION ${CMAKE_INSTALL_LIBDIR}/girepository-1.0)
89
90 add_custom_target(gir-${gir} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${gir})
91 add_custom_target(gir-typelibs-${_typelib} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_typelib})
92 endforeach()
93
94endmacro(gir_add_introspections)
95
96macro(gir_get_cflags _output)
97 get_directory_property(_tmp_includes INCLUDE_DIRECTORIES)
98 list_prefix(_includes _tmp_includes "-I")
99 get_directory_property(_tmp_compile_definitions COMPILE_DEFINITIONS)
100 list_prefix(_compile_definitions _tmp_compile_definitions "-D")
101 set(${_output} ${_includes} ${_compile_definitions})
102endmacro(gir_get_cflags)
1030
=== modified file 'common/LibertineConfig.cpp'
--- common/LibertineConfig.cpp 2017-01-18 15:43:03 +0000
+++ common/LibertineConfig.cpp 2017-01-27 18:57:35 +0000
@@ -3,7 +3,7 @@
3 * @brief Libertine Manager application-wide configuration module3 * @brief Libertine Manager application-wide configuration module
4 */4 */
5/*5/*
6 * Copyright 2015 Canonical Ltd6 * Copyright 2015-2017 Canonical Ltd
7 *7 *
8 * Libertine is free software: you can redistribute it and/or modify it under8 * Libertine is free software: you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3, as published by the9 * the terms of the GNU General Public License, version 3, as published by the
@@ -36,14 +36,6 @@
36 path.replace(std::getenv("HOME"), snap_common);36 path.replace(std::getenv("HOME"), snap_common);
37 }37 }
3838
39 // if libertine is installed as a snap but caller is not;
40 // workaround until ContainersConfig is only discovered from one location
41 if (QString(std::getenv("IGNORE_SNAP")) != "1" && QFile::exists("/snap/bin/libertine.libertine-launch"))
42 {
43 auto home = std::getenv("HOME");
44 path.replace(home, QString(home) + "/snap/libertine/common");
45 }
46
47 QDir dir(path);39 QDir dir(path);
4840
49 if (!dir.exists())41 if (!dir.exists())
5042
=== modified file 'data/CMakeLists.txt'
--- data/CMakeLists.txt 2016-12-21 20:57:15 +0000
+++ data/CMakeLists.txt 2017-01-27 18:57:35 +0000
@@ -8,7 +8,7 @@
8 DESTINATION ${CMAKE_INSTALL_DATADIR}/upstart/sessions)8 DESTINATION ${CMAKE_INSTALL_DATADIR}/upstart/sessions)
9install(FILES libertine-lxc-sudo libertine-lxd-sudo9install(FILES libertine-lxc-sudo libertine-lxd-sudo
10 DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/sudoers.d)10 DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/sudoers.d)
11install(FILES com.canonical.libertine.ContainerManager.service11install(FILES com.canonical.libertine.Service.service
12 com.canonical.libertine.LxcManager.service12 com.canonical.libertine.LxcManager.service
13 com.canonical.libertine.LxdManager.service13 com.canonical.libertine.LxdManager.service
14 DESTINATION ${CMAKE_INSTALL_DATADIR}/dbus-1/services)14 DESTINATION ${CMAKE_INSTALL_DATADIR}/dbus-1/services)
1515
=== renamed file 'data/com.canonical.libertine.ContainerManager.service' => 'data/com.canonical.libertine.Service.service'
--- data/com.canonical.libertine.ContainerManager.service 2016-11-01 20:10:58 +0000
+++ data/com.canonical.libertine.Service.service 2017-01-27 18:57:35 +0000
@@ -1,3 +1,3 @@
1[D-BUS Service]1[D-BUS Service]
2Name=com.canonical.libertine.ContainerManager2Name=com.canonical.libertine.Service
3Exec=/usr/bin/libertined --cache-output3Exec=/usr/bin/libertined --cache-output
44
=== modified file 'debian/changelog'
--- debian/changelog 2017-01-18 14:50:33 +0000
+++ debian/changelog 2017-01-27 18:57:35 +0000
@@ -1,3 +1,10 @@
1libertine (1.5.2-0ubuntu1) UNRELEASED; urgency=medium
2
3 [ Larry Price ]
4 * Bump version to 1.5.2.
5
6 -- Larry Price <larry.price@canonical.com> Thu, 26 Jan 2017 10:39:10 -0500
7
1libertine (1.5.1+17.04.20170118-0ubuntu1) zesty; urgency=medium8libertine (1.5.1+17.04.20170118-0ubuntu1) zesty; urgency=medium
29
3 [ Chris Townsend ]10 [ Chris Townsend ]
411
=== modified file 'debian/control'
--- debian/control 2016-12-07 17:45:28 +0000
+++ debian/control 2017-01-27 18:57:35 +0000
@@ -84,7 +84,6 @@
84Architecture: any84Architecture: any
85Depends: libglib2.0-bin,85Depends: libglib2.0-bin,
86 lsb-release,86 lsb-release,
87 python3-apt,
88 python3-dbus,87 python3-dbus,
89 python3-distro-info,88 python3-distro-info,
90 python3-libertine,89 python3-libertine,
@@ -115,15 +114,33 @@
115 Helper applications for using and interacting with Xmir such as launching114 Helper applications for using and interacting with Xmir such as launching
116 Xmir and allowing copy and paste.115 Xmir and allowing copy and paste.
117116
117Package: libertined
118Architecture: any
119Multi-Arch: same
120Depends: python3-libertine,
121 python3-apt,
122 python3-dbus,
123 python3-gi,
124 ${misc:Depends},
125 ${shlibs:Depends},
126 ${python3:Depends}
127Breaks: libertine-tools (<< 1.5.2)
128Replaces: libertine-tools (<< 1.5.2)
129Description: d-bus service for managing libertine containers
130 D-Bus service for asynchronously discovering and managing classic applications
131 using libertine containers. Allows installation and removal of deb-packaged
132 X11 apps within an isolated sandbox.
133
118Package: liblibertine1134Package: liblibertine1
119Architecture: any135Architecture: any
120Multi-Arch: same136Multi-Arch: same
121Depends: ${misc:Depends},137Depends: libertined,
138 ${misc:Depends},
122 ${shlibs:Depends}139 ${shlibs:Depends}
123Description: runtime for running deb-packaged X11 apps on Ubuntu Personal140Description: runtime for running deb-packaged X11 apps on Ubuntu Personal
124 Runtime library for creating and using the Ubuntu Personal sandbox for legacy141 Runtime library for creating and using the Ubuntu Personal sandbox for legacy
125 Deb-packaged X11 applicatons. This library is used by the Libertine tools142 Deb-packaged X11 applicatons. This library is used by the Libertine tools
126 and other software interacting wit hthe Libertine container, such as scopes143 and other software interacting with the Libertine container, such as scopes
127 or application launchers.144 or application launchers.
128145
129Package: liblibertine-dev146Package: liblibertine-dev
@@ -137,24 +154,11 @@
137 Headers and shared libraries used to create the tools for creating and using154 Headers and shared libraries used to create the tools for creating and using
138 the Ubuntu Personal sandbox for legacy Deb-packaged X11 applicatons.155 the Ubuntu Personal sandbox for legacy Deb-packaged X11 applicatons.
139156
140Package: gir1.2-libertine
141Architecture: any
142Multi-Arch: same
143Depends: liblibertine1 (= ${binary:Version}),
144 ${gir:Depends},
145 ${misc:Depends}
146Description: GObject introspection files for the Libertine application sandbox
147 The GObject introspection description files for the Libertine application
148 sandbox runtime. This package allows the Libertine API to be used from
149 GIR-compliant languages such as Python.
150
151Package: python3-libertine157Package: python3-libertine
152Architecture: any158Architecture: any
153Section: python159Section: python
154Multi-Arch: allowed160Multi-Arch: allowed
155Depends: gir1.2-libertine,161Depends: python3-psutil,
156 python3-gi,
157 python3-psutil,
158 python3-xdg,162 python3-xdg,
159 xdg-user-dirs,163 xdg-user-dirs,
160 ${misc:Depends},164 ${misc:Depends},
@@ -173,6 +177,7 @@
173 python3-libertine,177 python3-libertine,
174 python3-lxc,178 python3-lxc,
175 uidmap,179 uidmap,
180 python3-gi,
176 ${misc:Depends},181 ${misc:Depends},
177 ${python3:Depends}182 ${python3:Depends}
178Replaces: libertine-tools (<< 1.3)183Replaces: libertine-tools (<< 1.3)
@@ -190,6 +195,7 @@
190 python3-libertine,195 python3-libertine,
191 python3-pexpect,196 python3-pexpect,
192 python3-pylxd,197 python3-pylxd,
198 python3-gi,
193 ${misc:Depends},199 ${misc:Depends},
194 ${python3:Depends}200 ${python3:Depends}
195Description: Python3 scripts for the Libertine application sandbox201Description: Python3 scripts for the Libertine application sandbox
196202
=== removed file 'debian/gir1.2-libertine.install'
--- debian/gir1.2-libertine.install 2015-08-24 16:54:54 +0000
+++ debian/gir1.2-libertine.install 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
1usr/lib/*/girepository-1.0/Libertine-1.typelib
2usr/share/gir-1.0/Libertine-1.gir
30
=== modified file 'debian/libertine-tools.install'
--- debian/libertine-tools.install 2016-11-01 20:10:58 +0000
+++ debian/libertine-tools.install 2017-01-27 18:57:35 +0000
@@ -1,6 +1,4 @@
1usr/bin/libertine-container-manager1usr/bin/libertine-container-manager
2usr/bin/libertine-launch2usr/bin/libertine-launch
3usr/bin/libertined
4usr/share/dbus-1/services/com.canonical.libertine.ContainerManager.service
5usr/share/bash-completion/completions/libertine-container-manager3usr/share/bash-completion/completions/libertine-container-manager
6usr/share/man4usr/share/man
75
=== added file 'debian/libertined.install'
--- debian/libertined.install 1970-01-01 00:00:00 +0000
+++ debian/libertined.install 2017-01-27 18:57:35 +0000
@@ -0,0 +1,3 @@
1usr/bin/libertined
2usr/lib/python*/*/libertine/service
3usr/share/dbus-1/services/com.canonical.libertine.Service.service
04
=== modified file 'debian/python3-libertine.install'
--- debian/python3-libertine.install 2016-12-21 18:07:07 +0000
+++ debian/python3-libertine.install 2017-01-27 18:57:35 +0000
@@ -5,5 +5,4 @@
5usr/lib/python*/*/libertine/__init__.py5usr/lib/python*/*/libertine/__init__.py
6usr/lib/python*/*/libertine/launcher6usr/lib/python*/*/libertine/launcher
7usr/lib/python*/*/libertine/lifecycle7usr/lib/python*/*/libertine/lifecycle
8usr/lib/python*/*/libertine/service
9usr/lib/python*/*/libertine/utils.py8usr/lib/python*/*/libertine/utils.py
109
=== modified file 'debian/rules'
--- debian/rules 2016-12-06 20:52:55 +0000
+++ debian/rules 2017-01-27 18:57:35 +0000
@@ -1,7 +1,7 @@
1#!/usr/bin/make -f1#!/usr/bin/make -f
22
3%:3%:
4 dh $@ --with python3,gir4 dh $@ --with python3
55
6override_dh_auto_test:6override_dh_auto_test:
7 dbus-run-session -- dh_auto_test7 dbus-run-session -- dh_auto_test
88
=== modified file 'liblibertine/CMakeLists.txt'
--- liblibertine/CMakeLists.txt 2016-11-03 19:19:40 +0000
+++ liblibertine/CMakeLists.txt 2017-01-27 18:57:35 +0000
@@ -1,15 +1,12 @@
1set(API_VERSION 1)1set(API_VERSION 1)
2set(ABI_VERSION 1)2set(ABI_VERSION 1)
33
4set(COMMON_DIR ${CMAKE_SOURCE_DIR}/common)
5
6add_library(4add_library(
7 ${LIBERTINE_CORE} SHARED5 ${LIBERTINE_CORE} SHARED
8 libertine.cpp6 libertine.cpp
97
10 ${COMMON_DIR}/ContainerConfig.cpp8 # libertined client
11 ${COMMON_DIR}/ContainerConfigList.cpp9 libertined.cpp
12 ${COMMON_DIR}/LibertineConfig.cpp
13)10)
1411
15set_target_properties(${LIBERTINE_CORE} PROPERTIES12set_target_properties(${LIBERTINE_CORE} PROPERTIES
@@ -22,6 +19,7 @@
22 ${GLIB2_LIBRARIES}19 ${GLIB2_LIBRARIES}
23 ${PYTHON3_LIBRARIES}20 ${PYTHON3_LIBRARIES}
24 Qt5::Core21 Qt5::Core
22 Qt5::DBus
25)23)
2624
27# "liblibertine_headers_path" is used in libertine.pc.in25# "liblibertine_headers_path" is used in libertine.pc.in
@@ -32,28 +30,3 @@
32configure_file(libertine.pc.in ${CMAKE_BINARY_DIR}/libertine.pc @ONLY)30configure_file(libertine.pc.in ${CMAKE_BINARY_DIR}/libertine.pc @ONLY)
33install(FILES ${CMAKE_BINARY_DIR}/libertine.pc31install(FILES ${CMAKE_BINARY_DIR}/libertine.pc
34 DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)32 DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
35
36##########################
37# Introspection
38##########################
39
40include(UseGObjectIntrospection)
41
42set(INTROSPECTION_GIRS)
43set(_introspection_files libertine.h)
44set(Libertine_1_gir "libertine")
45set(Libertine_1_gir_INCLUDES GObject-2.0)
46
47gir_get_cflags(_cflags)
48set(Libertine_1_gir_CFLAGS ${c_flags})
49set(Libertine_1_gir_LIBS libertine)
50
51list_make_absolute(_abs_introspection_files _introspection_files "${CMAKE_CURRENT_SOURCE_DIR}/")
52set(Libertine_1_gir_FILES ${_abs_introspection_files})
53set(Libertine_1_gir_SCANNERFLAGS --c-include "libertine.h")
54set(Libertine_1_gir_EXPORT_PACKAGES "libertine-${API_VERSION}")
55
56list(APPEND INTROSPECTION_GIRS Libertine-1.gir)
57gir_add_introspections(INTROSPECTION_GIRS)
58
59install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Libertine-1.typelib" DESTINATION "${CMAKE_INSTALL_LIBDIR}/girepository-1.0")
6033
=== modified file 'liblibertine/libertine.cpp'
--- liblibertine/libertine.cpp 2017-01-18 15:43:03 +0000
+++ liblibertine/libertine.cpp 2017-01-27 18:57:35 +0000
@@ -1,9 +1,9 @@
1/**1/**
2 * @file libertine_common.cpp2 * @file libertine.cpp
3 * @brief The Libertine Common shared library3 * @brief The Libertine Common shared library
4 */4 */
5/*5/*
6 * Copyright 2015 Canonical Ltd.6 * Copyright 2015-2017 Canonical Ltd.
7 *7 *
8 * This program is free software: you can redistribute it and/or modify it under8 * This program is free software: you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3, as published by the9 * the terms of the GNU General Public License, version 3, as published by the
@@ -17,121 +17,21 @@
17 * You should have received a copy of the GNU General Public License17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */19 */
20
20#include "liblibertine/libertine.h"21#include "liblibertine/libertine.h"
2122#include "liblibertine/libertined.h"
22#include "common/ContainerConfigList.h"23
23#include "common/LibertineConfig.h"
24
25
26namespace
27{
28constexpr auto DESKTOP_EXTENSION = ".desktop";
29constexpr auto GLOBAL_APPLICATIONS = "usr/share/applications";
30constexpr auto LOCAL_APPLICATIONS = ".local/share/applications";
31
32
33GError*
34list_apps_from_path(gchar* path, const gchar* container_id, GArray* apps)
35{
36 GError* error = nullptr;
37 GDir* dir = g_dir_open(path, 0, &error);
38 if (error != nullptr)
39 {
40 return error;
41 }
42
43 const gchar * files;
44 while ((files = g_dir_read_name(dir)) != nullptr)
45 {
46 gchar *file = g_build_filename(path, files, nullptr);
47 if (g_file_test(file, G_FILE_TEST_IS_REGULAR) && g_str_has_suffix(files, DESKTOP_EXTENSION))
48 {
49 auto name = g_strdup(files);
50 name[strlen(name)-strlen(DESKTOP_EXTENSION)] = 0; // truncate the file extension
51
52 gchar * app_id = g_strjoin("_", g_strdup(container_id), name, "0.0", nullptr);
53 g_array_append_val(apps, app_id);
54 g_free(name);
55 }
56 else if (g_file_test(file, G_FILE_TEST_IS_DIR))
57 {
58 error = list_apps_from_path(file, container_id, apps);
59 if (error != nullptr)
60 {
61 return error;
62 }
63 }
64 g_free(file);
65 }
66
67 g_dir_close(dir);
68 return nullptr;
69}
70
71
72gchar*
73id_from_list_index(const ContainerConfigList& container_list, guint index)
74{
75 return (gchar*)container_list.data(container_list.index(index, 0),
76 (int)ContainerConfigList::DataRole::ContainerId)
77 .toString().toStdString().c_str();
78}
79
80
81bool
82running_snapped_libertine()
83{
84 if (g_strcmp0(std::getenv("IGNORE_SNAP"), "1") == 0)
85 {
86 return false;
87 }
88
89 auto libertine_launch_path = g_build_filename("/", "snap", "bin",
90 "libertine.libertine-launch",
91 nullptr);
92 bool out = g_file_test(libertine_launch_path, G_FILE_TEST_EXISTS);
93
94 g_free(libertine_launch_path);
95 return out;
96}
97}
9824
99gchar**25gchar**
100libertine_list_apps_for_container(const gchar* container_id)26libertine_list_apps_for_container(const gchar* container_id)
101{27{
102 g_return_val_if_fail(container_id != nullptr, nullptr);28 g_return_val_if_fail(container_id != nullptr, nullptr);
103 gchar* path = libertine_container_path(container_id);
104 GError* error = nullptr;
105 GArray* apps = g_array_new(TRUE, TRUE, sizeof(gchar*));29 GArray* apps = g_array_new(TRUE, TRUE, sizeof(gchar*));
10630 for (auto const& app: libertined_list_app_ids(container_id))
107 if (path != nullptr)31 {
108 {32 auto app_id = g_strdup((gchar *)app.toString().toStdString().c_str());
109 auto global_path = g_build_filename("/", g_strdup(path), GLOBAL_APPLICATIONS, nullptr);33 g_array_append_val(apps, app_id);
110 error = list_apps_from_path(global_path, container_id, apps);34 }
111 if (error != nullptr)
112 {
113 g_free(global_path);
114 g_free(path);
115 g_error_free(error);
116 return (gchar**)g_array_free(apps, FALSE);
117 }
118 g_free(global_path);
119 }
120 g_free(path);
121
122 auto home_path = libertine_container_home_path(container_id);
123 if (home_path != nullptr)
124 {
125 auto local_path = g_build_filename(home_path, LOCAL_APPLICATIONS, nullptr);
126
127 error = list_apps_from_path(local_path, container_id, apps);
128 if (error != nullptr)
129 {
130 g_error_free(error); // free error, but return previously found apps
131 }
132 g_free(local_path);
133 }
134 g_free(home_path);
13535
136 return (gchar**)g_array_free(apps, FALSE);36 return (gchar**)g_array_free(apps, FALSE);
137}37}
@@ -140,22 +40,12 @@
140gchar **40gchar **
141libertine_list_containers(void)41libertine_list_containers(void)
142{42{
143 guint container_count;43 auto containers = g_array_new(TRUE, TRUE, sizeof(gchar *));
144 guint i;44 for (auto const& container: libertined_list())
145 LibertineConfig config;
146 ContainerConfigList container_list(&config);
147 GArray * containers = g_array_new(TRUE, TRUE, sizeof(gchar *));
148 QVariant id;
149
150 container_count = (guint)container_list.size();
151
152 for (i = 0; i < container_count; ++i)
153 {45 {
154 id = container_list.data(container_list.index(i, 0), (int)ContainerConfigList::DataRole::ContainerId);46 auto container_id = g_strdup((gchar *)container.toString().toStdString().c_str());
155 gchar * container_id = g_strdup((gchar *)id.toString().toStdString().c_str());
156 g_array_append_val(containers, container_id);47 g_array_append_val(containers, container_id);
157 }48 }
158
159 return (gchar **)g_array_free(containers, FALSE);49 return (gchar **)g_array_free(containers, FALSE);
160}50}
16151
@@ -164,19 +54,8 @@
164libertine_container_path(const gchar * container_id)54libertine_container_path(const gchar * container_id)
165{55{
166 g_return_val_if_fail(container_id != nullptr, nullptr);56 g_return_val_if_fail(container_id != nullptr, nullptr);
167 LibertineConfig config;57
168 ContainerConfigList container_list(&config);58 gchar* path = g_strdup((gchar *)libertined_container_path(container_id).toStdString().c_str());
169 gchar* path = g_build_filename(g_get_user_cache_dir(), "libertine-container", container_id, "rootfs", nullptr);
170
171 // temporary solution for discovering applications in unity8 until libertined
172 // has been updated to access location data
173 if (running_snapped_libertine())
174 {
175 g_free(path);
176 path = g_build_filename("/", "home", g_get_user_name(), "snap", "libertine", "common", ".cache", "libertine-container", container_id, "rootfs", nullptr);
177 }
178
179
180 if (g_file_test(path, G_FILE_TEST_EXISTS))59 if (g_file_test(path, G_FILE_TEST_EXISTS))
181 {60 {
182 return path;61 return path;
@@ -191,18 +70,8 @@
191libertine_container_home_path(const gchar * container_id)70libertine_container_home_path(const gchar * container_id)
192{71{
193 g_return_val_if_fail(container_id != nullptr, nullptr);72 g_return_val_if_fail(container_id != nullptr, nullptr);
194 LibertineConfig config;73
195 ContainerConfigList container_list(&config);74 gchar* path = g_strdup((gchar *)libertined_container_home_path(container_id).toStdString().c_str());
196 gchar * path = g_build_filename(g_get_user_data_dir(), "libertine-container", "user-data", container_id, nullptr);
197
198 // temporary solution for discovering applications in unity8 until libertined
199 // has been updated to access location data
200 if (running_snapped_libertine())
201 {
202 g_free(path);
203 path = g_build_filename("/", "home", g_get_user_name(), "snap", "libertine", "common", ".local", "libertine-container", "user-data", container_id, nullptr);
204 }
205
206 if (g_file_test(path, G_FILE_TEST_EXISTS))75 if (g_file_test(path, G_FILE_TEST_EXISTS))
207 {76 {
208 return path;77 return path;
@@ -216,20 +85,7 @@
216gchar *85gchar *
217libertine_container_name(const gchar * container_id)86libertine_container_name(const gchar * container_id)
218{87{
219 gchar * container_name = nullptr;88 g_return_val_if_fail(container_id != nullptr, nullptr);
220 LibertineConfig config;89
221 ContainerConfigList container_list(&config);90 return g_strdup((gchar *)libertined_container_name(container_id).toStdString().c_str());
222 guint container_count = (guint)container_list.size();
223
224 for (guint i = 0; i < container_count; ++i)
225 {
226 if (g_strcmp0(id_from_list_index(container_list, i), container_id) == 0)
227 {
228 QVariant name = container_list.data(container_list.index(i, 0), (int)ContainerConfigList::DataRole::ContainerName);
229 container_name = g_strdup(name.toString().toStdString().c_str());
230 break;
231 }
232 }
233
234 return container_name;
235}91}
23692
=== modified file 'liblibertine/libertine.h'
--- liblibertine/libertine.h 2016-09-06 12:36:47 +0000
+++ liblibertine/libertine.h 2017-01-27 18:57:35 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2015 Canonical Ltd.2 * Copyright 2015-2017 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it under4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, version 3, as published by the5 * the terms of the GNU General Public License, version 3, as published by the
@@ -15,8 +15,8 @@
15 */15 */
16#include <glib.h>16#include <glib.h>
1717
18#ifndef _LIBERTINE_COMMON_H_18#ifndef _LIBLIBERTINE_H_
19#define _LIBERTINE_COMMON_H_19#define _LIBLIBERTINE_H_
2020
21#ifdef __cplusplus21#ifdef __cplusplus
22extern "C" {22extern "C" {
@@ -80,4 +80,4 @@
80}80}
81#endif81#endif
8282
83#endif /* _LIBERTINE_COMMON_H_ */83#endif /* _LIBLIBERTINE_H_ */
8484
=== added file 'liblibertine/libertined.cpp'
--- liblibertine/libertined.cpp 1970-01-01 00:00:00 +0000
+++ liblibertine/libertined.cpp 2017-01-27 18:57:35 +0000
@@ -0,0 +1,199 @@
1/*
2 * Copyright 2017 Canonical Ltd
3 *
4 * Libertine is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, version 3, as published by the
6 * Free Software Foundation.
7 *
8 * Libertine is distributed in the hope that it will be useful, but WITHOUT ANY
9 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
10 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 */
15
16
17#include "libertined.h"
18
19#include <QDBusMessage>
20#include <QDBusInterface>
21#include <QDebug>
22#include <thread>
23#include <chrono>
24#include <QJsonDocument>
25#include <QJsonArray>
26#include <QJsonObject>
27
28namespace
29{
30static const auto SERVICE_INTERFACE = "com.canonical.libertine.Service";
31static const auto PROGRESS_INTERFACE = "com.canonical.libertine.Service.Progress";
32
33static QVariantList
34dbusCall(QDBusConnection const& bus, QString const& iface, QString const& path,
35 QString const& method, QVariantList const& args = QVariantList())
36{
37 auto message = QDBusMessage::createMethodCall(SERVICE_INTERFACE, path, iface, method);
38 message.setArguments(args);
39 auto response = bus.call(message);
40 if (response.type() == QDBusMessage::ErrorMessage)
41 {
42 qWarning() << "error calling result" << response.errorMessage();
43 return QVariantList();
44 }
45
46 return response.arguments();
47}
48
49static bool
50isRunning(QDBusConnection const& bus, QString const& path)
51{
52 auto args = dbusCall(bus, PROGRESS_INTERFACE, path, "running", QVariantList());
53
54 if (args.isEmpty())
55 {
56 qWarning() << "lastError - no arguments?";
57 return false;
58 }
59
60 return args.first().toBool();
61}
62
63static QString
64result(QDBusConnection const& bus, QString const& path)
65{
66 auto args = dbusCall(bus, PROGRESS_INTERFACE, path, "result");
67
68 if (args.isEmpty())
69 {
70 qWarning() << "lastError - no arguments?";
71 return "";
72 }
73
74 return args.first().toString();
75}
76
77static QString
78lastError(QDBusConnection const& bus, QString const& path)
79{
80 auto args = dbusCall(bus, PROGRESS_INTERFACE, path, "last_error");
81
82 if (args.isEmpty())
83 {
84 qWarning() << "lastError - no arguments?";
85 return "";
86 }
87
88 return args.first().toString();
89}
90
91static QString
92call(QDBusConnection const& bus, QString const& method, QVariantList const& args)
93{
94 auto results = dbusCall(bus, SERVICE_INTERFACE, "/Manager", method, args);
95
96 if (results.isEmpty())
97 {
98 return QString();
99 }
100
101 return qvariant_cast<QDBusObjectPath>(results.first()).path();
102}
103
104static bool
105waitForFinish(QDBusConnection const& bus, QString const& path)
106{
107 std::chrono::microseconds wait(500);
108 for (auto i = 0; i < 2000; ++i)
109 {
110 if (!isRunning(bus, path))
111 {
112 return true;
113 }
114 std::this_thread::sleep_for(wait);
115 }
116 return !isRunning(bus, path);
117}
118
119QString
120container_info(char const* container_id, QString const& key)
121{
122 auto bus = QDBusConnection::sessionBus();
123 auto path = call(bus, "container_info", QVariantList{QVariant(container_id)});
124
125 if (!waitForFinish(bus, path))
126 {
127 return QString();
128 }
129
130 auto error = lastError(bus, path);
131 if (!error.isEmpty())
132 {
133 qWarning() << "error:" << error;
134 return QString();
135 }
136
137 return QJsonDocument::fromJson(result(bus, path).toLatin1()).object().value(key).toString();
138}
139}
140
141QJsonArray
142libertined_list()
143{
144 auto bus = QDBusConnection::sessionBus();
145 auto path = call(bus, "list", QVariantList());
146
147 if (!waitForFinish(bus, path))
148 {
149 return QJsonArray();
150 }
151
152 auto error = lastError(bus, path);
153 if (!error.isEmpty())
154 {
155 qWarning() << "error:" << error;
156 return QJsonArray();
157 }
158
159 return QJsonDocument::fromJson(result(bus, path).toLatin1()).array();
160}
161
162QJsonArray
163libertined_list_app_ids(char const* container_id)
164{
165 auto bus = QDBusConnection::sessionBus();
166 auto path = call(bus, "list_app_ids", QVariantList{QVariant(container_id)});
167
168 if (!waitForFinish(bus, path))
169 {
170 return QJsonArray();
171 }
172
173 auto error = lastError(bus, path);
174 if (!error.isEmpty())
175 {
176 qWarning() << "error:" << error;
177 return QJsonArray();
178 }
179
180 return QJsonDocument::fromJson(result(bus, path).toLatin1()).array();
181}
182
183QString
184libertined_container_path(char const* container_id)
185{
186 return container_info(container_id, "root");
187}
188
189QString
190libertined_container_home_path(char const* container_id)
191{
192 return container_info(container_id, "home");
193}
194
195QString
196libertined_container_name(char const* container_id)
197{
198 return container_info(container_id, "name");
199}
0200
=== added file 'liblibertine/libertined.h'
--- liblibertine/libertined.h 1970-01-01 00:00:00 +0000
+++ liblibertine/libertined.h 2017-01-27 18:57:35 +0000
@@ -0,0 +1,25 @@
1/*
2 * Copyright 2017 Canonical Ltd
3 *
4 * Libertine is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, version 3, as published by the
6 * Free Software Foundation.
7 *
8 * Libertine is distributed in the hope that it will be useful, but WITHOUT ANY
9 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
10 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 */
15
16#pragma once
17
18#include <QDBusConnection>
19#include <QJsonArray>
20
21QJsonArray libertined_list();
22QString libertined_container_path(char const* container_id);
23QString libertined_container_home_path(char const* container_id);
24QString libertined_container_name(char const* container_id);
25QJsonArray libertined_list_app_ids(char const* container_id);
026
=== modified file 'python/libertine/ChrootContainer.py'
--- python/libertine/ChrootContainer.py 2017-01-17 20:19:30 +0000
+++ python/libertine/ChrootContainer.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2015-2016 Canonical Ltd.1# Copyright 2015-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify it3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published4# under the terms of the GNU General Public License version 3, as published
@@ -47,9 +47,8 @@
47 A concrete container type implemented using a plain old chroot.47 A concrete container type implemented using a plain old chroot.
48 """48 """
4949
50 def __init__(self, container_id):50 def __init__(self, container_id, config):
51 super().__init__(container_id)51 super().__init__(container_id, 'chroot', config)
52 self.container_type = "chroot"
53 self._window_manager = None52 self._window_manager = None
54 # FIXME: Disabling seccomp is a temporary measure until we fully understand why we need53 # FIXME: Disabling seccomp is a temporary measure until we fully understand why we need
55 # it or figure out when we need it.54 # it or figure out when we need it.
@@ -112,7 +111,7 @@
112 fd.write(archive + self.installed_release + " multiverse\n")111 fd.write(archive + self.installed_release + " multiverse\n")
113 fd.write(archive + self.installed_release + "-updates multiverse\n")112 fd.write(archive + self.installed_release + "-updates multiverse\n")
114113
115 utils.create_libertine_user_data_dir(self.container_id)114 self._create_libertine_user_data_dir()
116115
117 self.update_locale()116 self.update_locale()
118117
@@ -140,7 +139,7 @@
140 self.update_packages()139 self.update_packages()
141140
142 # Check if the container was created as root and chown the user directories as necessary141 # Check if the container was created as root and chown the user directories as necessary
143 chown_recursive_dirs(utils.get_libertine_container_userdata_dir_path(self.container_id))142 chown_recursive_dirs(utils.get_libertine_container_home_dir(self.container_id))
144143
145 super().create_libertine_container()144 super().create_libertine_container()
146145
@@ -186,7 +185,7 @@
186 # Bind-mount common XDG direcotries185 # Bind-mount common XDG direcotries
187 bind_mounts = (186 bind_mounts = (
188 " -b %s:%s"187 " -b %s:%s"
189 % (utils.get_libertine_container_userdata_dir_path(self.container_id), home_path)188 % (utils.get_libertine_container_home_dir(self.container_id), home_path)
190 )189 )
191190
192 mounts = self._sanitize_bind_mounts(utils.get_common_xdg_user_directories() + \191 mounts = self._sanitize_bind_mounts(utils.get_common_xdg_user_directories() + \
193192
=== modified file 'python/libertine/ContainersConfig.py'
--- python/libertine/ContainersConfig.py 2017-01-24 20:21:16 +0000
+++ python/libertine/ContainersConfig.py 2017-01-27 18:57:35 +0000
@@ -242,6 +242,9 @@
242 if write_json:242 if write_json:
243 write_container_config_file(self.container_list)243 write_container_config_file(self.container_list)
244244
245 def get_containers(self):
246 return [c["id"] for c in self.container_list.get('containerList', [])]
247
245 """248 """
246 Operations for the container itself.249 Operations for the container itself.
247 """250 """
@@ -303,6 +306,12 @@
303 def get_container_locale(self, container_id):306 def get_container_locale(self, container_id):
304 return self._get_value_by_key(container_id, 'locale')307 return self._get_value_by_key(container_id, 'locale')
305308
309 def get_container_name(self, container_id):
310 return self._get_value_by_key(container_id, 'name')
311
312 def get_container_install_status(self, container_id):
313 return self._get_value_by_key(container_id, 'installStatus')
314
306 """315 """
307 Operations for archive (PPA) maintenance in a Libertine container.316 Operations for archive (PPA) maintenance in a Libertine container.
308 """317 """
309318
=== modified file 'python/libertine/Libertine.py'
--- python/libertine/Libertine.py 2017-01-24 15:31:01 +0000
+++ python/libertine/Libertine.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2015-2016 Canonical Ltd.1# Copyright 2015-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify it3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published4# under the terms of the GNU General Public License version 3, as published
@@ -13,7 +13,6 @@
13# with this program. If not, see <http://www.gnu.org/licenses/>.13# with this program. If not, see <http://www.gnu.org/licenses/>.
1414
15from .AppDiscovery import AppLauncherCache15from .AppDiscovery import AppLauncherCache
16from gi.repository import Libertine
17import abc16import abc
18import contextlib17import contextlib
19import os18import os
@@ -81,14 +80,12 @@
8180
82 :param container_id: The machine-readable container name.81 :param container_id: The machine-readable container name.
83 """82 """
84 def __init__(self, container_id, containers_config=None):83 def __init__(self, container_id, container_type, config):
85 if containers_config is None:84 self.container_type = container_type
86 containers_config = ContainersConfig()
87
88 self.container_type = 'unknown'
89 self.container_id = container_id85 self.container_id = container_id
86 self._config = config
90 self.root_path = utils.get_libertine_container_rootfs_path(self.container_id)87 self.root_path = utils.get_libertine_container_rootfs_path(self.container_id)
91 self.locale = containers_config.get_container_locale(container_id)88 self.locale = self._config.get_container_locale(container_id)
92 self.language = self._get_language_from_locale()89 self.language = self._get_language_from_locale()
93 self.default_packages = ['matchbox-window-manager',90 self.default_packages = ['matchbox-window-manager',
94 'libnss-extrausers',91 'libnss-extrausers',
@@ -247,10 +244,10 @@
247 self.delete_file_in_container(dest)244 self.delete_file_in_container(dest)
248245
249 return ret246 return ret
250 else:247
251 if no_dialog:248 if no_dialog:
252 os.environ['DEBIAN_FRONTEND'] = 'teletype'249 os.environ['DEBIAN_FRONTEND'] = 'teletype'
253 ret = self.run_in_container(_apt_command_prefix() + " install '" + package_name + "'") == 0250 ret = self.run_in_container(_apt_command_prefix() + " install '" + package_name + "'") == 0
254251
255 self.check_language_support()252 self.check_language_support()
256253
@@ -313,19 +310,26 @@
313 """310 """
314 The human-readable name of the container.311 The human-readable name of the container.
315 """312 """
316 name = Libertine.container_name(self.container_id)313 return self._config.get_container_name(self.container_id) or 'Unknown'
317 if not name:314
318 name = 'Unknown'315 def _create_libertine_user_data_dir(self):
319 return name316 user_data = utils.get_libertine_container_home_dir(self.container_id)
317
318 if not os.path.exists(user_data):
319 os.makedirs(user_data)
320
321 config_path = os.path.join(user_data, ".config", "dconf")
322
323 if not os.path.exists(config_path):
324 os.makedirs(config_path)
320325
321326
322class LibertineMock(BaseContainer):327class LibertineMock(BaseContainer):
323 """328 """
324 A concrete mock container type. Used for unit testing.329 A concrete mock container type. Used for unit testing.
325 """330 """
326 def __init__(self, container_id, containers_config=None):331 def __init__(self, container_id, config):
327 super().__init__(container_id, containers_config)332 super().__init__(container_id, 'mock', config)
328 self.container_type = "mock"
329333
330 def create_libertine_container(self, password=None, multiarch=False):334 def create_libertine_container(self, password=None, multiarch=False):
331 return True335 return True
@@ -395,7 +399,7 @@
395 self.container = LibertineLXD(container_id, self.containers_config)399 self.container = LibertineLXD(container_id, self.containers_config)
396 elif container_type == "chroot":400 elif container_type == "chroot":
397 from libertine.ChrootContainer import LibertineChroot401 from libertine.ChrootContainer import LibertineChroot
398 self.container = LibertineChroot(container_id)402 self.container = LibertineChroot(container_id, self.containers_config)
399 elif container_type == "mock":403 elif container_type == "mock":
400 self.container = LibertineMock(container_id, self.containers_config)404 self.container = LibertineMock(container_id, self.containers_config)
401 else:405 else:
@@ -514,7 +518,7 @@
514 Enumerates all application launchers (based on .desktop files) available518 Enumerates all application launchers (based on .desktop files) available
515 in the container.519 in the container.
516520
517 :param use_json: Indicates the returned string should be i JSON format.521 :param use_json: Indicates the returned string should be in JSON format.
518 The default format is some human-readble format.522 The default format is some human-readble format.
519 :rtype: A printable string containing a list of application launchers523 :rtype: A printable string containing a list of application launchers
520 available in the container.524 available in the container.
@@ -526,6 +530,24 @@
526 return str(AppLauncherCache(self.container.name,530 return str(AppLauncherCache(self.container.name,
527 self.container.root_path))531 self.container.root_path))
528532
533 def list_app_ids(self):
534 """
535 Finds application ids (based on .desktop files) available in the
536 container.
537
538 :rtype: A list of app ids consumable by tools such as ubuntu-app-launch
539 """
540 home = utils.get_libertine_container_home_dir(self.container_id)
541 app_ids = []
542 for apps_dir in ["{}/usr/share/applications".format(self.root_path),
543 "{}/usr/local/share/applications".format(self.root_path),
544 "{}/.local/share/applications".format(home)]:
545 if os.path.exists(apps_dir):
546 for root, dirs, files in os.walk(apps_dir):
547 app_ids.extend(["{}_{}_0.0".format(self.container_id, f[:-8]) for f in files if f.endswith(".desktop")])
548
549 return app_ids
550
529 def exec_command(self, exec_line):551 def exec_command(self, exec_line):
530 """552 """
531 Runs an arbitrary application in the container. Mainly used for status553 Runs an arbitrary application in the container. Mainly used for status
532554
=== modified file 'python/libertine/LxcContainer.py'
--- python/libertine/LxcContainer.py 2017-01-24 20:21:16 +0000
+++ python/libertine/LxcContainer.py 2017-01-27 18:57:35 +0000
@@ -158,9 +158,8 @@
158 A concrete container type implemented using an LXC container.158 A concrete container type implemented using an LXC container.
159 """159 """
160160
161 def __init__(self, container_id, config=None):161 def __init__(self, container_id, config):
162 super().__init__(container_id)162 super().__init__(container_id, 'lxc', config)
163 self.container_type = "lxc"
164 self.container = lxc_container(container_id)163 self.container = lxc_container(container_id)
165 self.lxc_manager_interface = None164 self.lxc_manager_interface = None
166 self.window_manager = None165 self.window_manager = None
@@ -247,7 +246,7 @@
247246
248 self.container.load_config(config_file)247 self.container.load_config(config_file)
249248
250 utils.create_libertine_user_data_dir(self.container_id)249 self._create_libertine_user_data_dir()
251250
252 with EnvLxcSettings():251 with EnvLxcSettings():
253 lxc_logfile = get_logfile(self.container)252 lxc_logfile = get_logfile(self.container)
@@ -299,7 +298,7 @@
299 user_id = os.getuid()298 user_id = os.getuid()
300 home_entry = (299 home_entry = (
301 "%s %s none bind,create=dir"300 "%s %s none bind,create=dir"
302 % (utils.get_libertine_container_userdata_dir_path(self.container_id),301 % (utils.get_libertine_container_home_dir(self.container_id),
303 home_path.strip('/'))302 home_path.strip('/'))
304 )303 )
305304
306305
=== modified file 'python/libertine/LxdContainer.py'
--- python/libertine/LxdContainer.py 2017-01-25 16:27:15 +0000
+++ python/libertine/LxdContainer.py 2017-01-27 18:57:35 +0000
@@ -226,7 +226,7 @@
226226
227227
228def update_bind_mounts(container, config, home_path):228def update_bind_mounts(container, config, home_path):
229 userdata_dir = utils.get_libertine_container_userdata_dir_path(container.name)229 userdata_dir = utils.get_libertine_container_home_dir(container.name)
230230
231 container.devices.clear()231 container.devices.clear()
232 container.devices['root'] = {'type': 'disk', 'path': '/'}232 container.devices['root'] = {'type': 'disk', 'path': '/'}
@@ -251,7 +251,7 @@
251251
252 mounts = config.get_container_bind_mounts(container.name)252 mounts = config.get_container_bind_mounts(container.name)
253 if utils.is_snap_environment():253 if utils.is_snap_environment():
254 mounts += ["{}{}".format(home_path, d) for d in ["Documents", "Downloads", "Music", "Videos", "Pictures"]]254 mounts += [os.path.join(home_path, d) for d in ["Documents", "Downloads", "Music", "Videos", "Pictures"]]
255 else:255 else:
256 mounts += utils.get_common_xdg_user_directories()256 mounts += utils.get_common_xdg_user_directories()
257257
@@ -301,8 +301,7 @@
301301
302class LibertineLXD(Libertine.BaseContainer):302class LibertineLXD(Libertine.BaseContainer):
303 def __init__(self, name, config):303 def __init__(self, name, config):
304 super().__init__(name, config)304 super().__init__(name, 'lxd', config)
305 self._config = config
306 self._host_info = HostInfo.HostInfo()305 self._host_info = HostInfo.HostInfo()
307 self._container = None306 self._container = None
308 self._matchbox_pid = None307 self._matchbox_pid = None
@@ -315,14 +314,15 @@
315 self._client = pylxd.Client()314 self._client = pylxd.Client()
316 self._window_manager = None315 self._window_manager = None
317316
318 try:317 if not utils.is_snap_environment():
319 if utils.set_session_dbus_env_var():318 try:
320 bus = dbus.SessionBus()319 if utils.set_session_dbus_env_var():
321 self._manager = bus.get_object(get_lxd_manager_dbus_name(), get_lxd_manager_dbus_path())320 bus = dbus.SessionBus()
322 except PermissionError as e:321 self._manager = bus.get_object(get_lxd_manager_dbus_name(), get_lxd_manager_dbus_path())
323 utils.get_logger().warning("Failed to set dbus session env var")322 except PermissionError as e:
324 except dbus.exceptions.DBusException:323 utils.get_logger().warning("Failed to set dbus session env var")
325 utils.get_logger().warning("D-Bus Service not found.")324 except dbus.exceptions.DBusException:
325 utils.get_logger().warning("D-Bus Service not found.")
326326
327 def create_libertine_container(self, password=None, multiarch=False):327 def create_libertine_container(self, password=None, multiarch=False):
328 if self._try_get_container():328 if self._try_get_container():
@@ -353,7 +353,7 @@
353 self.run_in_container("mkdir -p /home/{}".format(username))353 self.run_in_container("mkdir -p /home/{}".format(username))
354 self.run_in_container("chown {0}:{0} /home/{0}".format(username))354 self.run_in_container("chown {0}:{0} /home/{0}".format(username))
355355
356 utils.create_libertine_user_data_dir(self.container_id)356 self._create_libertine_user_data_dir()
357357
358 _setup_bind_mount_service(self._container, uid, username)358 _setup_bind_mount_service(self._container, uid, username)
359359
360360
=== modified file 'python/libertine/service/apt.py'
--- python/libertine/service/apt.py 2016-11-08 15:37:58 +0000
+++ python/libertine/service/apt.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -15,10 +15,6 @@
15import apt15import apt
16import re16import re
1717
18import gi
19gi.require_version('Libertine', '1')
20from gi.repository import Libertine
21
22from libertine import utils18from libertine import utils
23from os import path19from os import path
24from threading import Lock20from threading import Lock
@@ -67,7 +63,7 @@
67 if self._cache is None:63 if self._cache is None:
68 try:64 try:
69 utils.get_logger().debug("Trying aptcache for container %s" % self._container)65 utils.get_logger().debug("Trying aptcache for container %s" % self._container)
70 container_path = Libertine.container_path(self._container)66 container_path = utils.get_libertine_container_rootfs_path(self._container)
71 if not container_path or not path.exists(container_path):67 if not container_path or not path.exists(container_path):
72 raise PermissionError68 raise PermissionError
7369
7470
=== modified file 'python/libertine/service/container.py'
--- python/libertine/service/container.py 2016-11-08 15:37:58 +0000
+++ python/libertine/service/container.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -14,18 +14,27 @@
1414
15from libertine.service.tasks import *15from libertine.service.tasks import *
16from libertine import utils16from libertine import utils
17from libertine.service import apt17from threading import Lock
18
19
20if not utils.is_snap_environment():
21 from libertine.service import apt
1822
1923
20class Container(object):24class Container(object):
21 def __init__(self, container_id, config, lock, connection, callback):25 def __init__(self, container_id, config, connection, callback):
22 self._id = container_id26 self._id = container_id
23 self._connection = connection27 self._connection = connection
24 self._callback = callback28 self._callback = callback
25 self._config = config29 self._config = config
26 self._lock = lock30 self._lock = Lock()
27 self._tasks = []31 self._tasks = []
28 self._cache = apt.AptCache(self.id)32
33 if utils.is_snap_environment():
34 utils.get_logger().warning("Using AptCache not currently supported in snap environment")
35 self._cache = None
36 else:
37 self._cache = apt.AptCache(self.id)
2938
30 def _cleanup_task(self, task):39 def _cleanup_task(self, task):
31 utils.get_logger().debug("cleaning up tasks for container '%s'" % self.id)40 utils.get_logger().debug("cleaning up tasks for container '%s'" % self.id)
@@ -47,6 +56,9 @@
47 def search(self, query):56 def search(self, query):
48 utils.get_logger().debug("search container '%s' for package '%s'" % (self.id, query))57 utils.get_logger().debug("search container '%s' for package '%s'" % (self.id, query))
4958
59 if utils.is_snap_environment():
60 raise Exception("This operation is not currently supported within the snap")
61
50 task = SearchTask(self.id, self._cache, query, self._connection, self._cleanup_task)62 task = SearchTask(self.id, self._cache, query, self._connection, self._cleanup_task)
51 self._tasks.append(task)63 self._tasks.append(task)
52 task.start()64 task.start()
@@ -56,6 +68,9 @@
56 def app_info(self, package_name):68 def app_info(self, package_name):
57 utils.get_logger().debug("get info for package '%s' in container '%s'" % (package_name, self.id))69 utils.get_logger().debug("get info for package '%s' in container '%s'" % (package_name, self.id))
5870
71 if utils.is_snap_environment():
72 raise Exception("This operation is not currently supported within the snap")
73
59 related_task_ids = [t.id for t in self._tasks if t.package == package_name and t.running]74 related_task_ids = [t.id for t in self._tasks if t.package == package_name and t.running]
60 task = AppInfoTask(self.id, self._cache, package_name, related_task_ids, self._config, self._connection, self._cleanup_task)75 task = AppInfoTask(self.id, self._cache, package_name, related_task_ids, self._config, self._connection, self._cleanup_task)
6176
@@ -137,3 +152,12 @@
137 self._tasks.append(task)152 self._tasks.append(task)
138 task.start()153 task.start()
139 return task.id154 return task.id
155
156 def list_app_ids(self):
157 utils.get_logger().debug("List all app ids in container '%s'" % self.id)
158
159 task = ListAppIdsTask(self.id, self._config, self._connection, self._cleanup_task)
160
161 self._tasks.append(task)
162 task.start()
163 return task.id
140164
=== modified file 'python/libertine/service/manager.py'
--- python/libertine/service/manager.py 2016-10-31 18:31:00 +0000
+++ python/libertine/service/manager.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -72,6 +72,13 @@
72 return self._dispatcher.list_apps(container_id)72 return self._dispatcher.list_apps(container_id)
7373
74 @dbus.service.method(LIBERTINE_MANAGER_INTERFACE,74 @dbus.service.method(LIBERTINE_MANAGER_INTERFACE,
75 in_signature='s',
76 out_signature='o')
77 def list_app_ids(self, container_id):
78 utils.get_logger().debug("list_app_ids('{}')".format(container_id))
79 return self._dispatcher.list_app_ids(container_id)
80
81 @dbus.service.method(LIBERTINE_MANAGER_INTERFACE,
75 out_signature='o')82 out_signature='o')
76 def list(self):83 def list(self):
77 utils.get_logger().debug("list()")84 utils.get_logger().debug("list()")
7885
=== modified file 'python/libertine/service/progress.py'
--- python/libertine/service/progress.py 2016-11-29 17:38:38 +0000
+++ python/libertine/service/progress.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
18from time import time18from time import time
1919
20DOWNLOAD_INTERFACE = "com.canonical.applications.Download"20DOWNLOAD_INTERFACE = "com.canonical.applications.Download"
21PROGRESS_INTERFACE = "com.canonical.libertine.Progress"21PROGRESS_INTERFACE = "com.canonical.libertine.Service.Progress"
2222
23class Progress(dbus.service.Object):23class Progress(dbus.service.Object):
24 def __init__(self, connection):24 def __init__(self, connection):
@@ -28,7 +28,7 @@
28 self._error = ''28 self._error = ''
29 dbus.service.Object.__init__(self, conn=connection, object_path=("/Progress/%s" % hex(int(time()*10000000))[2:]))29 dbus.service.Object.__init__(self, conn=connection, object_path=("/Progress/%s" % hex(int(time()*10000000))[2:]))
3030
31 self.emit_processing()31 # self.emit_processing() # Disabled until something requires the Download interface
3232
33 @property33 @property
34 def id(self):34 def id(self):
3535
=== modified file 'python/libertine/service/task_dispatcher.py'
--- python/libertine/service/task_dispatcher.py 2016-11-01 18:50:32 +0000
+++ python/libertine/service/task_dispatcher.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -24,7 +24,6 @@
24 def __init__(self, connection):24 def __init__(self, connection):
25 self._connection = connection25 self._connection = connection
26 self._config = libertine.ContainersConfig.ContainersConfig()26 self._config = libertine.ContainersConfig.ContainersConfig()
27 self._lock = Lock()
28 self._containerless_tasks = []27 self._containerless_tasks = []
29 self._tasks = []28 self._tasks = []
30 self._containers = []29 self._containers = []
@@ -35,7 +34,7 @@
35 self._tasks.remove(task)34 self._tasks.remove(task)
3635
37 def _cleanup_container(self, container):36 def _cleanup_container(self, container):
38 utils.get_logger().debug("cleaning up container '%s'" % container)37 utils.get_logger().debug("cleaning up container '%s'" % container.id)
39 if container in self._containers:38 if container in self._containers:
40 self._containers.remove(container)39 self._containers.remove(container)
4140
@@ -45,7 +44,7 @@
45 if container is not None:44 if container is not None:
46 utils.get_logger().debug("using existing container '%s'" % container_id)45 utils.get_logger().debug("using existing container '%s'" % container_id)
47 return container46 return container
48 container = Container(container_id, self._config, self._lock, self._connection, self._cleanup_container)47 container = Container(container_id, self._config, self._connection, self._cleanup_container)
49 self._containers.append(container)48 self._containers.append(container)
5049
51 return container50 return container
@@ -89,6 +88,10 @@
89 utils.get_logger().debug("dispatching list all apps in container '%s'" % container_id)88 utils.get_logger().debug("dispatching list all apps in container '%s'" % container_id)
90 return self._find_or_create_container(container_id).list_apps()89 return self._find_or_create_container(container_id).list_apps()
9190
91 def list_app_ids(self, container_id):
92 utils.get_logger().debug("dispatching list apps ids in container '%s'" % container_id)
93 return self._find_or_create_container(container_id).list_app_ids()
94
92 # Containerless Tasks95 # Containerless Tasks
9396
94 def container_info(self, container_id):97 def container_info(self, container_id):
@@ -107,7 +110,7 @@
107 def list(self):110 def list(self):
108 utils.get_logger().debug("dispatching list all containers")111 utils.get_logger().debug("dispatching list all containers")
109112
110 task = ListTask(self._connection, self._cleanup_task)113 task = ListTask(self._config, self._connection, self._cleanup_task)
111 self._tasks.append(task)114 self._tasks.append(task)
112 task.start()115 task.start()
113116
114117
=== modified file 'python/libertine/service/tasks/__init__.py'
--- python/libertine/service/tasks/__init__.py 2016-11-01 17:38:38 +0000
+++ python/libertine/service/tasks/__init__.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify it3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published4# under the terms of the GNU General Public License version 3, as published
@@ -23,6 +23,7 @@
23from .update_task import UpdateTask23from .update_task import UpdateTask
24from .list_task import ListTask24from .list_task import ListTask
25from .list_apps_task import ListAppsTask25from .list_apps_task import ListAppsTask
26from .list_app_ids_task import ListAppIdsTask
2627
27__all__ = [28__all__ = [
28 'AppInfoTask',29 'AppInfoTask',
@@ -35,5 +36,6 @@
35 'SearchTask',36 'SearchTask',
36 'UpdateTask',37 'UpdateTask',
37 'ListTask',38 'ListTask',
38 'ListAppsTask'39 'ListAppsTask',
40 'ListAppIdsTask'
39 ]41 ]
4042
=== modified file 'python/libertine/service/tasks/base_task.py'
--- python/libertine/service/tasks/base_task.py 2016-11-07 20:37:54 +0000
+++ python/libertine/service/tasks/base_task.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -15,7 +15,6 @@
15import libertine.service.progress15import libertine.service.progress
16import threading16import threading
17from abc import ABCMeta, abstractmethod17from abc import ABCMeta, abstractmethod
18from libertine import utils
1918
2019
21class BaseTask(metaclass=ABCMeta):20class BaseTask(metaclass=ABCMeta):
@@ -60,7 +59,7 @@
60 if self._instant_callback:59 if self._instant_callback:
61 self._callback(self)60 self._callback(self)
62 else:61 else:
63 threading.Timer(30, lambda: self._callback(self)).start()62 threading.Timer(10, lambda: self._callback(self)).start()
6463
65 def start(self):64 def start(self):
66 self._progress = libertine.service.progress.Progress(self._connection)65 self._progress = libertine.service.progress.Progress(self._connection)
@@ -82,7 +81,6 @@
8281
83 if self.running:82 if self.running:
84 self._progress.finished(self.container)83 self._progress.finished(self.container)
85 utils.refresh_libertine_scope()
8684
87 self._delayed_callback()85 self._delayed_callback()
8886
8987
=== modified file 'python/libertine/service/tasks/container_info_task.py'
--- python/libertine/service/tasks/container_info_task.py 2016-11-01 17:38:38 +0000
+++ python/libertine/service/tasks/container_info_task.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -13,6 +13,8 @@
13# along with this program. If not, see <http://www.gnu.org/licenses/>.13# along with this program. If not, see <http://www.gnu.org/licenses/>.
1414
1515
16import json
17
16from .base_task import BaseTask18from .base_task import BaseTask
17from libertine import utils19from libertine import utils
1820
@@ -23,7 +25,21 @@
23 self._tasks = tasks25 self._tasks = tasks
2426
25 def _run(self):27 def _run(self):
26 container = {'id': str(self._container)}28 utils.get_logger().debug("Gathering info for container '{}'".format(self._container))
27 container['status'] = self._config._get_value_by_key(self._container, 'installStatus') or ''29 container = {'id': str(self._container), 'task_ids': self._tasks}
28 container['task_ids'] = self._tasks30
29 self._progress.data(str(container))31 container['status'] = self._config.get_container_install_status(self._container) or ''
32 container['name'] = self._config.get_container_name(self._container) or ''
33
34 container_type = self._config.get_container_type(self._container)
35 container['root'] = utils.get_libertine_container_rootfs_path(self._container)
36 container['home'] = utils.get_libertine_container_home_dir(self._container)
37
38 self._progress.data(json.dumps(container))
39
40 def _before(self):
41 if not self._config.container_exists(self._container):
42 self._progress.error("Container '%s' does not exist, ignoring info request" % self._container)
43 return False
44
45 return True
3046
=== added file 'python/libertine/service/tasks/list_app_ids_task.py'
--- python/libertine/service/tasks/list_app_ids_task.py 1970-01-01 00:00:00 +0000
+++ python/libertine/service/tasks/list_app_ids_task.py 2017-01-27 18:57:35 +0000
@@ -0,0 +1,35 @@
1# Copyright 2017 Canonical Ltd.
2#
3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; version 3 of the License.
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program. If not, see <http://www.gnu.org/licenses/>.
14
15
16import json
17from .base_task import BaseTask
18from libertine import LibertineContainer, utils
19import time
20
21
22class ListAppIdsTask(BaseTask):
23 def __init__(self, container_id, config, connection, callback):
24 super().__init__(lock=None, container_id=container_id, config=config, connection=connection, callback=callback)
25
26 def _run(self):
27 utils.get_logger().debug("Listing app ids from container '%s'" % self._container)
28 self._progress.data(json.dumps(LibertineContainer(self._container, self._config).list_app_ids()))
29
30 def _before(self):
31 if not self._config.container_exists(self._container):
32 self._progress.error("Container '%s' does not exist, skipping list" % self._container)
33 return False
34
35 return True
036
=== modified file 'python/libertine/service/tasks/list_apps_task.py'
--- python/libertine/service/tasks/list_apps_task.py 2016-11-01 17:38:38 +0000
+++ python/libertine/service/tasks/list_apps_task.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -23,8 +23,12 @@
2323
24 def _run(self):24 def _run(self):
25 utils.get_logger().debug("Listing apps in container '%s'" % self._container)25 utils.get_logger().debug("Listing apps in container '%s'" % self._container)
26 container = LibertineContainer(self._container, self._config)
27 self._progress.data(str(container.list_app_launchers(use_json=True)))
28
29 def _before(self):
26 if not self._config.container_exists(self._container):30 if not self._config.container_exists(self._container):
27 self._progress.error("Container '%s' does not exist, skipping list" % self._container)31 self._progress.error("Container '%s' does not exist, skipping list" % self._container)
28 else:32 return False
29 container = LibertineContainer(self._container, self._config)33
30 self._progress.data(str(container.list_app_launchers(use_json=True)))34 return True
3135
=== modified file 'python/libertine/service/tasks/list_task.py'
--- python/libertine/service/tasks/list_task.py 2016-11-01 18:50:32 +0000
+++ python/libertine/service/tasks/list_task.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -13,13 +13,15 @@
13# along with this program. If not, see <http://www.gnu.org/licenses/>.13# along with this program. If not, see <http://www.gnu.org/licenses/>.
1414
1515
16import json
17
16from .base_task import BaseTask18from .base_task import BaseTask
17from libertine import utils19from libertine import utils
1820
1921
20class ListTask(BaseTask):22class ListTask(BaseTask):
21 def __init__(self, connection, callback):23 def __init__(self, config, connection, callback):
22 super().__init__(lock=None, container_id=None, config=None, connection=connection, callback=callback)24 super().__init__(lock=None, container_id=None, config=config, connection=connection, callback=callback)
2325
24 def _run(self):26 def _run(self):
25 self._progress.data(str(utils.Libertine.list_containers()))27 self._progress.data(json.dumps(self._config.get_containers()))
2628
=== modified file 'python/libertine/utils.py'
--- python/libertine/utils.py 2017-01-18 21:07:39 +0000
+++ python/libertine/utils.py 2017-01-27 18:57:35 +0000
@@ -1,6 +1,6 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
22
3# Copyright (C) 2015-2016 Canonical Ltd.3# Copyright (C) 2015-2017 Canonical Ltd.
4# Author: Christopher Townsend <christopher.townsend@canonical.com>4# Author: Christopher Townsend <christopher.townsend@canonical.com>
55
6# This program is free software: you can redistribute it and/or modify6# This program is free software: you can redistribute it and/or modify
@@ -22,10 +22,6 @@
22import subprocess22import subprocess
23import xdg.BaseDirectory as basedir23import xdg.BaseDirectory as basedir
2424
25from gi import require_version
26require_version('Libertine', '1')
27from gi.repository import Libertine
28
2925
30def get_logger():26def get_logger():
31 logger = logging.getLogger('__libertine_logger__')27 logger = logging.getLogger('__libertine_logger__')
@@ -64,12 +60,7 @@
6460
6561
66def get_libertine_container_rootfs_path(container_id):62def get_libertine_container_rootfs_path(container_id):
67 path = Libertine.container_path(container_id)63 return os.path.join(get_libertine_containers_dir_path(), container_id, 'rootfs')
68
69 if path is None:
70 path = os.path.join(get_libertine_containers_dir_path(), container_id, 'rootfs')
71
72 return path
7364
7465
75def get_libertine_containers_dir_path():66def get_libertine_containers_dir_path():
@@ -100,11 +91,8 @@
100 return os.path.join(get_libertine_database_dir_path(), 'ContainersConfig.json')91 return os.path.join(get_libertine_database_dir_path(), 'ContainersConfig.json')
10192
10293
103def get_libertine_container_userdata_dir_path(container_id):94def get_libertine_container_home_dir(container_id):
104 path = Libertine.container_home_path(container_id)95 path = os.path.join(basedir.xdg_data_home, 'libertine-container', 'user-data', container_id)
105
106 if path is None:
107 path = os.path.join(basedir.xdg_data_home, 'libertine-container', 'user-data', container_id)
10896
109 if is_snap_environment():97 if is_snap_environment():
110 path = path.replace(os.environ['HOME'], os.getenv('SNAP_USER_COMMON'))98 path = path.replace(os.environ['HOME'], os.getenv('SNAP_USER_COMMON'))
@@ -153,18 +141,6 @@
153 return dirs141 return dirs
154142
155143
156def create_libertine_user_data_dir(container_id):
157 user_data = get_libertine_container_userdata_dir_path(container_id)
158
159 if not os.path.exists(user_data):
160 os.makedirs(user_data)
161
162 config_path = os.path.join(user_data, ".config", "dconf")
163
164 if not os.path.exists(config_path):
165 os.makedirs(config_path)
166
167
168def get_libertine_lxc_pulse_socket_path():144def get_libertine_lxc_pulse_socket_path():
169 return os.path.join(get_libertine_runtime_dir(), 'pulse_socket')145 return os.path.join(get_libertine_runtime_dir(), 'pulse_socket')
170146
@@ -194,14 +170,17 @@
194170
195 if not dbus_session_set:171 if not dbus_session_set:
196 for p in psutil.process_iter():172 for p in psutil.process_iter():
197 if p.name() == 'unity8' or p.name() == 'compiz':173 try:
198 p_environ = subprocess.check_output(["cat", "/proc/{}/environ".format(p.pid)])174 if p.name() == 'unity8' or p.name() == 'compiz':
199 for line in p_environ.decode().split('\0'):175 p_environ = subprocess.check_output(["cat", "/proc/{}/environ".format(p.pid)])
200 if line.startswith('DBUS_SESSION_BUS_ADDRESS'):176 for line in p_environ.decode().split('\0'):
201 os.environ['DBUS_SESSION_BUS_ADDRESS'] = line.partition('DBUS_SESSION_BUS_ADDRESS=')[2].rstrip('\n')177 if line.startswith('DBUS_SESSION_BUS_ADDRESS'):
202 dbus_session_set = True178 os.environ['DBUS_SESSION_BUS_ADDRESS'] = line.partition('DBUS_SESSION_BUS_ADDRESS=')[2].rstrip('\n')
203 break179 dbus_session_set = True
204 break180 break
181 break
182 except psutil.NoSuchProcess as e:
183 get_logger().warning(str(e))
205184
206 return dbus_session_set185 return dbus_session_set
207186
208187
=== modified file 'snapcraft.yaml'
--- snapcraft.yaml 2017-01-23 15:21:46 +0000
+++ snapcraft.yaml 2017-01-27 18:57:35 +0000
@@ -3,9 +3,15 @@
3summary: Libertine suite3summary: Libertine suite
4description: |4description: |
5 Suite for maintaining deb-based applications in a non-deb environment5 Suite for maintaining deb-based applications in a non-deb environment
6confinement: devmode # TODO: update to 'strict'6confinement: strict # devmode # TODO: update to 'strict'
7grade: devel7grade: devel
88
9slots:
10 libertined:
11 interface: dbus
12 name: com.canonical.libertine.Service
13 bus: session
14
9apps:15apps:
10 launch:16 launch:
11 command: usr/bin/snap-runner.wrapper libertine-launch17 command: usr/bin/snap-runner.wrapper libertine-launch
@@ -22,6 +28,12 @@
22 - opengl28 - opengl
23 - pulseaudio29 - pulseaudio
24 - alsa30 - alsa
31 libertined:
32 command: usr/bin/snap-runner.wrapper libertined
33 plugs:
34 - lxd
35 - network-bind
36 # daemon: simple # Waiting on LP:1613420
25 container-manager:37 container-manager:
26 command: usr/bin/snap-runner.wrapper libertine-container-manager38 command: usr/bin/snap-runner.wrapper libertine-container-manager
27 aliases:39 aliases:
2840
=== modified file 'tests/integration/test_libertine_service.py'
--- tests/integration/test_libertine_service.py 2016-11-29 17:38:38 +0000
+++ tests/integration/test_libertine_service.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify it3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published4# under the terms of the GNU General Public License version 3, as published
@@ -12,20 +12,24 @@
12# You should have received a copy of the GNU General Public License along12# You should have received a copy of the GNU General Public License along
13# with this program. If not, see <http://www.gnu.org/licenses/>.13# with this program. If not, see <http://www.gnu.org/licenses/>.
1414
15
16import ast
15import dbus17import dbus
16import dbus.mainloop.glib18import dbus.mainloop.glib
19import os
20import tempfile
21import threading
22import time
17import unittest.mock23import unittest.mock
18from unittest import TestCase24
25from gi.repository import GLib
26from gi.repository import GObject
27from libertine import utils
19from libertine.service import tasks, apt28from libertine.service import tasks, apt
20from libertine.ContainersConfig import ContainersConfig29from libertine.ContainersConfig import ContainersConfig
21from subprocess import Popen, PIPE30from subprocess import Popen, PIPE
22import time31from unittest import TestCase
23from gi.repository import GLib32
24from gi.repository import GObject
25import os
26import tempfile
27import threading
28import ast
2933
30class TestLibertineService(TestCase):34class TestLibertineService(TestCase):
31 _process = None35 _process = None
@@ -39,6 +43,7 @@
3943
40 environ = os.environ.copy()44 environ = os.environ.copy()
41 environ['XDG_DATA_HOME'] = cls._tempdir.name45 environ['XDG_DATA_HOME'] = cls._tempdir.name
46
42 cls._process = Popen(['libertined', '--debug'], stdout=PIPE, stderr=PIPE, env=environ)47 cls._process = Popen(['libertined', '--debug'], stdout=PIPE, stderr=PIPE, env=environ)
43 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)48 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
44 cls._loop = GObject.MainLoop()49 cls._loop = GObject.MainLoop()
@@ -91,7 +96,7 @@
91 signals.append(self._bus.add_signal_receiver(path=obj_path, handler_function=self._finished_handler,96 signals.append(self._bus.add_signal_receiver(path=obj_path, handler_function=self._finished_handler,
92 dbus_interface='com.canonical.applications.Download', signal_name='finished'))97 dbus_interface='com.canonical.applications.Download', signal_name='finished'))
93 signals.append(self._bus.add_signal_receiver(path=obj_path, handler_function=self._data_handler,98 signals.append(self._bus.add_signal_receiver(path=obj_path, handler_function=self._data_handler,
94 dbus_interface='com.canonical.libertine.Progress', signal_name='data'))99 dbus_interface='com.canonical.libertine.Service.Progress', signal_name='data'))
95 signals.append(self._bus.add_signal_receiver(path=obj_path, handler_function=self._error_handler,100 signals.append(self._bus.add_signal_receiver(path=obj_path, handler_function=self._error_handler,
96 dbus_interface='com.canonical.applications.Download', signal_name='error'))101 dbus_interface='com.canonical.applications.Download', signal_name='error'))
97102
@@ -110,20 +115,25 @@
110115
111 def test_container_management(self):116 def test_container_management(self):
112 try:117 try:
113 self.assertEqual('[]', self._send(lambda: self._libertined.list()))118 self.assertEqual([], ast.literal_eval(self._send(lambda: self._libertined.list())))
114 self._send(lambda: self._libertined.create('rey', 'Rey', 'xenial', 'mock'))119 self._send(lambda: self._libertined.create('rey', 'Rey', 'xenial', 'mock'))
115 self.assertEqual('[\'rey\']', self._send(lambda: self._libertined.list()))120 self.assertEqual(['rey'], ast.literal_eval(self._send(lambda: self._libertined.list())))
116121
117 self._send(lambda: self._libertined.create('kylo', 'Kylo Ren', 'xenial', 'mock'))122 self._send(lambda: self._libertined.create('kylo', 'Kylo Ren', 'xenial', 'mock'))
118 self.assertEqual('[\'rey\', \'kylo\']', self._send(lambda: self._libertined.list()))123 self.assertEqual(['rey', 'kylo'], ast.literal_eval(self._send(lambda: self._libertined.list())))
119124
120 self._send(lambda: self._libertined.update('kylo'))125 self._send(lambda: self._libertined.update('kylo'))
121126
122 self.assertEqual({'id': 'rey', 'status': 'ready', 'task_ids': []},127 self.assertEqual({'id': 'rey',
123 ast.literal_eval(self._send(lambda: self._libertined.container_info('rey'))))128 'status': 'ready',
129 'name': 'Rey',
130 'task_ids': [],
131 'root': utils.get_libertine_container_rootfs_path('rey'),
132 'home': '{}/libertine-container/user-data/rey'.format(TestLibertineService._tempdir.name)
133 }, ast.literal_eval(self._send(lambda: self._libertined.container_info('rey'))))
124134
125 self._send(lambda: self._libertined.destroy('kylo'))135 self._send(lambda: self._libertined.destroy('kylo'))
126 self.assertEqual('[\'rey\']', self._send(lambda: self._libertined.list()))136 self.assertEqual(['rey'], ast.literal_eval(self._send(lambda: self._libertined.list())))
127 except AssertionError as e:137 except AssertionError as e:
128 raise138 raise
129 except Exception as e:139 except Exception as e:
130140
=== added directory 'tests/unit/service/containerroot/libertine-container'
=== added directory 'tests/unit/service/containerroot/libertine-container/palpatine'
=== added directory 'tests/unit/service/containerroot/libertine-container/palpatine/rootfs'
=== modified file 'tests/unit/service/tasks/CMakeLists.txt'
--- tests/unit/service/tasks/CMakeLists.txt 2016-11-01 19:49:32 +0000
+++ tests/unit/service/tasks/CMakeLists.txt 2017-01-27 18:57:35 +0000
@@ -5,6 +5,7 @@
5create_service_unit_test(test_install_task)5create_service_unit_test(test_install_task)
6create_service_unit_test(test_list_task)6create_service_unit_test(test_list_task)
7create_service_unit_test(test_list_apps_task)7create_service_unit_test(test_list_apps_task)
8create_service_unit_test(test_list_app_ids_task)
8create_service_unit_test(test_remove_task)9create_service_unit_test(test_remove_task)
9create_service_unit_test(test_search_task)10create_service_unit_test(test_search_task)
10create_service_unit_test(test_update_task)11create_service_unit_test(test_update_task)
1112
=== modified file 'tests/unit/service/tasks/test_container_info_task.py'
--- tests/unit/service/tasks/test_container_info_task.py 2016-11-07 18:51:17 +0000
+++ tests/unit/service/tasks/test_container_info_task.py 2017-01-27 18:57:35 +0000
@@ -13,8 +13,10 @@
13# with this program. If not, see <http://www.gnu.org/licenses/>.13# with this program. If not, see <http://www.gnu.org/licenses/>.
1414
1515
16import ast
16import unittest.mock17import unittest.mock
17from unittest import TestCase18from unittest import TestCase
19from libertine import utils
18from libertine.service import tasks20from libertine.service import tasks
19from libertine.ContainersConfig import ContainersConfig21from libertine.ContainersConfig import ContainersConfig
2022
@@ -33,12 +35,22 @@
33 progress = MockProgress.return_value35 progress = MockProgress.return_value
34 progress.done = False36 progress.done = False
3537
36 self.config._get_value_by_key.return_value = 'ready'38 self.config.get_container_install_status.return_value = 'ready'
39 self.config.get_container_name.return_value = 'Palpatine'
37 task = tasks.ContainerInfoTask('palpatine', [1, 2, 3], self.config, self.connection, callback)40 task = tasks.ContainerInfoTask('palpatine', [1, 2, 3], self.config, self.connection, callback)
38 task._instant_callback = True41 task._instant_callback = True
39 task.start().join()42 task.start().join()
4043
41 progress.data.assert_called_once_with(str({'id': 'palpatine', 'status': 'ready', 'task_ids': [1, 2, 3]}))44 progress.data.assert_called_once_with(unittest.mock.ANY)
45 args, kwargs = progress.data.call_args
46 self.assertEqual({'id': 'palpatine',
47 'status': 'ready',
48 'task_ids': [1, 2, 3],
49 'name': 'Palpatine',
50 'root': utils.get_libertine_container_rootfs_path('palpatine'),
51 'home': utils.get_libertine_container_home_dir('palpatine')},
52 ast.literal_eval(args[0]))
53
42 progress.finished.assert_called_once_with('palpatine')54 progress.finished.assert_called_once_with('palpatine')
4355
44 self.assertEqual(task, self.called_with)56 self.assertEqual(task, self.called_with)
4557
=== added file 'tests/unit/service/tasks/test_list_app_ids_task.py'
--- tests/unit/service/tasks/test_list_app_ids_task.py 1970-01-01 00:00:00 +0000
+++ tests/unit/service/tasks/test_list_app_ids_task.py 2017-01-27 18:57:35 +0000
@@ -0,0 +1,59 @@
1# Copyright 2017 Canonical Ltd.
2#
3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published
5# by the Free Software Foundation.
6#
7# This program is distributed in the hope that it will be useful, but
8# WITHOUT ANY WARRANTY; without even the implied warranties of
9# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10# PURPOSE. See the GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License along
13# with this program. If not, see <http://www.gnu.org/licenses/>.
14
15import json
16import unittest.mock
17from unittest import TestCase
18from libertine.service import tasks
19from libertine.ContainersConfig import ContainersConfig
20
21
22class TestListAppIdsTask(TestCase):
23 def setUp(self):
24 self.config = unittest.mock.create_autospec(ContainersConfig)
25 self.connection = unittest.mock.Mock()
26 self.lock = unittest.mock.MagicMock()
27 self.called_with = None
28
29 def callback(self, task):
30 self.called_with = task
31
32 def test_sends_error_on_non_existent_container(self):
33 self.config.container_exists.return_value = False
34 with unittest.mock.patch('libertine.service.tasks.base_task.libertine.service.progress.Progress') as MockProgress:
35 progress = MockProgress.return_value
36 task = tasks.ListAppIdsTask('palpatine', self.config, self.connection, self.callback)
37 task._instant_callback = True
38
39 with unittest.mock.patch('libertine.service.tasks.list_apps_task.LibertineContainer') as MockContainer:
40 task.start().join()
41
42 progress.error.assert_called_once_with('Container \'palpatine\' does not exist, skipping list')
43 self.assertEqual(task, self.called_with)
44
45 def test_successfully_lists_apps(self):
46 self.config.container_exists.return_value = True
47 with unittest.mock.patch('libertine.service.tasks.base_task.libertine.service.progress.Progress') as MockProgress:
48 progress = MockProgress.return_value
49 progress.done = False
50 task = tasks.ListAppIdsTask('palpatine', self.config, self.connection, self.callback)
51 task._instant_callback = True
52
53 with unittest.mock.patch('libertine.service.tasks.list_app_ids_task.LibertineContainer') as MockContainer:
54 MockContainer.return_value.list_app_ids.return_value = '["palpatine_gedit_0.0","palpatine_xterm_0.0"]'
55 task.start().join()
56
57 progress.finished.assert_called_once_with('palpatine')
58 progress.data.assert_called_once_with(json.dumps('["palpatine_gedit_0.0","palpatine_xterm_0.0"]'))
59 self.assertEqual(task, self.called_with)
060
=== modified file 'tests/unit/service/tasks/test_list_task.py'
--- tests/unit/service/tasks/test_list_task.py 2016-11-07 18:51:17 +0000
+++ tests/unit/service/tasks/test_list_task.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify it3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published4# under the terms of the GNU General Public License version 3, as published
@@ -13,7 +13,9 @@
13# with this program. If not, see <http://www.gnu.org/licenses/>.13# with this program. If not, see <http://www.gnu.org/licenses/>.
1414
1515
16import json
16import unittest.mock17import unittest.mock
18
17from unittest import TestCase19from unittest import TestCase
18from libertine.service import tasks20from libertine.service import tasks
19from libertine.ContainersConfig import ContainersConfig21from libertine.ContainersConfig import ContainersConfig
@@ -32,14 +34,14 @@
32 with unittest.mock.patch('libertine.service.tasks.base_task.libertine.service.progress.Progress') as MockProgress:34 with unittest.mock.patch('libertine.service.tasks.base_task.libertine.service.progress.Progress') as MockProgress:
33 progress = MockProgress.return_value35 progress = MockProgress.return_value
34 progress.done = False36 progress.done = False
35 task = tasks.ListTask(self.connection, callback)37
38 task = tasks.ListTask(self.config, self.connection, callback)
36 task._instant_callback = True39 task._instant_callback = True
3740
38 with unittest.mock.patch('libertine.service.tasks.list_task.utils.Libertine') as MockLibertine:41 self.config.get_containers.return_value = ['palatine', 'vader', 'maul']
39 MockLibertine.list_containers.return_value = 'palpatine\nvader\nmaul'42 task.start().join()
40 task.start().join()
4143
42 progress.data.assert_called_once_with('palpatine\nvader\nmaul')44 progress.data.assert_called_once_with(json.dumps(['palatine', 'vader', 'maul']))
43 progress.finished.assert_called_once_with('')45 progress.finished.assert_called_once_with('')
4446
45 self.assertEqual(task, self.called_with)47 self.assertEqual(task, self.called_with)
4648
=== modified file 'tests/unit/service/test_apt.py'
--- tests/unit/service/test_apt.py 2016-11-03 20:10:47 +0000
+++ tests/unit/service/test_apt.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify it3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published4# under the terms of the GNU General Public License version 3, as published
@@ -14,8 +14,9 @@
1414
15import os15import os
16import unittest.mock16import unittest.mock
17from libertine import utils
18from libertine.service import apt
17from unittest import TestCase19from unittest import TestCase
18from libertine.service import apt
1920
2021
21def build_mock_app(name, summary, website, description):22def build_mock_app(name, summary, website, description):
@@ -30,13 +31,13 @@
3031
3132
32class TestAptCache(TestCase):33class TestAptCache(TestCase):
34 def setUp(self):
35 os.environ['XDG_CACHE_HOME'] = "{}/containerroot".format(os.environ['LIBERTINE_DATA_DIR'])
36
33 def test_search_returns_empty_when_no_matching_results(self):37 def test_search_returns_empty_when_no_matching_results(self):
34 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:38 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:
35 MockCache.return_value.keys.return_value = []39 MockCache.return_value.keys.return_value = []
3640 self.assertEqual(apt.AptCache('palpatine').search('vim'), [])
37 with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine:
38 MockLibertine.container_path.return_value = '/some/junk'
39 self.assertEqual(apt.AptCache('palpatine').search('vim'), [])
4041
41 def test_search_returns_matching_results(self):42 def test_search_returns_matching_results(self):
42 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:43 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:
@@ -47,9 +48,7 @@
47 "vim-common": build_mock_app("vim-common", "common vim stuff", "vim.common", "dependencies")48 "vim-common": build_mock_app("vim-common", "common vim stuff", "vim.common", "dependencies")
48 }49 }
4950
50 with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine:51 results = apt.AptCache('palpatine').search('vim')
51 MockLibertine.container_path.return_value = '/some/junk'
52 results = apt.AptCache('palpatine').search('vim')
5352
54 self.assertEqual(len(results), 2)53 self.assertEqual(len(results), 2)
55 results = sorted(results, key=lambda xx: xx['id'])54 results = sorted(results, key=lambda xx: xx['id'])
@@ -67,15 +66,13 @@
67 self.assertEqual(results[1]['website'], 'vim.common')66 self.assertEqual(results[1]['website'], 'vim.common')
68 self.assertEqual(results[1]['package'], 'vim-common')67 self.assertEqual(results[1]['package'], 'vim-common')
6968
70 MockCache.assert_called_once_with()69 MockCache.assert_called_once_with(rootdir=utils.get_libertine_container_rootfs_path('palpatine'))
7170
72 def test_app_info_returns_empty_dict_when_no_such_app_exists(self):71 def test_app_info_returns_empty_dict_when_no_such_app_exists(self):
73 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:72 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:
74 MockCache.return_value = {}73 MockCache.return_value = {}
75 with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine:74 self.assertEqual(apt.AptCache('palpatine').app_info("vim"), {})
76 MockLibertine.container_path.return_value = '/some/junk'75 MockCache.assert_called_once_with(rootdir=utils.get_libertine_container_rootfs_path('palpatine'))
77 self.assertEqual(apt.AptCache('palpatine').app_info("vim"), {})
78 MockCache.assert_called_once_with()
7976
80 def test_app_info_returns_values_for_app(self):77 def test_app_info_returns_values_for_app(self):
81 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:78 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:
@@ -83,17 +80,15 @@
83 "vim": build_mock_app("vim", "vi improved", "vim.com", "who even uses raw vi"),80 "vim": build_mock_app("vim", "vi improved", "vim.com", "who even uses raw vi"),
84 "gimp": build_mock_app("gimp", "foss photoshop", "gimp.com", "visual text editor"),81 "gimp": build_mock_app("gimp", "foss photoshop", "gimp.com", "visual text editor"),
85 }82 }
86 with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine:83 self.assertEqual(apt.AptCache('palpatine').app_info("vim"), {
87 MockLibertine.container_path.return_value = '/some/junk'84 'name': 'vim',
88 self.assertEqual(apt.AptCache('palpatine').app_info("vim"), {85 'id': 'vim',
89 'name': 'vim',86 'package': 'vim',
90 'id': 'vim',87 'summary': 'vi improved',
91 'package': 'vim',88 'description': 'who even uses raw vi',
92 'summary': 'vi improved',89 'website': 'vim.com'
93 'description': 'who even uses raw vi',90 })
94 'website': 'vim.com'91 MockCache.assert_called_once_with(rootdir=utils.get_libertine_container_rootfs_path('palpatine'))
95 })
96 MockCache.assert_called_once_with()
9792
98 def test_loads_cache_from_container_directory(self):93 def test_loads_cache_from_container_directory(self):
99 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:94 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:
@@ -101,19 +96,17 @@
101 "vim": build_mock_app("vim", "vi improved", "vim.com", "who even uses raw vi"),96 "vim": build_mock_app("vim", "vi improved", "vim.com", "who even uses raw vi"),
102 "gimp": build_mock_app("gimp", "foss photoshop", "gimp.com", "visual text editor"),97 "gimp": build_mock_app("gimp", "foss photoshop", "gimp.com", "visual text editor"),
103 }98 }
104 with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine:99
105 containerpath = "%s/containerroot" % os.path.dirname(os.path.realpath(__file__))100 self.assertEqual(apt.AptCache('palpatine').app_info("vim"), {
106 MockLibertine.container_path.return_value = containerpath101 'name': 'vim',
107 self.assertEqual(apt.AptCache('palpatine').app_info("vim"), {102 'id': 'vim',
108 'name': 'vim',103 'package': 'vim',
109 'id': 'vim',104 'summary': 'vi improved',
110 'package': 'vim',105 'description': 'who even uses raw vi',
111 'summary': 'vi improved',106 'website': 'vim.com'
112 'description': 'who even uses raw vi',107 })
113 'website': 'vim.com'108
114 })109 MockCache.assert_called_once_with(rootdir=utils.get_libertine_container_rootfs_path('palpatine'))
115
116 MockCache.assert_called_once_with(rootdir=containerpath)
117110
118 def test_loads_cache_only_once(self):111 def test_loads_cache_only_once(self):
119 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:112 with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache:
@@ -121,13 +114,12 @@
121 "vim": build_mock_app("vim", "vi improved", "vim.com", "who even uses raw vi"),114 "vim": build_mock_app("vim", "vi improved", "vim.com", "who even uses raw vi"),
122 "gimp": build_mock_app("gimp", "foss photoshop", "gimp.com", "visual text editor"),115 "gimp": build_mock_app("gimp", "foss photoshop", "gimp.com", "visual text editor"),
123 }116 }
124 with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine:117
125 MockLibertine.container_path.return_value = '/some/junk'118 cache = apt.AptCache('palpatine')
126 cache = apt.AptCache('palpatine')119 cache.app_info("vim")
127 cache.app_info("vim")120 cache.app_info("vim")
128 cache.app_info("vim")121
129122 MockCache.assert_called_once_with(rootdir=utils.get_libertine_container_rootfs_path('palpatine'))
130 MockCache.assert_called_once_with()
131123
132124
133if __name__ == '__main__':125if __name__ == '__main__':
134126
=== modified file 'tests/unit/service/test_container.py'
--- tests/unit/service/test_container.py 2016-11-04 15:54:34 +0000
+++ tests/unit/service/test_container.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify it3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published4# under the terms of the GNU General Public License version 3, as published
@@ -22,12 +22,11 @@
22 def setUp(self):22 def setUp(self):
23 self._connection = unittest.mock.Mock()23 self._connection = unittest.mock.Mock()
24 self._config = unittest.mock.Mock()24 self._config = unittest.mock.Mock()
25 self._lock = unittest.mock.Mock()
2625
27 def test_search_creates_search_task(self):26 def test_search_creates_search_task(self):
28 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:27 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
29 cache = MockCache.return_value28 cache = MockCache.return_value
30 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)29 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
31 with unittest.mock.patch('libertine.service.container.SearchTask') as MockSearchTask:30 with unittest.mock.patch('libertine.service.container.SearchTask') as MockSearchTask:
32 c.search('darkseid')31 c.search('darkseid')
33 MockSearchTask.assert_called_once_with('palpatine', cache, 'darkseid', self._connection, unittest.mock.ANY)32 MockSearchTask.assert_called_once_with('palpatine', cache, 'darkseid', self._connection, unittest.mock.ANY)
@@ -36,7 +35,7 @@
36 def test_app_info_creates_app_info_task(self):35 def test_app_info_creates_app_info_task(self):
37 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:36 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
38 cache = MockCache.return_value37 cache = MockCache.return_value
39 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)38 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
40 with unittest.mock.patch('libertine.service.container.AppInfoTask') as MockAppInfoTask:39 with unittest.mock.patch('libertine.service.container.AppInfoTask') as MockAppInfoTask:
41 c.app_info('force')40 c.app_info('force')
42 MockAppInfoTask.assert_called_once_with('palpatine', cache, 'force', [], self._config, self._connection, unittest.mock.ANY)41 MockAppInfoTask.assert_called_once_with('palpatine', cache, 'force', [], self._config, self._connection, unittest.mock.ANY)
@@ -45,7 +44,7 @@
45 def test_app_info_gets_related_task_info(self):44 def test_app_info_gets_related_task_info(self):
46 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:45 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
47 cache = MockCache.return_value46 cache = MockCache.return_value
48 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)47 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
49 with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask:48 with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask:
50 MockInstallTask.return_value.package = 'darkside'49 MockInstallTask.return_value.package = 'darkside'
51 MockInstallTask.return_value.matches.return_value = False50 MockInstallTask.return_value.matches.return_value = False
@@ -60,119 +59,115 @@
6059
61 def test_install_creates_install_task(self):60 def test_install_creates_install_task(self):
62 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:61 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
63 cache = MockCache.return_value62 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
64 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
65 with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask:63 with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask:
66 c.install('force')64 c.install('force')
67 MockInstallTask.assert_called_once_with('force', 'palpatine', self._config, self._lock, self._connection, unittest.mock.ANY)65 MockInstallTask.assert_called_once_with('force', 'palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY)
68 MockInstallTask.return_value.start.assert_called_once_with()66 MockInstallTask.return_value.start.assert_called_once_with()
6967
70 def test_install_only_calls_once_when_unfinished(self):68 def test_install_only_calls_once_when_unfinished(self):
71 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:69 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
72 cache = MockCache.return_value70 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
73 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
74 with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask:71 with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask:
75 c.install('darkside')72 c.install('darkside')
76 c.install('darkside')73 c.install('darkside')
77 c.install('darkside')74 c.install('darkside')
78 # MockInstallTask.assert_called_once_with('darkside', 'palpatine', self._config, self._lock, self._connection, unittest.mock.ANY)75 MockInstallTask.assert_called_once_with('darkside', 'palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY)
79 MockInstallTask.return_value.start.assert_called_once_with()76 MockInstallTask.return_value.start.assert_called_once_with()
8077
81 def test_remove_creates_remove_task(self):78 def test_remove_creates_remove_task(self):
82 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:79 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
83 cache = MockCache.return_value80 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
84 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
85 with unittest.mock.patch('libertine.service.container.RemoveTask') as MockRemoveTask:81 with unittest.mock.patch('libertine.service.container.RemoveTask') as MockRemoveTask:
86 c.remove('force')82 c.remove('force')
87 MockRemoveTask.assert_called_once_with('force', 'palpatine', self._config, self._lock, self._connection, unittest.mock.ANY)83 MockRemoveTask.assert_called_once_with('force', 'palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY)
88 MockRemoveTask.return_value.start.assert_called_once_with()84 MockRemoveTask.return_value.start.assert_called_once_with()
8985
90 def test_remove_only_calls_once_when_unfinished(self):86 def test_remove_only_calls_once_when_unfinished(self):
91 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:87 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
92 cache = MockCache.return_value88 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
93 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
94 with unittest.mock.patch('libertine.service.container.RemoveTask') as MockRemoveTask:89 with unittest.mock.patch('libertine.service.container.RemoveTask') as MockRemoveTask:
95 c.remove('darkside')90 c.remove('darkside')
96 c.remove('darkside')91 c.remove('darkside')
97 c.remove('darkside')92 c.remove('darkside')
98 # MockRemoveTask.assert_called_once_with('darkside', 'palpatine', self._config, self._lock, self._connection, unittest.mock.ANY)93 MockRemoveTask.assert_called_once_with('darkside', 'palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY)
99 MockRemoveTask.return_value.start.assert_called_once_with()94 MockRemoveTask.return_value.start.assert_called_once_with()
10095
101 def test_create_creates_create_task(self):96 def test_create_creates_create_task(self):
102 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:97 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
103 cache = MockCache.return_value98 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
104 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
105 with unittest.mock.patch('libertine.service.container.CreateTask') as MockCreateTask:99 with unittest.mock.patch('libertine.service.container.CreateTask') as MockCreateTask:
106 c.create('Emperor Palpatine', 'zesty', 'lxd', False)100 c.create('Emperor Palpatine', 'zesty', 'lxd', False)
107 MockCreateTask.assert_called_once_with('palpatine', 'Emperor Palpatine', 'zesty', 'lxd', False,101 MockCreateTask.assert_called_once_with('palpatine', 'Emperor Palpatine', 'zesty', 'lxd', False,
108 self._config, self._lock, self._connection, unittest.mock.ANY)102 self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY)
109 MockCreateTask.return_value.start.assert_called_once_with()103 MockCreateTask.return_value.start.assert_called_once_with()
110104
111 def test_create_only_calls_once_when_unfinished(self):105 def test_create_only_calls_once_when_unfinished(self):
112 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:106 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
113 cache = MockCache.return_value107 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
114 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
115 with unittest.mock.patch('libertine.service.container.CreateTask') as MockCreateTask:108 with unittest.mock.patch('libertine.service.container.CreateTask') as MockCreateTask:
116 c.create('Emperor Palpatine', 'zesty', 'lxd', False)109 c.create('Emperor Palpatine', 'zesty', 'lxd', False)
117 c.create('Emperor Palpatine', 'zesty', 'lxd', False)110 c.create('Emperor Palpatine', 'zesty', 'lxd', False)
118 c.create('Emperor Palpatine', 'zesty', 'lxd', False)111 c.create('Emperor Palpatine', 'zesty', 'lxd', False)
119 # MockCreateTask.assert_called_once_with('palpatine', 'Emperor Palpatine', 'zesty', 'lxd', False,112 MockCreateTask.assert_called_once_with('palpatine', 'Emperor Palpatine', 'zesty', 'lxd', False,
120 # self._config, self._lock, self._connection, unittest.mock.ANY)113 self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY)
121 MockCreateTask.return_value.start.assert_called_once_with()114 MockCreateTask.return_value.start.assert_called_once_with()
122115
123 def test_destroy_creates_destroy_task(self):116 def test_destroy_creates_destroy_task(self):
124 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:117 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
125 cache = MockCache.return_value118 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
126 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
127 with unittest.mock.patch('libertine.service.container.DestroyTask') as MockDestroyTask:119 with unittest.mock.patch('libertine.service.container.DestroyTask') as MockDestroyTask:
128 c.destroy()120 c.destroy()
129 # MockDestroyTask.assert_called_once_with('palpatine', self._config, self._lock, self._connection, unittest.mock.ANY)121 MockDestroyTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY)
130 MockDestroyTask.return_value.start.assert_called_once_with()122 MockDestroyTask.return_value.start.assert_called_once_with()
131123
132 def test_destroy_only_calls_once_when_unfinished(self):124 def test_destroy_only_calls_once_when_unfinished(self):
133 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:125 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
134 cache = MockCache.return_value126 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
135 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
136 with unittest.mock.patch('libertine.service.container.DestroyTask') as MockDestroyTask:127 with unittest.mock.patch('libertine.service.container.DestroyTask') as MockDestroyTask:
137 c.destroy()128 c.destroy()
138 c.destroy()129 c.destroy()
139 c.destroy()130 c.destroy()
140 # MockDestroyTask.assert_called_once_with('palpatine', self._config, self._lock, self._connection, unittest.mock.ANY)131 MockDestroyTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY)
141 MockDestroyTask.return_value.start.assert_called_once_with()132 MockDestroyTask.return_value.start.assert_called_once_with()
142133
143 def test_update_creates_update_task(self):134 def test_update_creates_update_task(self):
144 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:135 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
145 cache = MockCache.return_value136 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
146 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
147 with unittest.mock.patch('libertine.service.container.UpdateTask') as MockUpdateTask:137 with unittest.mock.patch('libertine.service.container.UpdateTask') as MockUpdateTask:
148 c.update()138 c.update()
149 MockUpdateTask.assert_called_once_with('palpatine', self._config, self._lock, self._connection, unittest.mock.ANY)139 MockUpdateTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY)
150 MockUpdateTask.return_value.start.assert_called_once_with()140 MockUpdateTask.return_value.start.assert_called_once_with()
151141
152 def test_update_only_calls_once_when_unfinished(self):142 def test_update_only_calls_once_when_unfinished(self):
153 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:143 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
154 cache = MockCache.return_value144 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
155 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
156 with unittest.mock.patch('libertine.service.container.UpdateTask') as MockUpdateTask:145 with unittest.mock.patch('libertine.service.container.UpdateTask') as MockUpdateTask:
157 c.update()146 c.update()
158 c.update()147 c.update()
159 c.update()148 c.update()
160 # MockUpdateTask.assert_called_once_with('palpatine', self._config, self._lock, self._connection, unittest.mock.ANY)149 MockUpdateTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY)
161 MockUpdateTask.return_value.start.assert_called_once_with()150 MockUpdateTask.return_value.start.assert_called_once_with()
162151
163 def test_list_apps_creates_list_apps_task(self):152 def test_list_apps_creates_list_apps_task(self):
164 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:153 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
165 cache = MockCache.return_value154 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
166 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
167 with unittest.mock.patch('libertine.service.container.ListAppsTask') as MockListAppsTask:155 with unittest.mock.patch('libertine.service.container.ListAppsTask') as MockListAppsTask:
168 c.list_apps()156 c.list_apps()
169 MockListAppsTask.assert_called_once_with('palpatine', self._config, self._connection, unittest.mock.ANY)157 MockListAppsTask.assert_called_once_with('palpatine', self._config, self._connection, unittest.mock.ANY)
170 MockListAppsTask.return_value.start.assert_called_once_with()158 MockListAppsTask.return_value.start.assert_called_once_with()
171159
160 def test_list_app_ids_creates_list_app_ids_task(self):
161 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
162 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
163 with unittest.mock.patch('libertine.service.container.ListAppIdsTask') as MockListAppsTask:
164 c.list_app_ids()
165 MockListAppsTask.assert_called_once_with('palpatine', self._config, self._connection, unittest.mock.ANY)
166 MockListAppsTask.return_value.start.assert_called_once_with()
167
172 def test_removes_task_during_callback(self):168 def test_removes_task_during_callback(self):
173 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:169 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
174 cache = MockCache.return_value170 c = container.Container('palpatine', self._config, self._connection, lambda task: task)
175 c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task)
176 with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask:171 with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask:
177 MockInstallTask.return_value.package = 'force'172 MockInstallTask.return_value.package = 'force'
178 c.install('force')173 c.install('force')
@@ -186,11 +181,10 @@
186181
187 def test_completing_all_tasks_fires_callback(self):182 def test_completing_all_tasks_fires_callback(self):
188 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:183 with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache:
189 cache = MockCache.return_value
190 self._container_id = None184 self._container_id = None
191 def callback(container):185 def callback(container):
192 self._container_id = container.id186 self._container_id = container.id
193 c = container.Container('palpatine', self._config, self._lock, self._connection, callback)187 c = container.Container('palpatine', self._config, self._connection, callback)
194 with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask:188 with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask:
195 c.install('force')189 c.install('force')
196 name, args, kwargs = MockInstallTask.mock_calls[0]190 name, args, kwargs = MockInstallTask.mock_calls[0]
197191
=== modified file 'tests/unit/service/test_task_dispatcher.py'
--- tests/unit/service/test_task_dispatcher.py 2016-11-03 20:20:15 +0000
+++ tests/unit/service/test_task_dispatcher.py 2017-01-27 18:57:35 +0000
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd.1# Copyright 2016-2017 Canonical Ltd.
2#2#
3# This program is free software: you can redistribute it and/or modify it3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published4# under the terms of the GNU General Public License version 3, as published
@@ -83,6 +83,13 @@
83 self.assertEqual(123, self._dispatcher.list_apps('palpatine'))83 self.assertEqual(123, self._dispatcher.list_apps('palpatine'))
84 c.list_apps.assert_called_once_with()84 c.list_apps.assert_called_once_with()
8585
86 def test_list_apps_calls_list_apps_on_container(self):
87 with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer:
88 c = MockContainer.return_value
89 c.list_app_ids.return_value = 123
90 self.assertEqual(123, self._dispatcher.list_app_ids('palpatine'))
91 c.list_app_ids.assert_called_once_with()
92
86 def test_containers_reused_on_subsequent_calls(self):93 def test_containers_reused_on_subsequent_calls(self):
87 with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer:94 with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer:
88 c = MockContainer.return_value95 c = MockContainer.return_value
@@ -90,20 +97,20 @@
90 self._dispatcher.list_apps('palpatine')97 self._dispatcher.list_apps('palpatine')
91 self._dispatcher.list_apps('palpatine')98 self._dispatcher.list_apps('palpatine')
92 self._dispatcher.list_apps('palpatine')99 self._dispatcher.list_apps('palpatine')
93 MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, unittest.mock.ANY, self._connection, unittest.mock.ANY)100 MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY)
94101
95 def test_container_callback_removes_container(self):102 def test_container_callback_removes_container(self):
96 with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer:103 with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer:
97 c = MockContainer.return_value104 c = MockContainer.return_value
98 c.id = 'palpatine'105 c.id = 'palpatine'
99 self._dispatcher.list_apps('palpatine')106 self._dispatcher.list_apps('palpatine')
100 MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, unittest.mock.ANY, self._connection, unittest.mock.ANY)107 MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY)
101 name, args, kwargs = MockContainer.mock_calls[0]108 name, args, kwargs = MockContainer.mock_calls[0]
102 args[len(args)-1](MockContainer.return_value)109 args[len(args)-1](MockContainer.return_value)
103 self._dispatcher.list_apps('palpatine')110 self._dispatcher.list_apps('palpatine')
104 MockContainer.assert_has_calls([ # verify container constructed twice111 MockContainer.assert_has_calls([ # verify container constructed twice
105 unittest.mock.call('palpatine', unittest.mock.ANY, unittest.mock.ANY, self._connection, unittest.mock.ANY),112 unittest.mock.call('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY),
106 unittest.mock.call('palpatine', unittest.mock.ANY, unittest.mock.ANY, self._connection, unittest.mock.ANY)113 unittest.mock.call('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY)
107 ], any_order=True)114 ], any_order=True)
108115
109 def test_container_info_creates_container_info_task(self):116 def test_container_info_creates_container_info_task(self):
@@ -131,13 +138,13 @@
131 task = MockListTask.return_value138 task = MockListTask.return_value
132 task.id = 123139 task.id = 123
133 self.assertEqual(123, self._dispatcher.list())140 self.assertEqual(123, self._dispatcher.list())
134 MockListTask.assert_called_once_with(self._connection, unittest.mock.ANY)141 MockListTask.assert_called_once_with(unittest.mock.ANY, self._connection, unittest.mock.ANY)
135 task.start.assert_called_once_with()142 task.start.assert_called_once_with()
136143
137 def test_containerless_tasks_are_cleaned_up(self):144 def test_containerless_tasks_are_cleaned_up(self):
138 with unittest.mock.patch('libertine.service.task_dispatcher.ListTask') as MockListTask:145 with unittest.mock.patch('libertine.service.task_dispatcher.ListTask') as MockListTask:
139 self._dispatcher.list()146 self._dispatcher.list()
140 MockListTask.assert_called_once_with(self._connection, unittest.mock.ANY)147 MockListTask.assert_called_once_with(unittest.mock.ANY, self._connection, unittest.mock.ANY)
141 name, args, kwargs = MockListTask.mock_calls[0]148 name, args, kwargs = MockListTask.mock_calls[0]
142 self.assertEqual(1, len(self._dispatcher._tasks))149 self.assertEqual(1, len(self._dispatcher._tasks))
143 args[len(args)-1](MockListTask.return_value)150 args[len(args)-1](MockListTask.return_value)
144151
=== modified file 'tests/unit/test_libertine_container.py'
--- tests/unit/test_libertine_container.py 2016-11-10 17:40:14 +0000
+++ tests/unit/test_libertine_container.py 2017-01-27 18:57:35 +0000
@@ -1,5 +1,5 @@
1"""Unit tests for the LibertineContainer interface."""1"""Unit tests for the LibertineContainer interface."""
2# Copyright 2015 Canonical Ltd.2# Copyright 2015-2017 Canonical Ltd.
3#3#
4# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
@@ -52,6 +52,7 @@
5252
53 def test_container_name_default(self):53 def test_container_name_default(self):
54 container_id = "test-id-3"54 container_id = "test-id-3"
55 self._config.get_container_name.return_value = None
55 container = Libertine.LibertineContainer(container_id, self._config)56 container = Libertine.LibertineContainer(container_id, self._config)
5657
57 self.assertThat(container.name, Equals("Unknown"))58 self.assertThat(container.name, Equals("Unknown"))
5859
=== removed file 'tests/unit/test_libertine_gir.py'
--- tests/unit/test_libertine_gir.py 2017-01-18 15:43:03 +0000
+++ tests/unit/test_libertine_gir.py 1970-01-01 00:00:00 +0000
@@ -1,65 +0,0 @@
1# Copyright 2015 Canonical Ltd.
2#
3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published
5# by the Free Software Foundation.
6#
7# This program is distributed in the hope that it will be useful, but
8# WITHOUT ANY WARRANTY; without even the implied warranties of
9# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10# PURPOSE. See the GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License along
13# with this program. If not, see <http://www.gnu.org/licenses/>.
14
15import os
16from testtools import TestCase
17from testtools.matchers import Equals
18from gi.repository import Libertine
19from unittest import skip
20from unittest.mock import patch
21
22
23class TestLibertineGir(TestCase):
24
25 def setUp(self):
26 super(TestLibertineGir, self).setUp()
27 self.cmake_source_dir = os.environ['LIBERTINE_DATA_DIR']
28
29 def test_list_containers(self):
30 with patch.dict('os.environ', {'XDG_DATA_HOME': self.cmake_source_dir + '/libertine-config', 'IGNORE_SNAP': '1'}):
31 containers = Libertine.list_containers()
32
33 self.assertThat(containers[0], Equals('wily'))
34 self.assertThat(containers[1], Equals('wily-2'))
35
36 @skip("need to work around cached globals in glib")
37 def test_container_path(self):
38 container_id = 'wily'
39 with patch.dict('os.environ', {'XDG_CACHE_HOME': self.cmake_source_dir + '/libertine-data', 'IGNORE_SNAP': '1'}):
40 container_path = Libertine.container_path(container_id)
41
42 self.assertThat(container_path, Equals(self.cmake_source_dir + '/libertine-data/libertine-container/wily/rootfs'))
43
44 def test_container_home_path(self):
45 container_id = 'wily'
46 with patch.dict('os.environ', {'XDG_DATA_HOME': self.cmake_source_dir + '/libertine-home', 'IGNORE_SNAP': '1'}):
47 container_home_path = Libertine.container_home_path(container_id)
48
49 self.assertThat(container_home_path, Equals(self.cmake_source_dir + '/libertine-home/libertine-container/user-data/wily'))
50
51 def test_container_name(self):
52 with patch.dict('os.environ', {'XDG_DATA_HOME': self.cmake_source_dir + '/libertine-config', 'IGNORE_SNAP': '1'}):
53 container_name = Libertine.container_name('wily')
54
55 self.assertThat(container_name, Equals("Ubuntu 'Wily Werewolf'"))
56
57 container_name = Libertine.container_name('wily-2')
58
59 self.assertThat(container_name, Equals("Ubuntu 'Wily Werewolf' (2)"))
60
61 def test_list_apps_for_container(self):
62 with patch.dict('os.environ', {'XDG_DATA_HOME': self.cmake_source_dir + '/libertine-config', 'IGNORE_SNAP': '1'}):
63 apps = Libertine.list_apps_for_container('wily')
64
65 self.assertThat(len(apps), Equals(0))
660
=== modified file 'tools/libertine-container-manager'
--- tools/libertine-container-manager 2017-01-25 16:27:15 +0000
+++ tools/libertine-container-manager 2017-01-27 18:57:35 +0000
@@ -218,8 +218,7 @@
218 self.containers_config.update_container_install_status(container_id, "ready")218 self.containers_config.update_container_install_status(container_id, "ready")
219219
220 def list(self, args):220 def list(self, args):
221 containers = libertine.utils.Libertine.list_containers()221 for container in ContainersConfig().get_containers():
222 for container in containers:
223 print("%s" % container)222 print("%s" % container)
224223
225 def list_apps(self, args):224 def list_apps(self, args):
226225
=== modified file 'tools/libertine-lxc-manager'
--- tools/libertine-lxc-manager 2017-01-24 20:21:16 +0000
+++ tools/libertine-lxc-manager 2017-01-27 18:57:35 +0000
@@ -83,7 +83,7 @@
83 mounts = self._sanitize_bind_mounts(libertine.utils.get_common_xdg_user_directories() + \83 mounts = self._sanitize_bind_mounts(libertine.utils.get_common_xdg_user_directories() + \
84 self._containers_config.get_container_bind_mounts(container_id))84 self._containers_config.get_container_bind_mounts(container_id))
8585
86 data_dir = libertine.utils.get_libertine_container_userdata_dir_path(container_id)86 data_dir = libertine.utils.get_libertine_container_home_dir(container_id)
87 for user_dir in libertine.utils.generate_binding_directories(mounts, self._home):87 for user_dir in libertine.utils.generate_binding_directories(mounts, self._home):
88 if os.path.isabs(user_dir[1]):88 if os.path.isabs(user_dir[1]):
89 path = user_dir[1].strip('/')89 path = user_dir[1].strip('/')

Subscribers

People subscribed via source and target branches