├── cmd ├── zsysctl │ └── zsysctl └── zsysd │ ├── cmdhandler │ └── common.go │ ├── daemon │ └── boot.go │ └── client │ ├── zsysctl.go │ └── version.go ├── debian ├── source │ ├── format │ └── lintian-overrides ├── gbp.conf ├── zsys.lintian-overrides ├── zsys.install ├── tests │ └── control ├── 90_zsys_system_autosnapshot ├── control ├── rules └── zsys.postinst ├── internal ├── machines │ └── testdata │ │ ├── testresolveorigin │ │ ├── no_dataset.golden │ │ ├── no_interesting_mountpoints.golden │ │ ├── one_dataset.golden │ │ ├── select_no_matching_dataset_mountpoints.golden │ │ ├── one_machine_with_children.golden │ │ ├── two_machines.golden │ │ ├── real_machine_no_snapshot_no_clone.golden │ │ ├── server_machine_no_snapshot_no_clone.golden │ │ ├── missing_clone_referenced_by_a_snapshot_clone_(broken_zfs).golden │ │ ├── one_machine_with_one_snapshot.golden │ │ ├── one_machine_with_one_snapshot_and_one_clone.golden │ │ ├── select_master_only.golden │ │ ├── one_machine_with_multiple_snapshots_and_clones_with_chain_of_dependency.golden │ │ ├── one_machine_with_multiple_snapshots_and_clones_with_chain_of_unordered_dependency.golden │ │ ├── select_a_particular_mountpoint.golden │ │ ├── real_machines_with_snapshots_and_clones.golden │ │ ├── server_machines_with_snapshots_and_clones.golden │ │ └── select_all_datasets_without_selecting_mountpoints.golden │ │ ├── d_no_dataset.yaml │ │ ├── confs │ │ ├── purge_all_zsys.conf │ │ ├── purge_but_previous_zsys.conf │ │ ├── default.conf │ │ ├── keep_many_snapshots.conf │ │ ├── not_enough_snapshots.conf │ │ └── one_empty_bucket.conf │ │ ├── d_no_machine.yaml │ │ ├── d_one_disabled_machine.yaml │ │ ├── d_one_machine_one_dataset_no_lastused.yaml │ │ ├── testnew │ │ ├── no_dataset.golden │ │ ├── no_machine.golden │ │ ├── one_disabled_machine.golden │ │ ├── one_machine_no_last_used.golden │ │ ├── one_machine_one_dataset_non_zsys.golden │ │ ├── one_machine_one_dataset.golden │ │ ├── selected_machine_doesn_t_exist.golden │ │ ├── one_machine_with_unordered_children.golden │ │ ├── one_machine_with_children_last_used_from_root_is_used.golden │ │ ├── one_machine_with_persistent_disabled.golden │ │ ├── user_dataset_attached_to_nothing_but_ignored_with_canmount_off.golden │ │ ├── two_machines_one_zsys_one_non_zsys.golden │ │ ├── boot_dataset_attached_to_nothing_but_ignored_with_canmount_off.golden │ │ ├── select_existing_dataset_machine.golden │ │ ├── one_machine_with_children.golden │ │ ├── user_dataset_attached_to_nothing.golden │ │ ├── one_machine_with_persistent_datasets.golden │ │ ├── boot_dataset_attached_to_nothing.golden │ │ └── select_existing_dataset_but_not_a_machine.golden │ │ ├── d_one_machine_one_dataset_non_zsys.yaml │ │ ├── d_one_machine_one_dataset.yaml │ │ ├── m_without_userdata.yaml │ │ ├── d_one_machine_with_children_unordered.yaml │ │ ├── m_with_persistent.yaml │ │ ├── m_with_userdata_only.yaml │ │ ├── d_one_machine_with_children.yaml │ │ ├── m_with_persistent_canmount_noauto.yaml │ │ ├── d_one_machine_with_children_all_with_lastused.yaml │ │ ├── m_with_userdata_only_on_other_pool.yaml │ │ ├── d_two_machines_one_dataset.yaml │ │ ├── m_with_persistent_on_another_pool.yaml │ │ ├── d_two_machines_one_zsys_one_non_zsys.yaml │ │ ├── m_with_unlinked_boot.yaml │ │ ├── m_two_machines_both_canmount_on.yaml │ │ ├── d_one_machine_with_one_snapshot.yaml │ │ ├── m_two_machines_simple.yaml │ │ ├── m_with_unlinked_boot_canmount_off.yaml │ │ ├── m_with_unlinked_userdata.yaml │ │ ├── m_with_separate_boot.yaml │ │ ├── m_with_persistent_on_bpool.yaml │ │ ├── m_without_userdata_prefer_system_pool.yaml │ │ ├── m_two_machines_with_persistent.yaml │ │ ├── m_with_unlinked_userdata_canmount_off.yaml │ │ ├── d_one_machine_with_snapshot_less_datasets.yaml │ │ ├── m_snapshot_with_persistent.yaml │ │ ├── d_one_machine_with_children_snapshot_on_subdataset.yaml │ │ ├── m_no_attached_userdata_first_pool.yaml │ │ ├── m_two_machines_recursive.yaml │ │ ├── testremovesystemstates │ │ ├── remove_non_current_state_one_dataset.golden │ │ ├── remove_non_current_state_complex_with_boot_children_and_user_datasets.golden │ │ ├── remove_multiple_states_in_correct_order.golden │ │ ├── removing_main_dataset_deletes_its_snapshots.golden │ │ ├── remove_multiple_states_with_clones_in_correct_order.golden │ │ └── snapshots_are_removed_even_if_provided_after_main_dataset.golden │ │ ├── d_one_machine_missing_clone.json │ │ ├── d_one_machine_with_clone_named_before.yaml │ │ ├── m_no_attached_userdata_second_pool.yaml │ │ ├── m_with_userdata_no_zsys.yaml │ │ ├── m_with_userdata.yaml │ │ ├── d_one_machine_with_clone_dataset.yaml │ │ ├── d_one_machine_with_clone_to_promote.yaml │ │ ├── gc_system_with_unlinked_users.yaml │ │ ├── m_with_userdata_on_other_pool.yaml │ │ ├── m_with_userdata_children_on_system.yaml │ │ ├── m_with_userdata_children_on_user.yaml │ │ ├── d_one_machine_with_snapshot_more_datasets.yaml │ │ ├── m_two_machines_with_separate_boot.yaml │ │ ├── m_clone_simple_with_manual_clone.yaml │ │ ├── m_with_userdata_child_associated_one_state.yaml │ │ ├── m_clone_with_persistent.yaml │ │ ├── m_with_userdata_user_snapshot.yaml │ │ ├── m_with_userdata_snapshotname_with_underscore.yaml │ │ ├── m_with_userdata_linked_to_no_machines.yaml │ │ ├── m_snapshot_with_separate_boot.yaml │ │ ├── m_new_dataset_without_suffix_and_clone.yaml │ │ ├── m_clone_simple.yaml │ │ ├── gc_system_with_unlinked_users_and_snapshot.yaml │ │ ├── m_clone_both_canmount_on.yaml │ │ ├── m_two_machines_with_same_userdata.yaml │ │ ├── testremovestate │ │ ├── remove_system_state_one_dataset.golden │ │ └── remove_system_state_complex_with_boot_children_and_user_datasets.golden │ │ ├── d_one_machine_with_multiple_clones_recursive.yaml │ │ ├── d_one_machine_with_multiple_clones_recursive_unordered.yaml │ │ ├── gc_system_failed_revert.yaml │ │ ├── m_with_userdata_snapshot_attached.yaml │ │ ├── m_clone_origin_doesnt_exist.yaml │ │ ├── m_snapshot_with_userdata.yaml │ │ ├── m_two_machines_with_different_userdata.yaml │ │ ├── gc_system_with_unlinked_users_unmanaged_user_clone.yaml │ │ ├── m_snapshot_with_separate_boot_with_children.yaml │ │ ├── d_one_machine_with_multiple_clones_recursive.json │ │ ├── gc_system_with_unlinked_users_unmanaged_clone_bootfs_on_clone.yaml │ │ ├── gc_system_with_unlinked_users_unmanaged_clone_nobootfs_dataset.yaml │ │ ├── d_one_machine_with_multiple_clones_recursive_unordered.json │ │ ├── gc_system_with_unlinked_users_unmanaged_clone.yaml │ │ ├── m_with_userdata_dataset_and_snapshot_attached.yaml │ │ ├── m_main_dataset_without_suffix_and_clone.yaml │ │ ├── m_main_dataset_without_suffix_and_clone_to_promote.yaml │ │ ├── m_clone_with_separate_boot.yaml │ │ ├── m_clone_with_separate_boot_to_promote.yaml │ │ ├── m_clone_with_separate_boot_with_children_manually_created.yaml │ │ ├── m_with_userdata_and_multiple_snapshots.yaml │ │ ├── m_clone_with_children_to_promote.yaml │ │ ├── m_clone_with_separate_boot_with_children_manually_created_to_promote.yaml │ │ ├── m_snapshot_with_userdata_with_children.yaml │ │ ├── m_clone_with_children.yaml │ │ ├── m_clone_with_separate_boot_with_children.yaml │ │ ├── m_clone_with_userdata.yaml │ │ ├── m_clone_with_clone_has_more_users.yaml │ │ ├── m_clone_with_separate_boot_with_children_to_promote.yaml │ │ ├── m_clone_with_userdata_to_promote_no_user_revert.yaml │ │ ├── m_clone_with_userdata_to_promote_user_revert.yaml │ │ └── m_with_userdata_snapshot_attached_with_clone.yaml ├── authorizer │ ├── testdata │ │ └── proc │ │ │ ├── 10000 │ │ │ └── stat │ │ │ ├── 10001 │ │ │ └── stat │ │ │ ├── 10002 │ │ │ └── stat │ │ │ ├── 10003 │ │ │ └── stat │ │ │ └── 10004 │ │ │ └── stat │ └── export_test.go ├── zfs │ ├── testdata │ │ ├── one_pool_one_dataset_no_mountpoint.yaml │ │ ├── one_pool_one_dataset_no_property.yaml │ │ ├── one_pool_dataset_with_canmount_default.yaml │ │ ├── one_pool_one_dataset_different_mountpoints.yaml │ │ ├── one_pool_n_datasets_no_mountpoint.yaml │ │ ├── one_pool_one_dataset_with_lastused.yaml │ │ ├── one_pool_one_dataset_with_bootfsdatasets.yaml │ │ ├── one_pool_one_dataset_with_lastbootedkernel.yaml │ │ ├── one_pool_one_dataset_canmount_noauto.yaml │ │ ├── one_pool_one_dataset_with_bootfsdatasets_multiple.yaml │ │ ├── one_pool_one_dataset.yaml │ │ ├── testnew │ │ │ ├── one_pool_one_dataset_mountpoint_default.golden │ │ │ ├── one_pool_one_dataset_no_property.golden │ │ │ ├── one_pool_one_dataset_different_mountpoints.golden │ │ │ ├── one_pool_one_dataset_canmount_noauto.golden │ │ │ ├── one_pool_one_dataset_with_lastused_property.golden │ │ │ ├── one_pool_one_dataset_with_bootfsdatasets_property.golden │ │ │ ├── one_pool_one_dataset_with_lastbootedkernel_property.golden │ │ │ ├── one_pool_one_dataset_with_bootfsdatasets_property_multiple_elems.golden │ │ │ ├── one_pool_one_dataset_with_invalid_lastused.golden │ │ │ ├── one_pool_with_canmount_as_default.golden │ │ │ ├── one_pool_one_dataset.golden │ │ │ ├── snapshot_without_any_users_properties_are_still_loaded.golden │ │ │ ├── snapshot_ignores_bootfsdataset_user_property_even_if_set.golden │ │ │ ├── one_pool_one_dataset_one_snapshot_no_source_on_user_property.golden │ │ │ ├── one_pool_n_datasets_mountpoint_default.golden │ │ │ ├── one_pool_one_dataset_one_snapshot.golden │ │ │ ├── one_pool_non-root_mpoint_n_datasets_no_mountpoint.golden │ │ │ ├── one_pool_n_datasets.golden │ │ │ ├── one_pool_n_datasets_ignore_volume.golden │ │ │ ├── snapshot_user_properties_differs_from_parent_dataset.golden │ │ │ ├── one_pool_n_datasets_one_snapshot.golden │ │ │ └── two_pools_n_datasets.golden │ │ ├── one_pool_n_datasets.yaml │ │ ├── one_pool_one_dataset_one_snapshot_without_user_properties.yaml │ │ ├── one_pool_n_datasets_with_volume.yaml │ │ ├── one_pool_with_nonroot_mountpoint_n_datasets_no_mountpoint.yaml │ │ ├── testsetproperty │ │ │ ├── mountpoint_property.golden │ │ │ ├── user_property_(local).golden │ │ │ ├── authorized_property_(local).golden │ │ │ ├── user_property_(none).golden │ │ │ ├── authorized_property_(default).golden │ │ │ ├── let_set_on_bootfsdatasetsprop_but_don_t_load_it_(none).golden │ │ │ ├── user_property_on_snapshot_(none).golden │ │ │ ├── let_set_on_bootfsdatasetsprop_but_don_t_load_it_(local).golden │ │ │ ├── lastused_with_children.golden │ │ │ ├── user_property_on_snapshot_(local).golden │ │ │ ├── user_property_on_snapshot_(inherit).golden │ │ │ ├── snapshotmountpointprop_is_mountpointprop.golden │ │ │ └── user_property_on_snapshot_(inherit_but_forced).golden │ │ ├── one_pool_one_dataset_one_snapshot.yaml │ │ ├── one_pool_one_dataset_one_snapshot_with_bootfsdatasets.yaml │ │ ├── one_pool_one_dataset_one_snapshot_no_source_on_userproperty.yaml │ │ ├── one_pool_n_datasets_one_snapshot.yaml │ │ ├── one_pool_n_datasets_one_snapshot_non_root.yaml │ │ ├── one_pool_n_datasets_one_snapshot_with_canmount_off.yaml │ │ ├── one_pool_n_datasets_one_snapshot_with_canmount_noauto.yaml │ │ ├── one_pool_n_datasets_one_snapshot_with_canmount_noauto_default.yaml │ │ ├── testdestroy │ │ │ └── hierarchy_simple.golden │ │ ├── one_pool_n_datasets_n_children.yaml │ │ ├── two_pools_n_datasets.yaml │ │ ├── one_pool_n_datasets_n_children_with_bootfsdatasets.yaml │ │ ├── one_pool_one_dataset_one_snapshot_with_user_properties.yaml │ │ ├── layout1__one_pool_n_datasets.yaml │ │ ├── one_pool_n_datasets_n_snapshots_with_bootfsdataset_n_sources.yaml │ │ ├── one_pool_n_datasets_n_snapshots_with_bootfs_n_sources.yaml │ │ ├── one_pool_n_datasets_n_snapshots_with_lastused_n_sources.yaml │ │ ├── one_pool_n_datasets_n_children_n_snapshots_with_bootfsdatasets.yaml │ │ ├── dates.refs │ │ ├── one_pool_n_datasets_n_snapshots_with_lastbootedkernel_n_sources.yaml │ │ ├── testsnapshot │ │ │ ├── simple_snapshot.golden │ │ │ └── recursive_snapshot_on_leaf_dataset.golden │ │ ├── testcreate │ │ │ ├── simple_creation.golden │ │ │ ├── with_canmount_false.golden │ │ │ ├── without_mountpoint.golden │ │ │ └── with_mountpoint_and_canmount_false.golden │ │ ├── one_pool_n_clones.yaml │ │ ├── one_pool_n_datasets_n_children_n_snapshots.yaml │ │ ├── two_pools_n_datasets_n_snapshots.yaml │ │ ├── one_pool_n_datasets_n_children_n_snapshots_canmount_off.yaml │ │ ├── one_pool_n_datasets_n_children_n_snapshots_with_unset_user_properties.yaml │ │ ├── m_with_userdata_linked_and_unlinked_and_snapshot.yaml │ │ ├── testclone │ │ │ ├── simple_clone_ignore_canmount_set_to_noauto_(default).golden │ │ │ ├── simple_clone_keeps_canmount_off_as_off.golden │ │ │ ├── simple_clone_set_canmount_on_to_noauto.golden │ │ │ ├── simple_clone_keeps_canmount_noauto_as_noauto.golden │ │ │ └── simple_clone_on_non_root_local_mountpoint_keeps_mountpoints.golden │ │ └── one_pool_n_datasets_n_children_n_snapshots_with_dependencies.yaml │ └── pool.go ├── generators │ ├── can_modify_repo.go │ ├── copy.go │ └── common.go ├── testutils │ ├── time.go │ └── zfs_adapters.go ├── i18n │ └── export_test.go ├── daemon │ ├── export_test.go │ ├── version.go │ ├── bootmenu.go │ └── timeout.go ├── streamlogger │ └── common.go └── config │ ├── zsys.conf │ └── const.go ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── bug_report.md ├── ci │ └── check-modules └── workflows │ └── commands.yaml ├── systemd ├── zsys-gc.timer ├── zsysd.socket ├── user │ ├── zsys-user-savestate.timer │ └── zsys-user-savestate.service ├── zsys-gc.service ├── zsysd.service └── zsys-commit.service ├── .gitignore └── go.mod /cmd/zsysctl/zsysctl: -------------------------------------------------------------------------------- 1 | ../zsysd/zsysd -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/no_dataset.golden: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /internal/machines/testdata/d_no_dataset.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/no_interesting_mountpoints.golden: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/one_dataset.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool": "" 3 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/select_no_matching_dataset_mountpoints.golden: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /debian/gbp.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | debian-tag=v%(version)s 3 | 4 | [buildpackage] 5 | export=INDEX 6 | 7 | -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/one_machine_with_children.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool": "" 3 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | # Disallow direct creation of blank issues 2 | blank_issues_enabled: false 3 | -------------------------------------------------------------------------------- /internal/authorizer/testdata/proc/10003/stat: -------------------------------------------------------------------------------- 1 | 776912 (sleep) S 39311 776912 39311 34824 39311 1077936128 259 2 | -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/two_machines.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool": "", 3 | "rpool2": "" 4 | } -------------------------------------------------------------------------------- /internal/machines/testdata/confs/purge_all_zsys.conf: -------------------------------------------------------------------------------- 1 | history: 2 | gcstartafter: 1 3 | keeplast: 0 4 | gcrules: -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_no_mountpoint.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | nodefaults: true 4 | -------------------------------------------------------------------------------- /debian/zsys.lintian-overrides: -------------------------------------------------------------------------------- 1 | package-supports-alternative-init-but-no-init.d-script lib/systemd/system/zsys-commit.service 2 | -------------------------------------------------------------------------------- /internal/machines/testdata/confs/purge_but_previous_zsys.conf: -------------------------------------------------------------------------------- 1 | history: 2 | gcstartafter: 0 3 | keeplast: 0 4 | gcrules: -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/real_machine_no_snapshot_no_clone.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool/ROOT/ubuntu_1234": "" 3 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_no_property.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/server_machine_no_snapshot_no_clone.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool/ROOT/ubuntu_1234": "" 3 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/missing_clone_referenced_by_a_snapshot_clone_(broken_zfs).golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool": "" 3 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/one_machine_with_one_snapshot.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool": "", 3 | "rpool@snap1": "rpool" 4 | } -------------------------------------------------------------------------------- /internal/machines/testdata/d_no_machine.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | mountpoint: /foo 6 | -------------------------------------------------------------------------------- /debian/source/lintian-overrides: -------------------------------------------------------------------------------- 1 | # The NOTICE file is there (alongside a LICENSE) 2 | zsys source: missing-notice-file-for-apache-license vendor/gopkg.in/yaml.v2/NOTICE -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_dataset_with_canmount_default.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ubuntu 5 | canmount: '-' 6 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_different_mountpoints.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | mountpoint: /boot 6 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_disabled_machine.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | mountpoint: / 6 | canmount: off 7 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_no_mountpoint.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | nodefaults: true 4 | datasets: 5 | - name: ROOT 6 | - name: ROOT/ubuntu 7 | -------------------------------------------------------------------------------- /systemd/zsys-gc.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Clean up old snapshots to free space 3 | 4 | [Timer] 5 | OnStartupSec=10min 6 | OnUnitActiveSec=24h 7 | 8 | [Install] 9 | WantedBy=timers.target -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/one_machine_with_one_snapshot_and_one_clone.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool/clone": "rpool/main", 3 | "rpool/main": "", 4 | "rpool/main@snap1": "rpool/main" 5 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_with_lastused.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | last_used: 2019-04-18T02:45:55+00:00 6 | mountpoint: /home/foo 7 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_one_dataset_no_lastused.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | mountpoint: / 7 | canmount: on 8 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/no_dataset.golden: -------------------------------------------------------------------------------- 1 | { 2 | "UnmanagedDatasets": [ 3 | { 4 | "Name": "rpool", 5 | "Mountpoint": "/", 6 | "CanMount": "off" 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /systemd/zsysd.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Socker activation for zsys daemon 3 | PartOf=zsysd.service 4 | 5 | [Socket] 6 | ListenStream=/run/zsysd.sock 7 | 8 | [Install] 9 | WantedBy=sockets.target 10 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/no_machine.golden: -------------------------------------------------------------------------------- 1 | { 2 | "AllPersistentDatasets": [ 3 | { 4 | "Name": "rpool", 5 | "Mountpoint": "/foo", 6 | "CanMount": "on" 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_with_bootfsdatasets.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | mountpoint: /home/foo 6 | bootfs_datasets: rpool/ROOT/ubuntu_42 7 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/one_disabled_machine.golden: -------------------------------------------------------------------------------- 1 | { 2 | "UnmanagedDatasets": [ 3 | { 4 | "Name": "rpool", 5 | "Mountpoint": "/", 6 | "CanMount": "off" 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_with_lastbootedkernel.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | mountpoint: /home/foo 6 | last_booted_kernel: vmlinuz-5.2.0-8-generic 7 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_one_dataset_non_zsys.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | last_used: 2020-09-13T12:26:39+00:00 6 | mountpoint: / 7 | canmount: on 8 | -------------------------------------------------------------------------------- /systemd/user/zsys-user-savestate.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Save current user state periodically 3 | ConditionUser=!@system 4 | 5 | [Timer] 6 | OnStartupSec=1min 7 | OnUnitActiveSec=1h 8 | 9 | [Install] 10 | WantedBy=timers.target -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_canmount_noauto.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | last_used: 2019-04-18T02:45:55+00:00 6 | mountpoint: /home/foo 7 | canmount: noauto 8 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_with_bootfsdatasets_multiple.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | mountpoint: /home/foo 6 | bootfs_datasets: rpool/ROOT/ubuntu_42,rpool/ROOT/ubuntu_43 7 | -------------------------------------------------------------------------------- /systemd/zsys-gc.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Clean up old snapshots to free space 3 | 4 | # We can't run it in a container 5 | ConditionVirtualization=!container 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/sbin/zsysctl service gc 10 | -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/select_master_only.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool/clone": "rpool/main", 3 | "rpool/clone2": "rpool/main", 4 | "rpool/clone@snap2": "rpool/main", 5 | "rpool/main": "", 6 | "rpool/main@snap1": "rpool/main" 7 | } -------------------------------------------------------------------------------- /systemd/user/zsys-user-savestate.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Save current user state periodically 3 | 4 | # We can't run it in a container 5 | ConditionVirtualization=!container 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/sbin/zsysctl state save 10 | -------------------------------------------------------------------------------- /.github/ci/check-modules: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | MODIFIED=`git status --porcelain go.sum go.mod` 6 | if [ -n "$MODIFIED" ]; then 7 | echo "ERROR: go module files aren't up to date:" 8 | git --no-pager diff go.mod go.sum 9 | exit 1 10 | fi 11 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2019-04-18T02:45:55+00:00 7 | last_booted_kernel: vmlinuz-5.2.0-8-generic 8 | mountpoint: / 9 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_mountpoint_default.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/rpool", 5 | "CanMount": "on", 6 | "Sources": { 7 | "Mountpoint": "inherited" 8 | } 9 | } 10 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_one_dataset.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | last_booted_kernel: vmlinuz-5.2.0-8-generic 8 | mountpoint: / -------------------------------------------------------------------------------- /debian/zsys.install: -------------------------------------------------------------------------------- 1 | systemd/*.service lib/systemd/system/ 2 | systemd/*.socket lib/systemd/system/ 3 | systemd/*.timer lib/systemd/system/ 4 | systemd/user/* usr/lib/systemd/user/ 5 | debian/zsys-system-autosnapshot usr/libexec/ 6 | debian/90_zsys_system_autosnapshot etc/apt/apt.conf.d/ -------------------------------------------------------------------------------- /internal/machines/testdata/m_without_userdata.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_no_property.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | } 11 | ] -------------------------------------------------------------------------------- /internal/generators/can_modify_repo.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | package main 5 | 6 | import ( 7 | "os" 8 | 9 | "github.com/ubuntu/zsys/internal/generators" 10 | ) 11 | 12 | func main() { 13 | if generators.InstallOnlyMode() { 14 | os.Exit(1) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_children_unordered.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: opt 5 | mountpoint: /opt 6 | - name: . 7 | zsys_bootfs: yes 8 | last_used: 2020-09-13T12:26:39+00:00 9 | mountpoint: / 10 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_one_snapshot_without_user_properties.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2019-04-18T02:45:55+00:00 7 | mountpoint: / 8 | snapshots: 9 | - name: snap1 -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_different_mountpoints.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/boot", 5 | "CanMount": "on", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | } 11 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/one_machine_with_multiple_snapshots_and_clones_with_chain_of_dependency.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool/clone": "rpool/main", 3 | "rpool/clone2": "rpool/main", 4 | "rpool/clone@snap2": "rpool/main", 5 | "rpool/main": "", 6 | "rpool/main@snap1": "rpool/main" 7 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/one_machine_with_multiple_snapshots_and_clones_with_chain_of_unordered_dependency.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool/clone": "rpool/main", 3 | "rpool/clone2": "rpool/main", 4 | "rpool/clone@snap2": "rpool/main", 5 | "rpool/main": "", 6 | "rpool/main@snap1": "rpool/main" 7 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/select_a_particular_mountpoint.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool/clone/child": "rpool/main/child", 3 | "rpool/clone/child@snap2": "rpool/main/child", 4 | "rpool/clone2/child": "rpool/main/child", 5 | "rpool/main/child": "", 6 | "rpool/main/child@snap1": "rpool/main/child" 7 | } -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_persistent.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: opt 11 | mountpoint: /opt 12 | -------------------------------------------------------------------------------- /internal/machines/testdata/confs/default.conf: -------------------------------------------------------------------------------- 1 | history: 2 | gcstartafter: 1 3 | keeplast: 3 4 | gcrules: 5 | - name: PreviousDay 6 | buckets: 1 7 | bucketlength: 1 8 | samplesperbucket: 3 9 | - name: PreviousWeek 10 | buckets: 2 11 | bucketlength: 7 12 | samplesperbucket: 3 13 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_only.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: USERDATA 11 | canmount: off 12 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_with_volume.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: vol1 11 | isvolume: true -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_with_nonroot_mountpoint_n_datasets_no_mountpoint.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | mountpoint: /boot 6 | canmount: off 7 | - name: BOOT 8 | canmount: off 9 | - name: BOOT/ubuntu 10 | last_used: 2019-04-18T02:45:55+00:00 11 | -------------------------------------------------------------------------------- /internal/machines/testdata/confs/keep_many_snapshots.conf: -------------------------------------------------------------------------------- 1 | history: 2 | gcstartafter: 1 3 | keeplast: 15 4 | gcrules: 5 | - name: PreviousDay 6 | buckets: 1 7 | bucketlength: 1 8 | samplesperbucket: 3 9 | - name: PreviousWeek 10 | buckets: 2 11 | bucketlength: 7 12 | samplesperbucket: 3 13 | -------------------------------------------------------------------------------- /internal/machines/testdata/confs/not_enough_snapshots.conf: -------------------------------------------------------------------------------- 1 | history: 2 | gcstartafter: 1 3 | keeplast: 3 4 | gcrules: 5 | - name: PreviousDay 6 | buckets: 1 7 | bucketlength: 1 8 | samplesperbucket: 20 9 | - name: PreviousWeek 10 | buckets: 2 11 | bucketlength: 7 12 | samplesperbucket: 20 13 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_children.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | last_booted_kernel: vmlinuz-5.2.0-8-generic 8 | mountpoint: / 9 | - name: opt 10 | mountpoint: /opt 11 | -------------------------------------------------------------------------------- /internal/authorizer/testdata/proc/10000/stat: -------------------------------------------------------------------------------- 1 | 776912 (sleep) S 39311 776912 39311 34824 39311 1077936128 259 0 1 0 0 0 0 0 20 0 1 0 50909551 10874880 179 18446744073709551615 93972232257536 93972232281121 140721293712640 0 0 0 0 0 0 1 0 0 17 2 0 0 0 0 0 93972232297392 93972232298624 93972251222016 140721293716291 140721293716303 140721293716303 140721293721581 0 2 | -------------------------------------------------------------------------------- /internal/authorizer/testdata/proc/10001/stat: -------------------------------------------------------------------------------- 1 | 776912 (sleep S 39311 776912 39311 34824 39311 1077936128 259 0 1 0 0 0 0 0 20 0 1 0 50909551 10874880 179 18446744073709551615 93972232257536 93972232281121 140721293712640 0 0 0 0 0 0 1 0 0 17 2 0 0 0 0 0 93972232297392 93972232298624 93972251222016 140721293716291 140721293716303 140721293716303 140721293721581 0 2 | -------------------------------------------------------------------------------- /internal/authorizer/testdata/proc/10002/stat: -------------------------------------------------------------------------------- 1 | 776912 (sleep S 39311 776912 39311 34824 39311 1077936128 259 0 1 0 0 0 0 0 20 0 1 0 50909551 10874880 179 18446744073709551615 93972232257536 93972232281121 140721293712640 0 0 0 0 0 0 1 0 0 17 2 0 0 0 0 0 93972232297392 93972232298624 93972251222016 140721293716291 140721293716303 140721293716303 140721293721581 0 2 | ) -------------------------------------------------------------------------------- /debian/tests/control: -------------------------------------------------------------------------------- 1 | # Skip tests on platform we don't build a binary for (no grub2-common package available). 2 | # Autopkgtests will still try to run it if it ever ran one day and would fail as it can't 3 | # install zsys. 4 | Test-Command: sudo go test -v -mod=vendor ./... 5 | Restrictions: needs-root, allow-stderr, skip-not-installable 6 | Depends: @builddeps@ 7 | -------------------------------------------------------------------------------- /internal/authorizer/testdata/proc/10004/stat: -------------------------------------------------------------------------------- 1 | 776912 (sleep) S 39311 776912 39311 34824 39311 1077936128 259 0 1 0 0 0 0 0 20 0 1 0 xxx50909551 10874880 179 18446744073709551615 93972232257536 93972232281121 140721293712640 0 0 0 0 0 0 1 0 0 17 2 0 0 0 0 0 93972232297392 93972232298624 93972251222016 140721293716291 140721293716303 140721293716303 140721293721581 0 2 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_persistent_canmount_noauto.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: opt 11 | mountpoint: /opt 12 | canmount: noauto 13 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_canmount_noauto.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/home/foo", 5 | "CanMount": "noauto", 6 | "LastUsed": 1555555555, 7 | "Sources": { 8 | "Mountpoint": "local", 9 | "CanMount": "local", 10 | "LastUsed": "local" 11 | } 12 | } 13 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_with_lastused_property.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/home/foo", 5 | "CanMount": "on", 6 | "LastUsed": 1555555555, 7 | "Sources": { 8 | "Mountpoint": "local", 9 | "CanMount": "local", 10 | "LastUsed": "local" 11 | } 12 | } 13 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_children_all_with_lastused.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | mountpoint: / 8 | canmount: on 9 | - name: opt 10 | mountpoint: /opt 11 | last_used: 2019-04-18T02:45:55+00:00 12 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/mountpoint_property.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/foo", 5 | "CanMount": "on", 6 | "BootfsDatasets": "rpool/ROOT/ubuntu_42", 7 | "Sources": { 8 | "Mountpoint": "local", 9 | "CanMount": "local", 10 | "BootfsDatasets": "local" 11 | } 12 | } 13 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_only_on_other_pool.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: rpool2 11 | datasets: 12 | - name: USERDATA 13 | canmount: off 14 | -------------------------------------------------------------------------------- /internal/testutils/time.go: -------------------------------------------------------------------------------- 1 | package testutils 2 | 3 | import "time" 4 | 5 | // FixedTime is the fixed "now" used for testing 6 | type FixedTime struct{} 7 | 8 | // Now returns fixed time for testing 9 | func (FixedTime) Now() time.Time { 10 | t, err := time.Parse(time.RFC3339, "2020-01-01T12:00:00+00:00") 11 | if err != nil { 12 | panic(err) 13 | } 14 | return t 15 | } 16 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/user_property_(local).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/home/foo", 5 | "CanMount": "on", 6 | "BootfsDatasets": "SetProperty Value", 7 | "Sources": { 8 | "Mountpoint": "local", 9 | "CanMount": "local", 10 | "BootfsDatasets": "local" 11 | } 12 | } 13 | ] -------------------------------------------------------------------------------- /systemd/zsysd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=ZSYS daemon service 3 | After=zsysd.socket 4 | Requires=zsysd.socket 5 | 6 | # We can't run it in a container as there is no ZFS namespaces 7 | ConditionVirtualization=!container 8 | 9 | [Service] 10 | Type=notify 11 | ExecStart=/sbin/zsysd 12 | 13 | # Some daemon restrictions 14 | NoNewPrivileges=true 15 | PrivateNetwork=true 16 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/authorized_property_(local).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/home/foo", 5 | "CanMount": "noauto", 6 | "BootfsDatasets": "rpool/ROOT/ubuntu_42", 7 | "Sources": { 8 | "Mountpoint": "local", 9 | "CanMount": "local", 10 | "BootfsDatasets": "local" 11 | } 12 | } 13 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/d_two_machines_one_dataset.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | mountpoint: / 8 | - name: rpool2 9 | datasets: 10 | - name: . 11 | zsys_bootfs: yes 12 | last_used: 2020-05-07T22:01:28+00:00 13 | mountpoint: / 14 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_one_snapshot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2019-04-18T02:45:55+00:00 7 | mountpoint: / 8 | snapshots: 9 | - name: snap1 10 | zsys_bootfs: yes:local 11 | mountpoint: /:local 12 | canmount: on:local 13 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_persistent_on_another_pool.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: cpool 11 | datasets: 12 | - name: grub 13 | mountpoint: /boot/grub 14 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_with_bootfsdatasets_property.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/home/foo", 5 | "CanMount": "on", 6 | "BootfsDatasets": "rpool/ROOT/ubuntu_42", 7 | "Sources": { 8 | "Mountpoint": "local", 9 | "CanMount": "local", 10 | "BootfsDatasets": "local" 11 | } 12 | } 13 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_one_snapshot_with_bootfsdatasets.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2019-04-18T02:45:55+00:00 7 | mountpoint: / 8 | bootfs_datasets: rpool/ROOT/ubuntu_42 9 | snapshots: 10 | - name: snap1 11 | bootfs_datasets: something set:local 12 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_with_lastbootedkernel_property.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/home/foo", 5 | "CanMount": "on", 6 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 7 | "Sources": { 8 | "Mountpoint": "local", 9 | "CanMount": "local", 10 | "LastBootedKernel": "local" 11 | } 12 | } 13 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/confs/one_empty_bucket.conf: -------------------------------------------------------------------------------- 1 | history: 2 | gcstartafter: 1 3 | keeplast: 3 4 | gcrules: 5 | - name: Rule1 6 | buckets: 1 7 | bucketlength: 4 8 | samplesperbucket: 20 9 | - name: Rule2 10 | buckets: 1 11 | bucketlength: 1 12 | samplesperbucket: 3 13 | - name: Rule3 14 | buckets: 1 15 | bucketlength: 7 16 | samplesperbucket: 3 17 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_two_machines_one_zsys_one_non_zsys.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | mountpoint: / 8 | canmount: on 9 | - name: rpool2 10 | datasets: 11 | - name: . 12 | last_used: 2020-05-07T22:01:28+00:00 13 | mountpoint: / 14 | canmount: on 15 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_unlinked_boot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: bpool 11 | datasets: 12 | - name: BOOT 13 | canmount: off 14 | - name: BOOT/ubuntu_none 15 | mountpoint: /boot 16 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_with_bootfsdatasets_property_multiple_elems.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/home/foo", 5 | "CanMount": "on", 6 | "BootfsDatasets": "rpool/ROOT/ubuntu_42,rpool/ROOT/ubuntu_43", 7 | "Sources": { 8 | "Mountpoint": "local", 9 | "CanMount": "local", 10 | "BootfsDatasets": "local" 11 | } 12 | } 13 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/m_two_machines_both_canmount_on.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: ROOT/ubuntu_5678 11 | zsys_bootfs: yes 12 | last_used: 2018-12-10T12:20:44+00:00 13 | mountpoint: / 14 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_one_snapshot_no_source_on_userproperty.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2019-04-18T02:45:55+00:00 7 | mountpoint: / 8 | snapshots: 9 | - name: snap1 10 | # Miss :local 11 | zsys_bootfs: yes 12 | mountpoint: /:local 13 | canmount: on:local 14 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_one_snapshot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | mountpoint: / 8 | snapshots: 9 | - name: snap1 10 | zsys_bootfs: yes:local 11 | mountpoint: /:local 12 | canmount: on:local 13 | creation_time: 2020-05-07T22:01:28+00:00 14 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_one_snapshot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_with_invalid_lastused.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 8 | "Sources": { 9 | "Mountpoint": "local", 10 | "CanMount": "local", 11 | "BootFS": "local", 12 | "LastBootedKernel": "local" 13 | } 14 | } 15 | ] -------------------------------------------------------------------------------- /debian/90_zsys_system_autosnapshot: -------------------------------------------------------------------------------- 1 | // Takes a snapshot of the system before package changes. 2 | DPkg::Pre-Invoke {"[ -x /usr/libexec/zsys-system-autosnapshot ] && /usr/libexec/zsys-system-autosnapshot snapshot || true";}; 3 | // Update our bootloader to list the new snapshot after the update is done to not block the critical path 4 | DPkg::Post-Invoke {"[ -x /usr/libexec/zsys-system-autosnapshot ] && /usr/libexec/zsys-system-autosnapshot update-menu || true";}; 5 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_two_machines_simple.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: ROOT/ubuntu_5678 11 | zsys_bootfs: yes 12 | last_used: 2018-12-10T12:20:44+00:00 13 | mountpoint: / 14 | canmount: noauto 15 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_one_snapshot_non_root.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /foo:local 14 | canmount: on:local 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs, uncommited generated code and plugins 2 | cmd/zsysd/zsysd 3 | cmd/zsysd/zsysctl 4 | generated/ 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | coverage/ 14 | 15 | # Package artefacts 16 | obj-x86_64-linux-gnu/ 17 | vendor/ 18 | 19 | # Various cruft to not consider 20 | *.log 21 | *.code-workspace 22 | 23 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_unlinked_boot_canmount_off.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: bpool 11 | datasets: 12 | - name: BOOT 13 | canmount: off 14 | - name: BOOT/ubuntu_none 15 | canmount: off 16 | mountpoint: /boot 17 | -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/real_machines_with_snapshots_and_clones.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool/ROOT/ubuntu_1234": "", 3 | "rpool/ROOT/ubuntu_1234@snap1": "rpool/ROOT/ubuntu_1234", 4 | "rpool/ROOT/ubuntu_1234@snap2": "rpool/ROOT/ubuntu_1234", 5 | "rpool/ROOT/ubuntu_5678": "rpool/ROOT/ubuntu_1234", 6 | "rpool/ROOT/ubuntu_5678@snap3": "rpool/ROOT/ubuntu_1234", 7 | "rpool/ROOT/ubuntu_9876": "rpool/ROOT/ubuntu_1234", 8 | "rpool/ROOT/ubuntu_9999": "" 9 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/server_machines_with_snapshots_and_clones.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool/ROOT/ubuntu_1234": "", 3 | "rpool/ROOT/ubuntu_1234@snap1": "rpool/ROOT/ubuntu_1234", 4 | "rpool/ROOT/ubuntu_1234@snap2": "rpool/ROOT/ubuntu_1234", 5 | "rpool/ROOT/ubuntu_5678": "rpool/ROOT/ubuntu_1234", 6 | "rpool/ROOT/ubuntu_5678@snap3": "rpool/ROOT/ubuntu_1234", 7 | "rpool/ROOT/ubuntu_9876": "rpool/ROOT/ubuntu_1234", 8 | "rpool/ROOT/ubuntu_9999": "" 9 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_one_snapshot_with_canmount_off.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: off:local 15 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/user_property_(none).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/home/foo", 5 | "CanMount": "on", 6 | "LastBootedKernel": "SetProperty Value", 7 | "BootfsDatasets": "rpool/ROOT/ubuntu_42", 8 | "Sources": { 9 | "Mountpoint": "local", 10 | "CanMount": "local", 11 | "LastBootedKernel": "local", 12 | "BootfsDatasets": "local" 13 | } 14 | } 15 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_one_snapshot_with_canmount_noauto.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: noauto:local 15 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_with_canmount_as_default.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ubuntu", 13 | "Mountpoint": "/ubuntu", 14 | "CanMount": "on", 15 | "Sources": { 16 | "Mountpoint": "inherited" 17 | } 18 | } 19 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_one_snapshot_with_canmount_noauto_default.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: noauto:default 15 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_unlinked_userdata.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: USERDATA 11 | canmount: off 12 | - name: USERDATA/root_bcde 13 | mountpoint: /root 14 | last_used: 2018-08-03T21:55:33+00:00 15 | bootfs_datasets: rpool/ROOT/ubuntu_none 16 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_separate_boot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2020-09-13T12:26:39+00:00 9 | mountpoint: / 10 | - name: bpool 11 | datasets: 12 | - name: BOOT 13 | canmount: off 14 | - name: BOOT/ubuntu_1234 15 | last_used: 2020-09-13T12:26:39+00:00 16 | mountpoint: /boot 17 | 18 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testdestroy/hierarchy_simple.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ROOT", 13 | "Mountpoint": "/ROOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | } 20 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local" 15 | } 16 | } 17 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_children.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: ROOT/ubuntu/var 11 | - name: ROOT/ubuntu/var/lib 12 | - name: ROOT/ubuntu/opt 13 | - name: ROOT/ubuntu2 14 | last_used: 2018-12-10T12:20:44+00:00 15 | mountpoint: / 16 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_persistent_on_bpool.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: bpool 11 | datasets: 12 | - name: BOOT 13 | canmount: off 14 | - name: BOOT/ubuntu_1234 15 | mountpoint: /boot 16 | - name: grub 17 | mountpoint: /boot/grub 18 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_without_userdata_prefer_system_pool.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: rpool2 11 | datasets: 12 | - name: ROOT 13 | canmount: off 14 | - name: ROOT/ubuntu_1234 15 | zsys_bootfs: yes 16 | last_used: 2018-12-10T12:20:44+00:00 17 | mountpoint: / 18 | -------------------------------------------------------------------------------- /internal/zfs/testdata/two_pools_n_datasets.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: bpool 11 | datasets: 12 | - name: BOOT 13 | canmount: off 14 | - name: BOOT/boot 15 | zsys_bootfs: yes 16 | last_used: 2019-04-18T02:45:55+00:00 17 | mountpoint: /boot 18 | 19 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_two_machines_with_persistent.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: ROOT/ubuntu_5678 11 | zsys_bootfs: yes 12 | last_used: 2018-12-10T12:20:44+00:00 13 | mountpoint: / 14 | canmount: noauto 15 | - name: opt 16 | mountpoint: /opt 17 | -------------------------------------------------------------------------------- /internal/machines/testdata/testresolveorigin/select_all_datasets_without_selecting_mountpoints.golden: -------------------------------------------------------------------------------- 1 | { 2 | "rpool/clone": "rpool/main", 3 | "rpool/clone/child": "rpool/main/child", 4 | "rpool/clone/child@snap2": "rpool/main/child", 5 | "rpool/clone2": "rpool/main", 6 | "rpool/clone2/child": "rpool/main/child", 7 | "rpool/clone@snap2": "rpool/main", 8 | "rpool/main": "", 9 | "rpool/main/child": "", 10 | "rpool/main/child@snap1": "rpool/main/child", 11 | "rpool/main@snap1": "rpool/main" 12 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/authorized_property_(default).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ubuntu", 13 | "Mountpoint": "/ubuntu", 14 | "CanMount": "noauto", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | } 20 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_unlinked_userdata_canmount_off.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: USERDATA 11 | canmount: off 12 | - name: USERDATA/root_bcde 13 | canmount: off 14 | mountpoint: /root 15 | last_used: 2018-08-03T21:55:33+00:00 16 | bootfs_datasets: rpool/ROOT/ubuntu_none 17 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_snapshot_less_datasets.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | mountpoint: / 8 | canmount: on 9 | snapshots: 10 | - name: snap1 11 | zsys_bootfs: yes:local 12 | mountpoint: /:local 13 | canmount: on:local 14 | creation_time: 2020-05-07T22:01:28+00:00 15 | - name: opt 16 | mountpoint: /opt 17 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_snapshot_with_persistent.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: opt 17 | mountpoint: /opt 18 | -------------------------------------------------------------------------------- /systemd/zsys-commit.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Mark current ZSYS boot as successful 3 | After=default.target zsysd.socket zsysd.service 4 | Requires=default.target zsysd.socket zsysd.service 5 | 6 | # We can't run it in a container 7 | ConditionVirtualization=!container 8 | 9 | [Service] 10 | Type=oneshot 11 | RemainAfterExit=yes 12 | ExecStart=/sbin/zsysctl boot commit 13 | ExecStop=/sbin/zsysctl boot update-lastused 14 | 15 | # Some daemon restrictions 16 | NoNewPrivileges=true 17 | PrivateNetwork=true 18 | 19 | [Install] 20 | WantedBy=default.target -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_children_snapshot_on_subdataset.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | last_booted_kernel: vmlinuz-5.2.0-8-generic 8 | mountpoint: / 9 | - name: opt 10 | snapshots: 11 | - name: optonly 12 | canmount: on:local 13 | mountpoint: /opt:inherited 14 | zsys_bootfs: yes:inherited 15 | creation_time: 2020-05-07T22:01:28+00:00 16 | 17 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_no_attached_userdata_first_pool.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: USERDATA 11 | canmount: off 12 | - name: USERDATA/user1_abcd 13 | mountpoint: /home/user1 14 | last_used: 2018-12-10T12:20:44+00:00 15 | - name: USERDATA/root_bcde 16 | mountpoint: /root 17 | last_used: 2018-08-03T21:55:33+00:00 18 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_two_machines_recursive.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: ROOT/ubuntu_1234/opt 11 | - name: ROOT/ubuntu_5678 12 | zsys_bootfs: yes 13 | last_used: 2018-12-10T12:20:44+00:00 14 | mountpoint: / 15 | canmount: noauto 16 | - name: ROOT/ubuntu_5678/opt 17 | canmount: noauto 18 | -------------------------------------------------------------------------------- /internal/machines/testdata/testremovesystemstates/remove_non_current_state_one_dataset.golden: -------------------------------------------------------------------------------- 1 | { 2 | "Cmdline": "aaaaa bbbbb root=ZFS= ccccc", 3 | "UnmanagedDatasets": [ 4 | { 5 | "Name": "rpool", 6 | "Mountpoint": "/", 7 | "CanMount": "off" 8 | }, 9 | { 10 | "Name": "rpool/ROOT", 11 | "Mountpoint": "/ROOT", 12 | "CanMount": "off" 13 | }, 14 | { 15 | "Name": "rpool/USERDATA", 16 | "Mountpoint": "/USERDATA", 17 | "CanMount": "off" 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_children_with_bootfsdatasets.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | bootfs_datasets: rpool/ROOT/ubuntu_42 9 | last_used: 2019-04-18T02:45:55+00:00 10 | mountpoint: / 11 | - name: ROOT/ubuntu/var 12 | - name: ROOT/ubuntu/var/lib 13 | - name: ROOT/ubuntu/opt 14 | - name: ROOT/ubuntu2 15 | last_used: 2018-12-10T12:20:44+00:00 16 | mountpoint: / 17 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/snapshot_without_any_users_properties_are_still_loaded.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "Sources": { 9 | "Mountpoint": "local", 10 | "CanMount": "local", 11 | "BootFS": "local", 12 | "LastUsed": "local" 13 | } 14 | }, 15 | { 16 | "Name": "rpool@snap1", 17 | "IsSnapshot": true, 18 | "LastUsed": 2000000000, 19 | "Sources": {} 20 | } 21 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_one_dataset_one_snapshot_with_user_properties.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: no 6 | last_used: 2019-04-18T02:45:55+00:00 7 | last_booted_kernel: vmlinuz-5.2.0-8-generic 8 | bootfs_datasets: something 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:inherited 14 | canmount: on:default 15 | last_booted_kernel: vmlinuz-5.0.0-0-generic:local 16 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/let_set_on_bootfsdatasetsprop_but_don_t_load_it_(none).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "Sources": { 9 | "Mountpoint": "local", 10 | "CanMount": "local", 11 | "BootFS": "local", 12 | "LastUsed": "local" 13 | } 14 | }, 15 | { 16 | "Name": "rpool@snap1", 17 | "IsSnapshot": true, 18 | "LastUsed": 2000000000, 19 | "Sources": {} 20 | } 21 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/layout1__one_pool_n_datasets.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | last_booted_kernel: vmlinuz-5.2.0-8-generic 10 | bootfs_datasets: "rpool/path/to/dataset" 11 | mountpoint: / 12 | - name: ROOT/ubuntu_1234/var 13 | - name: ROOT/ubuntu_1234/var/lib 14 | zsys_bootfs: no 15 | - name: ROOT/ubuntu_1234/var/lib/apt 16 | - name: ROOT/ubuntu_1234/opt -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_snapshots_with_bootfsdataset_n_sources.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap_local_inherited 12 | - name: ROOT/ubuntu/inherited 13 | snapshots: 14 | - name: snap_local_inherited 15 | - name: ROOT/ubuntu2 16 | snapshots: 17 | - name: snap_default 18 | 19 | 20 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_missing_clone.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Bootfs": true, 5 | "LastUsed": 1599999999, 6 | "Mountpoint": "/", 7 | "CanMount": "on" 8 | }, 9 | { 10 | "Name": "rpool_clone@snap1", 11 | "IsSnapshot": true, 12 | "LastUsed": 1588888888, 13 | "Mountpoint": "/" 14 | }, 15 | { 16 | "Name": "rpool_clone2", 17 | "Bootfs": true, 18 | "LastUsed": 1577777777, 19 | "Mountpoint": "/", 20 | "Origin": "rpool_clone@snap1" 21 | } 22 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/testremovesystemstates/remove_non_current_state_complex_with_boot_children_and_user_datasets.golden: -------------------------------------------------------------------------------- 1 | { 2 | "Cmdline": "aaaaa bbbbb root=ZFS= ccccc", 3 | "UnmanagedDatasets": [ 4 | { 5 | "Name": "rpool", 6 | "Mountpoint": "/", 7 | "CanMount": "off" 8 | }, 9 | { 10 | "Name": "rpool/ROOT", 11 | "Mountpoint": "/ROOT", 12 | "CanMount": "off" 13 | }, 14 | { 15 | "Name": "rpool/USERDATA", 16 | "Mountpoint": "/USERDATA", 17 | "CanMount": "off" 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_clone_named_before.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: a 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | mountpoint: / 8 | canmount: noauto 9 | origin: rpool/b@snap1 10 | - name: b 11 | zsys_bootfs: yes 12 | last_used: 2019-12-31T07:36:17+00:00 13 | mountpoint: / 14 | snapshots: 15 | - name: snap1 16 | mountpoint: /:local 17 | canmount: on:local 18 | creation_time: 2020-05-07T22:01:28+00:00 19 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_no_attached_userdata_second_pool.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: rpool2 11 | datasets: 12 | - name: USERDATA 13 | canmount: off 14 | - name: USERDATA/user1_abcd 15 | mountpoint: /home/user1 16 | last_used: 2018-12-10T12:20:44+00:00 17 | - name: USERDATA/root_bcde 18 | mountpoint: /root 19 | last_used: 2018-08-03T21:55:33+00:00 20 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_no_zsys.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | last_used: 2019-04-18T02:45:55+00:00 8 | mountpoint: / 9 | - name: USERDATA 10 | canmount: off 11 | - name: USERDATA/user1_abcd 12 | mountpoint: /home/user1 13 | last_used: 2018-12-10T12:20:44+00:00 14 | bootfs_datasets: rpool/ROOT/ubuntu_1234 15 | - name: USERDATA/root_bcde 16 | mountpoint: /root 17 | last_used: 2018-08-03T21:55:33+00:00 18 | bootfs_datasets: rpool/ROOT/ubuntu_1234 19 | -------------------------------------------------------------------------------- /internal/i18n/export_test.go: -------------------------------------------------------------------------------- 1 | package i18n 2 | 3 | // WithLocaleDir enables overriding locale directory in tests 4 | func WithLocaleDir(path string) func(l *i18n) { 5 | return func(l *i18n) { 6 | l.localeDir = path 7 | } 8 | } 9 | 10 | // WithLoc enables overriding loc settings in tests 11 | func WithLoc(loc string) func(l *i18n) { 12 | return func(l *i18n) { 13 | l.loc = loc 14 | } 15 | } 16 | 17 | // ResetGlobals resets G and GN to their empty func 18 | func ResetGlobals() { 19 | G = func(msgid string) string { return msgid } 20 | NG = func(msgid string, msgidPlural string, n uint32) string { return msgid } 21 | } 22 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: USERDATA 11 | canmount: off 12 | - name: USERDATA/user1_abcd 13 | mountpoint: /home/user1 14 | last_used: 2018-12-10T12:20:44+00:00 15 | bootfs_datasets: rpool/ROOT/ubuntu_1234 16 | - name: USERDATA/root_bcde 17 | mountpoint: /root 18 | last_used: 2018-08-03T21:55:33+00:00 19 | bootfs_datasets: rpool/ROOT/ubuntu_1234 20 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/user_property_on_snapshot_(none).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "Sources": { 9 | "Mountpoint": "local", 10 | "CanMount": "local", 11 | "BootFS": "local", 12 | "LastUsed": "local" 13 | } 14 | }, 15 | { 16 | "Name": "rpool@snap1", 17 | "IsSnapshot": true, 18 | "LastUsed": 2000000000, 19 | "LastBootedKernel": "SetProperty Value", 20 | "Sources": { 21 | "LastBootedKernel": "local" 22 | } 23 | } 24 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/snapshot_ignores_bootfsdataset_user_property_even_if_set.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "BootfsDatasets": "rpool/ROOT/ubuntu_42", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "BootfsDatasets": "local" 15 | } 16 | }, 17 | { 18 | "Name": "rpool@snap1", 19 | "IsSnapshot": true, 20 | "LastUsed": 2000000000, 21 | "Sources": {} 22 | } 23 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_clone_dataset.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: main 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | last_booted_kernel: vmlinuz-5.2.0-8-generic 8 | mountpoint: / 9 | snapshots: 10 | - name: snap1 11 | mountpoint: /:local 12 | canmount: on:local 13 | creation_time: 2019-12-31T07:36:17+00:00 14 | - name: clone 15 | zsys_bootfs: yes 16 | last_used: 2020-05-07T22:01:28+00:00 17 | mountpoint: / 18 | canmount: noauto 19 | origin: rpool/main@snap1 20 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_clone_to_promote.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: main 5 | zsys_bootfs: yes 6 | canmount: noauto 7 | last_used: 2020-09-13T12:26:39+00:00 8 | last_booted_kernel: vmlinuz-5.2.0-8-generic 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | mountpoint: /:local 13 | canmount: on:local 14 | creation_time: 2019-12-31T07:36:17+00:00 15 | - name: clone 16 | zsys_bootfs: yes 17 | last_used: 2020-05-07T22:01:28+00:00 18 | mountpoint: / 19 | origin: rpool/main@snap1 20 | -------------------------------------------------------------------------------- /internal/machines/testdata/gc_system_with_unlinked_users.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | 11 | - name: USERDATA 12 | canmount: off 13 | - name: USERDATA/user1_abcd 14 | mountpoint: /home/user1 15 | last_used: 2018-12-10T12:20:44+00:00 16 | bootfs_datasets: rpool/ROOT/ubuntu_1234 17 | 18 | - name: USERDATA/user2_unlinked 19 | mountpoint: /home/unlinked 20 | last_used: 2018-08-03T21:55:33+00:00 21 | bootfs_datasets: "-" 22 | -------------------------------------------------------------------------------- /internal/daemon/export_test.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import ( 4 | "errors" 5 | "net" 6 | ) 7 | 8 | func WithSystemdActivationListener(f func() ([]net.Listener, error)) func(o *options) error { 9 | return func(o *options) error { 10 | o.systemdActivationListener = f 11 | return nil 12 | } 13 | } 14 | 15 | func WithSystemdSdNotifier(f func(unsetEnvironment bool, state string) (bool, error)) func(o *options) error { 16 | return func(o *options) error { 17 | o.systemdSdNotifier = f 18 | return nil 19 | } 20 | } 21 | 22 | func FailingOption() func(o *options) error { 23 | return func(o *options) error { 24 | return errors.New("failing option") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/let_set_on_bootfsdatasetsprop_but_don_t_load_it_(local).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "BootfsDatasets": "rpool/ROOT/ubuntu_42", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "BootfsDatasets": "local" 15 | } 16 | }, 17 | { 18 | "Name": "rpool@snap1", 19 | "IsSnapshot": true, 20 | "LastUsed": 2000000000, 21 | "Sources": {} 22 | } 23 | ] -------------------------------------------------------------------------------- /internal/streamlogger/common.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package streamlogger creates some stream client and server which can proxy logs to client, by adding to the grpc 3 | call some metadata used to identify and specify log levels. 4 | */ 5 | package streamlogger 6 | 7 | const ( 8 | // metaRequesterIDKey is the metadata key provided by the client to associate a given requester 9 | metaRequesterIDKey = "requesterid" 10 | // metaLevelKey is the metadata key provided by the client to request a particular logging level 11 | metaLevelKey = "loglevel" 12 | // metaRequestIDKey is the metadata key used to associate a given request (set by the service). 13 | metaRequestIDKey = "requestid" 14 | ) 15 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_on_other_pool.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: rpool2 11 | datasets: 12 | - name: USERDATA 13 | canmount: off 14 | - name: USERDATA/user1_abcd 15 | mountpoint: /home/user1 16 | last_used: 2018-12-10T12:20:44+00:00 17 | bootfs_datasets: rpool/ROOT/ubuntu_1234 18 | - name: USERDATA/root_bcde 19 | mountpoint: /root 20 | last_used: 2018-08-03T21:55:33+00:00 21 | bootfs_datasets: rpool/ROOT/ubuntu_1234 22 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_children_on_system.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: ROOT/ubuntu_1234/tools 11 | - name: USERDATA 12 | canmount: off 13 | - name: USERDATA/user1_abcd 14 | mountpoint: /home/user1 15 | last_used: 2018-12-10T12:20:44+00:00 16 | bootfs_datasets: rpool/ROOT/ubuntu_1234 17 | - name: USERDATA/root_bcde 18 | mountpoint: /root 19 | last_used: 2018-08-03T21:55:33+00:00 20 | bootfs_datasets: rpool/ROOT/ubuntu_1234 21 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_children_on_user.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: USERDATA 11 | canmount: off 12 | - name: USERDATA/user1_abcd 13 | mountpoint: /home/user1 14 | last_used: 2018-12-10T12:20:44+00:00 15 | bootfs_datasets: rpool/ROOT/ubuntu_1234 16 | - name: USERDATA/user1_abcd/tools 17 | - name: USERDATA/root_bcde 18 | mountpoint: /root 19 | last_used: 2018-08-03T21:55:33+00:00 20 | bootfs_datasets: rpool/ROOT/ubuntu_1234 21 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/one_machine_no_last_used.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool": { 4 | "IsZsys": true, 5 | "ID": "rpool", 6 | "LastUsed": "0001-01-01T00:00:00Z", 7 | "Datasets": { 8 | "rpool": [ 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true 14 | } 15 | ] 16 | } 17 | } 18 | }, 19 | "AllSystemDatasets": [ 20 | { 21 | "Name": "rpool", 22 | "Mountpoint": "/", 23 | "CanMount": "on", 24 | "BootFS": true 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/one_machine_one_dataset_non_zsys.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool": { 4 | "ID": "rpool", 5 | "LastUsed": "2020-09-13T14:26:39+02:00", 6 | "Datasets": { 7 | "rpool": [ 8 | { 9 | "Name": "rpool", 10 | "Mountpoint": "/", 11 | "CanMount": "on", 12 | "LastUsed": 1599999999 13 | } 14 | ] 15 | } 16 | } 17 | }, 18 | "AllSystemDatasets": [ 19 | { 20 | "Name": "rpool", 21 | "Mountpoint": "/", 22 | "CanMount": "on", 23 | "LastUsed": 1599999999 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_snapshot_more_datasets.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: . 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | mountpoint: / 8 | canmount: on 9 | snapshots: 10 | - name: snap1 11 | zsys_bootfs: yes:local 12 | mountpoint: /:local 13 | canmount: on:local 14 | creation_time: 2020-05-07T22:01:28+00:00 15 | - name: opt 16 | canmount: off 17 | snapshots: 18 | - name: snap1 19 | mountpoint: /opt:local 20 | canmount: on:local 21 | creation_time: 2020-05-07T22:01:28+00:00 22 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_two_machines_with_separate_boot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: ROOT/ubuntu_5678 11 | zsys_bootfs: yes 12 | last_used: 2018-12-10T12:20:44+00:00 13 | mountpoint: / 14 | canmount: noauto 15 | - name: bpool 16 | datasets: 17 | - name: BOOT 18 | canmount: off 19 | - name: BOOT/ubuntu_1234 20 | mountpoint: /boot 21 | - name: BOOT/ubuntu_5678 22 | mountpoint: /boot 23 | canmount: noauto 24 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_one_snapshot_no_source_on_user_property.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "Sources": { 9 | "Mountpoint": "local", 10 | "CanMount": "local", 11 | "BootFS": "local", 12 | "LastUsed": "local" 13 | } 14 | }, 15 | { 16 | "Name": "rpool@snap1", 17 | "IsSnapshot": true, 18 | "Mountpoint": "/", 19 | "CanMount": "on", 20 | "LastUsed": 2000000000, 21 | "Sources": { 22 | "Mountpoint": "local", 23 | "CanMount": "local" 24 | } 25 | } 26 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_simple_with_manual_clone.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | last_booted_kernel: vmlinuz-5.2.0-8-generic 10 | mountpoint: / 11 | snapshots: 12 | - name: snap1 13 | zsys_bootfs: yes:local 14 | last_booted_kernel: vmlinuz-5.0.0-0-generic:local 15 | mountpoint: /:local 16 | canmount: on:local 17 | creation_time: 2018-12-10T12:20:44+00:00 18 | - name: ROOT/ubuntu_manual 19 | origin: rpool/ROOT/ubuntu_1234@snap1 20 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_snapshots_with_bootfs_n_sources.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap_local 12 | zsys_bootfs: yes:local 13 | - name: snap_default 14 | zsys_bootfs: false:default 15 | - name: snap_inherited 16 | zsys_bootfs: yes:local 17 | - name: ROOT/ubuntu/subdataset 18 | zsys_bootfs: no 19 | snapshots: 20 | - name: snap_inherited 21 | zsys_bootfs: yes:inherited 22 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_n_datasets_mountpoint_default.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/rpool", 5 | "CanMount": "on", 6 | "Sources": { 7 | "Mountpoint": "inherited" 8 | } 9 | }, 10 | { 11 | "Name": "rpool/ROOT", 12 | "Mountpoint": "/rpool/ROOT", 13 | "CanMount": "on", 14 | "Sources": { 15 | "Mountpoint": "inherited", 16 | "CanMount": "local" 17 | } 18 | }, 19 | { 20 | "Name": "rpool/ROOT/ubuntu", 21 | "Mountpoint": "/rpool/ROOT/ubuntu", 22 | "CanMount": "on", 23 | "Sources": { 24 | "Mountpoint": "inherited", 25 | "CanMount": "local" 26 | } 27 | } 28 | ] -------------------------------------------------------------------------------- /internal/zfs/pool.go: -------------------------------------------------------------------------------- 1 | package zfs 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | 7 | "github.com/ubuntu/zsys/internal/i18n" 8 | "github.com/ubuntu/zsys/internal/zfs/libzfs" 9 | ) 10 | 11 | // GetPoolFreeSpace returns the available free space on the pool 12 | func (z Zfs) GetPoolFreeSpace(n string) (freespace int, err error) { 13 | p, err := z.libzfs.PoolOpen(n) 14 | if err != nil { 15 | return 0, fmt.Errorf(i18n.G("Couldn't open pool %s: %v"), n, err) 16 | } 17 | defer p.Close() 18 | cap := p.Properties[libzfs.PoolPropCapacity].Value 19 | freespace, err = strconv.Atoi(cap) 20 | if err != nil { 21 | return 0, fmt.Errorf(i18n.G("Invalid capacity %q on pool %q: %v"), cap, n, err) 22 | } 23 | return 100 - freespace, nil 24 | } 25 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_one_dataset_one_snapshot.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "Sources": { 9 | "Mountpoint": "local", 10 | "CanMount": "local", 11 | "BootFS": "local", 12 | "LastUsed": "local" 13 | } 14 | }, 15 | { 16 | "Name": "rpool@snap1", 17 | "IsSnapshot": true, 18 | "Mountpoint": "/", 19 | "CanMount": "on", 20 | "BootFS": true, 21 | "LastUsed": 2000000000, 22 | "Sources": { 23 | "Mountpoint": "local", 24 | "CanMount": "local", 25 | "BootFS": "local" 26 | } 27 | } 28 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_snapshots_with_lastused_n_sources.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap_local_inherited 12 | last_used: 2019-04-18T02:45:55+00:00:local 13 | - name: ROOT/ubuntu/inherited 14 | snapshots: 15 | - name: snap_local_inherited 16 | last_used: 2019-04-18T02:45:55+00:00:inherited 17 | - name: ROOT/ubuntu2 18 | snapshots: 19 | - name: snap_default 20 | last_used: 2019-04-18T02:45:55+00:00:default 21 | 22 | 23 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_child_associated_one_state.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: ROOT/ubuntu_9999 11 | zsys_bootfs: yes 12 | last_used: 2018-12-10T12:20:44+00:00 13 | mountpoint: / 14 | - name: USERDATA 15 | canmount: off 16 | - name: USERDATA/user1_abcd 17 | mountpoint: /home/user1 18 | last_used: 2019-04-18T02:45:55+00:00 19 | bootfs_datasets: rpool/ROOT/ubuntu_1234,rpool/ROOT/ubuntu_9999 20 | - name: USERDATA/user1_abcd/childfor1234 21 | bootfs_datasets: rpool/ROOT/ubuntu_1234 22 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_persistent.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: ROOT/ubuntu_5678 17 | zsys_bootfs: yes 18 | last_used: 2019-12-31T07:36:17+00:00 19 | mountpoint: / 20 | canmount: noauto 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: opt 23 | mountpoint: /opt 24 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_user_snapshot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: USERDATA 11 | canmount: off 12 | - name: USERDATA/user1_abcd 13 | mountpoint: /home/user1 14 | last_used: 2018-12-10T12:20:44+00:00 15 | bootfs_datasets: rpool/ROOT/ubuntu_1234 16 | snapshots: 17 | - name: automatedusersnapshot 18 | creation_time: 2019-12-31T07:36:17+00:00 19 | - name: USERDATA/root_bcde 20 | mountpoint: /root 21 | last_used: 2018-08-03T21:55:33+00:00 22 | bootfs_datasets: rpool/ROOT/ubuntu_1234 23 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_snapshotname_with_underscore.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: USERDATA 11 | canmount: off 12 | - name: USERDATA/user1_abcd 13 | mountpoint: /home/user1 14 | last_used: 2018-12-10T12:20:44+00:00 15 | bootfs_datasets: rpool/ROOT/ubuntu_1234 16 | snapshots: 17 | - name: automated_user_snapshot 18 | creation_time: 2019-12-31T07:36:17+00:00 19 | - name: USERDATA/root_bcde 20 | mountpoint: /root 21 | last_used: 2018-08-03T21:55:33+00:00 22 | bootfs_datasets: rpool/ROOT/ubuntu_1234 23 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_linked_to_no_machines.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: USERDATA 11 | canmount: off 12 | - name: USERDATA/user1_abcd 13 | mountpoint: /home/user1 14 | last_used: 2018-12-10T12:20:44+00:00 15 | bootfs_datasets: rpool/ROOT/ubuntu_1234 16 | - name: USERDATA/user1_other 17 | mountpoint: /home/user1 18 | snapshots: 19 | - name: snap1 20 | creation_time: 2019-12-31T07:36:17+00:00 21 | - name: USERDATA/user1_efgh 22 | mountpoint: /home/user1 23 | origin: rpool/USERDATA/user1_other@snap1 24 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_children_n_snapshots_with_bootfsdatasets.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | bootfs_datasets: rpool/ROOT/ubuntu_42 9 | last_used: 2019-04-18T02:45:55+00:00 10 | mountpoint: / 11 | snapshots: 12 | - name: snap_r1 13 | - name: ROOT/ubuntu/var 14 | snapshots: 15 | - name: snap_v1 16 | - name: ROOT/ubuntu/var/lib 17 | zsys_bootfs: no 18 | - name: ROOT/ubuntu/opt 19 | - name: ROOT/ubuntu2 20 | last_used: 2018-12-10T12:20:44+00:00 21 | mountpoint: / 22 | snapshots: 23 | - name: snap_u1 24 | - name: snap_u2 25 | -------------------------------------------------------------------------------- /internal/daemon/version.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import ( 4 | "github.com/ubuntu/zsys" 5 | "github.com/ubuntu/zsys/internal/authorizer" 6 | "github.com/ubuntu/zsys/internal/config" 7 | "github.com/ubuntu/zsys/internal/i18n" 8 | "github.com/ubuntu/zsys/internal/log" 9 | ) 10 | 11 | // Version returns the version of the daemon 12 | func (s *Server) Version(req *zsys.Empty, stream zsys.Zsys_VersionServer) (err error) { 13 | if err := s.authorizer.IsAllowedFromContext(stream.Context(), authorizer.ActionAlwaysAllowed); err != nil { 14 | return err 15 | } 16 | 17 | log.Info(stream.Context(), i18n.G("Retrieving version of daemon")) 18 | 19 | stream.Send(&zsys.VersionResponse{ 20 | Reply: &zsys.VersionResponse_Version{ 21 | Version: config.Version, 22 | }, 23 | }) 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /internal/zfs/testdata/dates.refs: -------------------------------------------------------------------------------- 1 | ################################################################## 2 | # File generated with 3 | for x in $(seq 1 9); do 4 | y=15$x$x$x$x$x$x$x$x 5 | echo "$(TZ=Etc/UTC date -d"@15$x$x$x$x$x$x$x$x" -Iseconds) $y" 6 | done 7 | ################################################################## 8 | 9 | 2017-11-19T17:05:11+00:00 1511111111 10 | 2018-03-28T07:30:22+00:00 1522222222 11 | 2018-08-03T21:55:33+00:00 1533333333 12 | 2018-12-10T12:20:44+00:00 1544444444 13 | 2019-04-18T02:45:55+00:00 1555555555 14 | 2019-08-24T17:11:06+00:00 1566666666 15 | 2019-12-31T07:36:17+00:00 1577777777 16 | 2020-05-07T22:01:28+00:00 1588888888 17 | 2020-09-13T12:26:39+00:00 1599999999 <- current last_used 18 | 2033-05-18T03:33:20+00:00 2000000000 <- magic "current time" 19 | -------------------------------------------------------------------------------- /internal/machines/testdata/testremovesystemstates/remove_multiple_states_in_correct_order.golden: -------------------------------------------------------------------------------- 1 | { 2 | "Cmdline": "aaaaa bbbbb root=ZFS= ccccc", 3 | "UnmanagedDatasets": [ 4 | { 5 | "Name": "bpool", 6 | "Mountpoint": "/", 7 | "CanMount": "off" 8 | }, 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "off" 13 | }, 14 | { 15 | "Name": "bpool/BOOT", 16 | "Mountpoint": "/BOOT", 17 | "CanMount": "off" 18 | }, 19 | { 20 | "Name": "rpool/ROOT", 21 | "Mountpoint": "/ROOT", 22 | "CanMount": "off" 23 | }, 24 | { 25 | "Name": "rpool/USERDATA", 26 | "Mountpoint": "/USERDATA", 27 | "CanMount": "off" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testremovesystemstates/removing_main_dataset_deletes_its_snapshots.golden: -------------------------------------------------------------------------------- 1 | { 2 | "Cmdline": "aaaaa bbbbb root=ZFS= ccccc", 3 | "UnmanagedDatasets": [ 4 | { 5 | "Name": "bpool", 6 | "Mountpoint": "/", 7 | "CanMount": "off" 8 | }, 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "off" 13 | }, 14 | { 15 | "Name": "bpool/BOOT", 16 | "Mountpoint": "/BOOT", 17 | "CanMount": "off" 18 | }, 19 | { 20 | "Name": "rpool/ROOT", 21 | "Mountpoint": "/ROOT", 22 | "CanMount": "off" 23 | }, 24 | { 25 | "Name": "rpool/USERDATA", 26 | "Mountpoint": "/USERDATA", 27 | "CanMount": "off" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /internal/machines/testdata/m_snapshot_with_separate_boot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: bpool 17 | datasets: 18 | - name: BOOT 19 | canmount: off 20 | - name: BOOT/ubuntu_1234 21 | mountpoint: /boot 22 | snapshots: 23 | - name: snap1 24 | mountpoint: /boot:local 25 | canmount: on:local 26 | creation_time: 2018-12-10T12:20:44+00:00 27 | -------------------------------------------------------------------------------- /internal/machines/testdata/testremovesystemstates/remove_multiple_states_with_clones_in_correct_order.golden: -------------------------------------------------------------------------------- 1 | { 2 | "Cmdline": "aaaaa bbbbb root=ZFS= ccccc", 3 | "UnmanagedDatasets": [ 4 | { 5 | "Name": "bpool", 6 | "Mountpoint": "/", 7 | "CanMount": "off" 8 | }, 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "off" 13 | }, 14 | { 15 | "Name": "bpool/BOOT", 16 | "Mountpoint": "/BOOT", 17 | "CanMount": "off" 18 | }, 19 | { 20 | "Name": "rpool/ROOT", 21 | "Mountpoint": "/ROOT", 22 | "CanMount": "off" 23 | }, 24 | { 25 | "Name": "rpool/USERDATA", 26 | "Mountpoint": "/USERDATA", 27 | "CanMount": "off" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /internal/testutils/zfs_adapters.go: -------------------------------------------------------------------------------- 1 | package testutils 2 | 3 | import ( 4 | "github.com/ubuntu/zsys/internal/zfs/libzfs" 5 | "github.com/ubuntu/zsys/internal/zfs/libzfs/mock" 6 | ) 7 | 8 | // TestHelper maps testing.T and testing.B 9 | type testHelper interface { 10 | Helper() 11 | Logf(format string, args ...interface{}) 12 | } 13 | 14 | // GetMockZFS always return a zfs mock object 15 | func GetMockZFS(t testHelper) LibZFSInterface { 16 | t.Helper() 17 | 18 | t.Logf("Running tests with mocked libzfs") 19 | mock := mock.New() 20 | return &mock 21 | } 22 | 23 | // GetLibZFS returns either a mock or real system zfs depending on use system zfs flag 24 | func GetLibZFS(t testHelper) LibZFSInterface { 25 | t.Helper() 26 | 27 | if !UseSystemZFS() { 28 | return GetMockZFS(t) 29 | } 30 | return &libzfs.Adapter{} 31 | } 32 | -------------------------------------------------------------------------------- /internal/machines/testdata/testremovesystemstates/snapshots_are_removed_even_if_provided_after_main_dataset.golden: -------------------------------------------------------------------------------- 1 | { 2 | "Cmdline": "aaaaa bbbbb root=ZFS= ccccc", 3 | "UnmanagedDatasets": [ 4 | { 5 | "Name": "bpool", 6 | "Mountpoint": "/", 7 | "CanMount": "off" 8 | }, 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "off" 13 | }, 14 | { 15 | "Name": "bpool/BOOT", 16 | "Mountpoint": "/BOOT", 17 | "CanMount": "off" 18 | }, 19 | { 20 | "Name": "rpool/ROOT", 21 | "Mountpoint": "/ROOT", 22 | "CanMount": "off" 23 | }, 24 | { 25 | "Name": "rpool/USERDATA", 26 | "Mountpoint": "/USERDATA", 27 | "CanMount": "off" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_non-root_mpoint_n_datasets_no_mountpoint.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/boot", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/BOOT", 13 | "Mountpoint": "/boot/BOOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | }, 20 | { 21 | "Name": "rpool/BOOT/ubuntu", 22 | "Mountpoint": "/boot/BOOT/ubuntu", 23 | "CanMount": "on", 24 | "LastUsed": 1555555555, 25 | "Sources": { 26 | "Mountpoint": "inherited", 27 | "CanMount": "local", 28 | "LastUsed": "local" 29 | } 30 | } 31 | ] -------------------------------------------------------------------------------- /.github/workflows/commands.yaml: -------------------------------------------------------------------------------- 1 | name: Users commands 2 | on: 3 | issue_comment: 4 | types: [created] 5 | 6 | jobs: 7 | rebase: 8 | name: Rebase PR branch 9 | if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | - name: Automatic Rebase 14 | uses: cirrus-actions/rebase@1.2 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | 18 | # https://github.community/t5/GitHub-Actions/Workflow-is-failing-if-no-job-can-be-ran-due-to-condition/m-p/38186#M3250 19 | always_job: 20 | name: Aways run job 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Always run 24 | run: echo "This job is used to prevent the workflow to fail when all other jobs are skipped." -------------------------------------------------------------------------------- /cmd/zsysd/cmdhandler/common.go: -------------------------------------------------------------------------------- 1 | package cmdhandler 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/spf13/cobra" 7 | "github.com/ubuntu/zsys/internal/i18n" 8 | ) 9 | 10 | // NoCmd is a no-op command to just make it valid 11 | func NoCmd(cmd *cobra.Command, args []string) { 12 | } 13 | 14 | // RegisterAlias allows to decorelate the alias from the main command when alias have different command level (different parents) 15 | // README and manpage refers to them in each subsection (parents are differents, but only one is kept if we use the same object) 16 | func RegisterAlias(cmd, parent *cobra.Command) { 17 | alias := *cmd 18 | t := fmt.Sprintf(i18n.G("Alias of %s. %s"), cmd.CommandPath(), cmd.Short) 19 | if alias.Long != "" { 20 | t = fmt.Sprintf("%s (%s)", alias.Long, t) 21 | } 22 | alias.Long = t 23 | parent.AddCommand(&alias) 24 | } 25 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_snapshots_with_lastbootedkernel_n_sources.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap_local 12 | last_booted_kernel: vmlinuz-5.0.0-0-generic:local 13 | - name: snap_default 14 | last_booted_kernel: vmlinuz-5.0.0-0-generic:default 15 | - name: snap_inherited 16 | last_booted_kernel: vmlinuz-5.0.0-0-generic:local 17 | - name: ROOT/ubuntu/subdataset 18 | zsys_bootfs: no 19 | snapshots: 20 | - name: snap_inherited 21 | last_booted_kernel: vmlinuz-5.0.0-0-generic:inherited 22 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_n_datasets.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ROOT", 13 | "Mountpoint": "/ROOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | }, 20 | { 21 | "Name": "rpool/ROOT/ubuntu", 22 | "Mountpoint": "/", 23 | "CanMount": "on", 24 | "BootFS": true, 25 | "LastUsed": 1555555555, 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "CanMount": "local", 29 | "BootFS": "local", 30 | "LastUsed": "local" 31 | } 32 | } 33 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/m_new_dataset_without_suffix_and_clone.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | canmount: noauto 8 | mountpoint: / 9 | origin: rpool/ROOT/ubuntu_5678@snap1 10 | - name: ROOT/ubuntu_5678 11 | zsys_bootfs: yes 12 | last_used: 2019-12-31T07:36:17+00:00 13 | mountpoint: / 14 | snapshots: 15 | - name: snap1 16 | zsys_bootfs: yes:local 17 | mountpoint: /:local 18 | canmount: on:local 19 | creation_time: 2018-12-10T12:20:44+00:00 20 | - name: ROOT/ubuntu_5678/opt 21 | mountpoint: /opt 22 | snapshots: 23 | - name: snap1 24 | mountpoint: /opt:inherited 25 | canmount: on:local 26 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_n_datasets_ignore_volume.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ROOT", 13 | "Mountpoint": "/ROOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | }, 20 | { 21 | "Name": "rpool/ROOT/ubuntu", 22 | "Mountpoint": "/", 23 | "CanMount": "on", 24 | "BootFS": true, 25 | "LastUsed": 1555555555, 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "CanMount": "local", 29 | "BootFS": "local", 30 | "LastUsed": "local" 31 | } 32 | } 33 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_simple.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | last_booted_kernel: vmlinuz-5.2.0-8-generic 10 | mountpoint: / 11 | snapshots: 12 | - name: snap1 13 | zsys_bootfs: yes:local 14 | last_booted_kernel: vmlinuz-5.0.0-0-generic:local 15 | mountpoint: /:local 16 | canmount: on:local 17 | creation_time: 2018-12-10T12:20:44+00:00 18 | - name: ROOT/ubuntu_5678 19 | zsys_bootfs: yes 20 | last_used: 2019-12-31T07:36:17+00:00 21 | last_booted_kernel: vmlinuz-5.1.1-1-generic 22 | mountpoint: / 23 | canmount: noauto 24 | origin: rpool/ROOT/ubuntu_1234@snap1 25 | -------------------------------------------------------------------------------- /internal/machines/testdata/gc_system_with_unlinked_users_and_snapshot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | 11 | - name: USERDATA 12 | canmount: off 13 | - name: USERDATA/user1_abcd 14 | mountpoint: /home/user1 15 | last_used: 2018-12-10T12:20:44+00:00 16 | bootfs_datasets: rpool/ROOT/ubuntu_1234 17 | 18 | - name: USERDATA/user2_unlinked 19 | mountpoint: /home/unlinked 20 | last_used: 2018-08-03T21:55:33+00:00 21 | bootfs_datasets: "-" 22 | snapshots: 23 | - name: snapshot 24 | mountpoint: /home/unlinked:local 25 | zsys_bootfs: yes:local 26 | canmount: on:local 27 | creation_time: 2019-12-16T18:00:00+00:00 28 | 29 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_both_canmount_on.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | last_booted_kernel: vmlinuz-5.2.0-8-generic 10 | mountpoint: / 11 | snapshots: 12 | - name: snap1 13 | zsys_bootfs: yes:local 14 | last_booted_kernel: vmlinuz-5.0.0-0-generic:local 15 | mountpoint: /:local 16 | canmount: on:local 17 | creation_time: 2018-12-10T12:20:44+00:00 18 | - name: ROOT/ubuntu_5678 19 | zsys_bootfs: yes 20 | last_used: 2019-12-31T07:36:17+00:00 21 | last_booted_kernel: vmlinuz-5.1.1-1-generic 22 | mountpoint: / 23 | canmount: on 24 | origin: rpool/ROOT/ubuntu_1234@snap1 25 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_two_machines_with_same_userdata.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: ROOT/ubuntu_5678 11 | zsys_bootfs: yes 12 | last_used: 2018-12-10T12:20:44+00:00 13 | mountpoint: / 14 | canmount: noauto 15 | - name: USERDATA 16 | canmount: off 17 | - name: USERDATA/user1_abcd 18 | mountpoint: /home/user1 19 | bootfs_datasets: rpool/ROOT/ubuntu_1234,rpool/ROOT/ubuntu_5678 20 | last_used: 2018-12-10T12:20:44+00:00 21 | - name: USERDATA/root_bcde 22 | mountpoint: /root 23 | bootfs_datasets: rpool/ROOT/ubuntu_1234,rpool/ROOT/ubuntu_5678 24 | last_used: 2018-08-03T21:55:33+00:00 25 | 26 | -------------------------------------------------------------------------------- /internal/machines/testdata/testremovestate/remove_system_state_one_dataset.golden: -------------------------------------------------------------------------------- 1 | { 2 | "Cmdline": "aaaaa bbbbb root=ZFS= ccccc", 3 | "UnmanagedDatasets": [ 4 | { 5 | "Name": "rpool", 6 | "Mountpoint": "/", 7 | "CanMount": "off" 8 | }, 9 | { 10 | "Name": "rpool/ROOT", 11 | "Mountpoint": "/ROOT", 12 | "CanMount": "off" 13 | }, 14 | { 15 | "Name": "rpool/USERDATA", 16 | "Mountpoint": "/USERDATA", 17 | "CanMount": "off" 18 | }, 19 | { 20 | "Name": "rpool/USERDATA/root_bcde", 21 | "Mountpoint": "/root", 22 | "CanMount": "on", 23 | "LastUsed": 1533333333 24 | }, 25 | { 26 | "Name": "rpool/USERDATA/user1_abcd", 27 | "Mountpoint": "/home/user1", 28 | "CanMount": "on", 29 | "LastUsed": 1544444444 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/one_machine_one_dataset.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool": { 4 | "IsZsys": true, 5 | "ID": "rpool", 6 | "LastUsed": "2020-09-13T14:26:39+02:00", 7 | "Datasets": { 8 | "rpool": [ 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1599999999, 15 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 16 | } 17 | ] 18 | } 19 | } 20 | }, 21 | "AllSystemDatasets": [ 22 | { 23 | "Name": "rpool", 24 | "Mountpoint": "/", 25 | "CanMount": "on", 26 | "BootFS": true, 27 | "LastUsed": 1599999999, 28 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/testsnapshot/simple_snapshot.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local" 15 | } 16 | }, 17 | { 18 | "Name": "rpool@snap1", 19 | "IsSnapshot": true, 20 | "Mountpoint": "/", 21 | "CanMount": "on", 22 | "BootFS": true, 23 | "LastUsed": 2000000000, 24 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 25 | "Sources": { 26 | "Mountpoint": "local", 27 | "CanMount": "local", 28 | "BootFS": "local", 29 | "LastBootedKernel": "local" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/daemon/bootmenu.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os/exec" 7 | 8 | "github.com/ubuntu/zsys/internal/config" 9 | "github.com/ubuntu/zsys/internal/i18n" 10 | "github.com/ubuntu/zsys/internal/log" 11 | ) 12 | 13 | const ( 14 | updateGrubCmd = "update-grub" 15 | ) 16 | 17 | func updateBootMenu(ctx context.Context) error { 18 | log.RemotePrintln(ctx, i18n.G("ZSys is adding automatic system snapshot to GRUB menu")) 19 | cmd := exec.Command(updateGrubCmd) 20 | logger := &logWriter{ctx: ctx} 21 | cmd.Stdout = logger 22 | cmd.Stderr = logger 23 | if err := cmd.Run(); err != nil { 24 | return fmt.Errorf(i18n.G("%q returned an error: ")+config.ErrorFormat, updateGrubCmd, err) 25 | } 26 | return nil 27 | } 28 | 29 | type logWriter struct { 30 | ctx context.Context 31 | } 32 | 33 | func (lw logWriter) Write(p []byte) (n int, err error) { 34 | log.Debug(lw.ctx, string(p)) 35 | return len(p), nil 36 | } 37 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testsnapshot/recursive_snapshot_on_leaf_dataset.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local" 15 | } 16 | }, 17 | { 18 | "Name": "rpool@snap1", 19 | "IsSnapshot": true, 20 | "Mountpoint": "/", 21 | "CanMount": "on", 22 | "BootFS": true, 23 | "LastUsed": 2000000000, 24 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 25 | "Sources": { 26 | "Mountpoint": "local", 27 | "CanMount": "local", 28 | "BootFS": "local", 29 | "LastBootedKernel": "local" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testcreate/simple_creation.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local" 15 | } 16 | }, 17 | { 18 | "Name": "rpool/dataset", 19 | "Mountpoint": "/home/foo", 20 | "CanMount": "on", 21 | "BootFS": true, 22 | "LastUsed": 1555555555, 23 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 24 | "Sources": { 25 | "Mountpoint": "local", 26 | "CanMount": "local", 27 | "BootFS": "inherited", 28 | "LastUsed": "inherited", 29 | "LastBootedKernel": "inherited" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/lastused_with_children.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "LastUsed": 42, 7 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 8 | "BootfsDatasets": "something", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local", 15 | "BootfsDatasets": "local" 16 | } 17 | }, 18 | { 19 | "Name": "rpool@snap1", 20 | "IsSnapshot": true, 21 | "Mountpoint": "/", 22 | "CanMount": "on", 23 | "BootFS": true, 24 | "LastUsed": 2000000000, 25 | "LastBootedKernel": "vmlinuz-5.0.0-0-generic", 26 | "Sources": { 27 | "Mountpoint": "inherited", 28 | "BootFS": "local", 29 | "LastBootedKernel": "local" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testcreate/with_canmount_false.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local" 15 | } 16 | }, 17 | { 18 | "Name": "rpool/dataset", 19 | "Mountpoint": "/home/foo", 20 | "CanMount": "off", 21 | "BootFS": true, 22 | "LastUsed": 1555555555, 23 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 24 | "Sources": { 25 | "Mountpoint": "local", 26 | "CanMount": "local", 27 | "BootFS": "inherited", 28 | "LastUsed": "inherited", 29 | "LastBootedKernel": "inherited" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testcreate/without_mountpoint.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local" 15 | } 16 | }, 17 | { 18 | "Name": "rpool/dataset", 19 | "Mountpoint": "/dataset", 20 | "CanMount": "on", 21 | "BootFS": true, 22 | "LastUsed": 1555555555, 23 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 24 | "Sources": { 25 | "Mountpoint": "inherited", 26 | "CanMount": "local", 27 | "BootFS": "inherited", 28 | "LastUsed": "inherited", 29 | "LastBootedKernel": "inherited" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/user_property_on_snapshot_(local).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "LastUsed": 1555555555, 7 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 8 | "BootfsDatasets": "something", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local", 15 | "BootfsDatasets": "local" 16 | } 17 | }, 18 | { 19 | "Name": "rpool@snap1", 20 | "IsSnapshot": true, 21 | "Mountpoint": "/", 22 | "CanMount": "on", 23 | "BootFS": true, 24 | "LastUsed": 2000000000, 25 | "LastBootedKernel": "SetProperty Value", 26 | "Sources": { 27 | "Mountpoint": "inherited", 28 | "BootFS": "local", 29 | "LastBootedKernel": "local" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testcreate/with_mountpoint_and_canmount_false.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "BootFS": true, 7 | "LastUsed": 1555555555, 8 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local" 15 | } 16 | }, 17 | { 18 | "Name": "rpool/dataset", 19 | "Mountpoint": "/dataset", 20 | "CanMount": "off", 21 | "BootFS": true, 22 | "LastUsed": 1555555555, 23 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 24 | "Sources": { 25 | "Mountpoint": "inherited", 26 | "CanMount": "local", 27 | "BootFS": "inherited", 28 | "LastUsed": "inherited", 29 | "LastBootedKernel": "inherited" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/user_property_on_snapshot_(inherit).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "LastUsed": 1555555555, 7 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 8 | "BootfsDatasets": "something", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local", 15 | "BootfsDatasets": "local" 16 | } 17 | }, 18 | { 19 | "Name": "rpool@snap1", 20 | "IsSnapshot": true, 21 | "Mountpoint": "/", 22 | "CanMount": "on", 23 | "BootFS": true, 24 | "LastUsed": 2000000000, 25 | "LastBootedKernel": "vmlinuz-5.0.0-0-generic", 26 | "Sources": { 27 | "Mountpoint": "inherited", 28 | "BootFS": "local", 29 | "LastBootedKernel": "local" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/selected_machine_doesn_t_exist.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool": { 4 | "IsZsys": true, 5 | "ID": "rpool", 6 | "LastUsed": "2020-09-13T14:26:39+02:00", 7 | "Datasets": { 8 | "rpool": [ 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1599999999, 15 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 16 | } 17 | ] 18 | } 19 | } 20 | }, 21 | "Cmdline": "aaaaa bbbbb root=ZFS=foo ccccc", 22 | "AllSystemDatasets": [ 23 | { 24 | "Name": "rpool", 25 | "Mountpoint": "/", 26 | "CanMount": "on", 27 | "BootFS": true, 28 | "LastUsed": 1599999999, 29 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/snapshot_user_properties_differs_from_parent_dataset.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "LastUsed": 1555555555, 7 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 8 | "BootfsDatasets": "something", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local", 15 | "BootfsDatasets": "local" 16 | } 17 | }, 18 | { 19 | "Name": "rpool@snap1", 20 | "IsSnapshot": true, 21 | "Mountpoint": "/", 22 | "CanMount": "on", 23 | "BootFS": true, 24 | "LastUsed": 2000000000, 25 | "LastBootedKernel": "vmlinuz-5.0.0-0-generic", 26 | "Sources": { 27 | "Mountpoint": "inherited", 28 | "BootFS": "local", 29 | "LastBootedKernel": "local" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/snapshotmountpointprop_is_mountpointprop.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "LastUsed": 1555555555, 7 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 8 | "BootfsDatasets": "something", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local", 15 | "BootfsDatasets": "local" 16 | } 17 | }, 18 | { 19 | "Name": "rpool@snap1", 20 | "IsSnapshot": true, 21 | "Mountpoint": "/home/a/path", 22 | "CanMount": "on", 23 | "BootFS": true, 24 | "LastUsed": 2000000000, 25 | "LastBootedKernel": "vmlinuz-5.0.0-0-generic", 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "BootFS": "local", 29 | "LastBootedKernel": "local" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/zfs/testdata/testsetproperty/user_property_on_snapshot_(inherit_but_forced).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "on", 6 | "LastUsed": 1555555555, 7 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic", 8 | "BootfsDatasets": "something", 9 | "Sources": { 10 | "Mountpoint": "local", 11 | "CanMount": "local", 12 | "BootFS": "local", 13 | "LastUsed": "local", 14 | "LastBootedKernel": "local", 15 | "BootfsDatasets": "local" 16 | } 17 | }, 18 | { 19 | "Name": "rpool@snap1", 20 | "IsSnapshot": true, 21 | "Mountpoint": "/home/a/path", 22 | "CanMount": "on", 23 | "BootFS": true, 24 | "LastUsed": 2000000000, 25 | "LastBootedKernel": "vmlinuz-5.0.0-0-generic", 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "BootFS": "local", 29 | "LastBootedKernel": "local" 30 | } 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_multiple_clones_recursive.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: main 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | mountpoint: / 8 | snapshots: 9 | - name: snap1 10 | mountpoint: /:local 11 | canmount: on:local 12 | creation_time: 2020-05-07T22:01:28+00:00 13 | - name: clone 14 | zsys_bootfs: yes 15 | last_used: 2019-12-31T07:36:17+00:00 16 | mountpoint: / 17 | canmount: noauto 18 | origin: rpool/main@snap1 19 | snapshots: 20 | - name: snap2 21 | mountpoint: /:local 22 | canmount: on:local 23 | creation_time: 2019-08-24T17:11:06+00:00 24 | - name: clone2 25 | zsys_bootfs: yes 26 | last_used: 2019-04-18T02:45:55+00:00 27 | mountpoint: / 28 | canmount: noauto 29 | origin: rpool/clone@snap2 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **For ubuntu users, please run and copy the following:** 24 | 1. `ubuntu-bug zsys --save=/tmp/report` 25 | 2. Copy paste below `/tmp/report` content: 26 | ``` 27 | COPY REPORT CONTENT HERE. 28 | ``` 29 | 30 | **Screenshots** 31 | If applicable, add screenshots to help explain your problem. 32 | 33 | **Installed versions:** 34 | - OS: (`/etc/os-release`) 35 | - Zsysd running version: (`zsysctl version` output) 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_multiple_clones_recursive_unordered.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: main 5 | zsys_bootfs: yes 6 | last_used: 2020-09-13T12:26:39+00:00 7 | mountpoint: / 8 | snapshots: 9 | - name: snap1 10 | mountpoint: /:local 11 | canmount: on:local 12 | creation_time: 2020-05-07T22:01:28+00:00 13 | - name: clone2 14 | zsys_bootfs: yes 15 | last_used: 2019-04-18T02:45:55+00:00 16 | mountpoint: / 17 | canmount: noauto 18 | origin: rpool/clone@snap2 19 | - name: clone 20 | zsys_bootfs: yes 21 | last_used: 2019-12-31T07:36:17+00:00 22 | mountpoint: / 23 | canmount: noauto 24 | origin: rpool/main@snap1 25 | snapshots: 26 | - name: snap2 27 | mountpoint: /:local 28 | canmount: on:local 29 | creation_time: 2019-08-24T17:11:06+00:00 30 | -------------------------------------------------------------------------------- /internal/machines/testdata/gc_system_failed_revert.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: autozsys_20200101-1100 12 | mountpoint: /:local 13 | zsys_bootfs: yes:local 14 | canmount: on:local 15 | creation_time: 2020-01-01T11:00:00+00:00 16 | - name: autozsys_20200101-1000 17 | mountpoint: /:local 18 | zsys_bootfs: yes:local 19 | canmount: on:local 20 | creation_time: 2020-01-01T10:00:00+00:00 21 | - name: autozsys_20200101-0900 22 | mountpoint: /:local 23 | zsys_bootfs: yes:local 24 | canmount: on:local 25 | creation_time: 2020-01-01T09:00:00+00:00 26 | - name: ROOT/ubuntu_failedboot 27 | zsys_bootfs: yes 28 | mountpoint: / 29 | origin: rpool/ROOT/ubuntu_1234@autozsys_20200101-1100 30 | -------------------------------------------------------------------------------- /internal/config/zsys.conf: -------------------------------------------------------------------------------- 1 | history: 2 | # Keep at least n history entry per unit of time if enough of them are present 3 | # The order condition the bucket start and end dates (from most recent to oldest) 4 | gcstartafter: 1 5 | keeplast: 20 # Minimum number of recent states to keep. 6 | # - name: Abitrary name of the bucket 7 | # buckets: Number of buckets over the interval 8 | # bucketlength: Length of each bucket in days 9 | # samplesperbucket: Number of datasets to keep in each bucket 10 | gcrules: 11 | - name: PreviousDay 12 | buckets: 1 13 | bucketlength: 1 14 | samplesperbucket: 3 15 | - name: PreviousWeek 16 | buckets: 5 17 | bucketlength: 1 18 | samplesperbucket: 1 19 | - name: PreviousMonth 20 | buckets: 4 21 | bucketlength: 7 22 | samplesperbucket: 1 23 | general: 24 | # Minimal free space required before taking a snapshot 25 | minfreepoolspace: 20 26 | # Daemon timeout in seconds 27 | timeout: 60 28 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_clones.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | mountpoint: / 8 | snapshots: 9 | - name: snap0 10 | - name: snap1 11 | # This is created imperatively in TestPromoteCloneTree() 12 | # - name: ROOT/ubuntu_5678 13 | # mountpoint: / 14 | # canmount: noauto 15 | # origin: rpool/ROOT/ubuntu_1234@snap1 16 | # snapshots: 17 | # - name: snap2 18 | # - name: snap8888 19 | # - name: ROOT/ubuntu_9876 20 | # mountpoint: / 21 | # canmount: noauto 22 | # origin: rpool/ROOT/ubuntu_5678@snap2 23 | # snapshots: 24 | # - name: snap3 25 | # - name: ROOT/ubuntu_9999 26 | # mountpoint: / 27 | # canmount: noauto 28 | # origin: rpool/ROOT/ubuntu_9876@snap3 29 | # - name: ROOT/ubuntu_8888 30 | # mountpoint: / 31 | # canmount: noauto 32 | # origin: rpool/ROOT/ubuntu_5678@snap8888 33 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_snapshot_attached.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: system-snapshot 12 | mountpoint: /:local 13 | creation_time: 2018-12-10T12:20:44+00:00 14 | - name: USERDATA 15 | canmount: off 16 | - name: USERDATA/user1_abcd 17 | mountpoint: /home/user1 18 | last_used: 2018-12-10T12:20:44+00:00 19 | snapshots: 20 | - name: system-snapshot 21 | mountpoint: /home/user1:local 22 | creation_time: 2018-12-10T12:20:44+00:00 23 | - name: USERDATA/user1_abcd/tools 24 | mountpoint: /home/user1/tools 25 | last_used: 2018-12-10T12:20:44+00:00 26 | snapshots: 27 | - name: system-snapshot 28 | mountpoint: /home/user1/tools:inherited 29 | creation_time: 2018-12-10T12:20:44+00:00 -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_origin_doesnt_exist.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | last_booted_kernel: vmlinuz-5.2.0-8-generic 10 | mountpoint: / 11 | snapshots: 12 | - name: snap1 13 | zsys_bootfs: yes:local 14 | last_booted_kernel: vmlinuz-5.0.0-0-generic:local 15 | mountpoint: /:local 16 | canmount: on:local 17 | creation_time: 2018-12-10T12:20:44+00:00 18 | - name: ROOT/ubuntu_5678 19 | zsys_bootfs: yes 20 | last_used: 2019-12-31T07:36:17+00:00 21 | last_booted_kernel: vmlinuz-5.1.1-1-generic 22 | mountpoint: / 23 | canmount: noauto 24 | origin: rpool/ROOT/ubuntu_1234@snap1 25 | - name: USERDATA 26 | canmount: off 27 | - name: USERDATA/user1_abcd 28 | origin: nopool/USERDATA/ubuntu_1234@snap1 29 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_snapshot_with_userdata.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: USERDATA 17 | canmount: off 18 | - name: USERDATA/user1_abcd 19 | mountpoint: /home/user1 20 | bootfs_datasets: rpool/ROOT/ubuntu_1234 21 | last_used: 2018-12-10T12:20:44+00:00 22 | snapshots: 23 | - name: snap1 24 | mountpoint: /home/user1:local 25 | canmount: on:local 26 | creation_time: 2018-03-28T07:30:22+00:00 27 | - name: USERDATA/root_bcde 28 | mountpoint: /root 29 | bootfs_datasets: rpool/ROOT/ubuntu_1234 30 | last_used: 2018-08-03T21:55:33+00:00 31 | 32 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_two_machines_with_different_userdata.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: ROOT/ubuntu_5678 11 | zsys_bootfs: yes 12 | last_used: 2018-12-10T12:20:44+00:00 13 | mountpoint: / 14 | canmount: noauto 15 | - name: USERDATA 16 | canmount: off 17 | - name: USERDATA/user1_abcd 18 | mountpoint: /home/user1 19 | bootfs_datasets: rpool/ROOT/ubuntu_1234 20 | last_used: 2018-12-10T12:20:44+00:00 21 | - name: USERDATA/user1_efgh 22 | mountpoint: /home/user1 23 | bootfs_datasets: rpool/ROOT/ubuntu_5678 24 | last_used: 2018-03-28T07:30:22+00:00 25 | - name: USERDATA/root_bcde 26 | mountpoint: /root 27 | bootfs_datasets: rpool/ROOT/ubuntu_1234 28 | last_used: 2018-08-03T21:55:33+00:00 29 | 30 | -------------------------------------------------------------------------------- /internal/generators/copy.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | package main 5 | 6 | import ( 7 | "io" 8 | "log" 9 | "os" 10 | "path/filepath" 11 | 12 | "github.com/ubuntu/zsys/internal/generators" 13 | ) 14 | 15 | func main() { 16 | if len(os.Args) != 4 { 17 | log.Fatal("Expect 3 arguments: ") 18 | } 19 | root := generators.DestDirectory(os.Args[3]) 20 | dir := filepath.Join(root, os.Args[2]) 21 | 22 | if err := os.MkdirAll(dir, 0755); err != nil { 23 | log.Fatalf("Couldn't create dest directory: %v", err) 24 | } 25 | 26 | from, err := os.Open(os.Args[1]) 27 | if err != nil { 28 | log.Fatalf("Couldn't open source file: %v", err) 29 | } 30 | defer from.Close() 31 | 32 | dest, err := os.OpenFile(filepath.Join(dir, filepath.Base(os.Args[1])), os.O_RDWR|os.O_CREATE, 0666) 33 | if err != nil { 34 | log.Fatal("Couldn't open dest file: %v", err) 35 | } 36 | defer dest.Close() 37 | 38 | _, err = io.Copy(dest, from) 39 | if err != nil { 40 | log.Fatalf("Copy failed: %v", err) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /internal/machines/testdata/gc_system_with_unlinked_users_unmanaged_user_clone.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | 11 | - name: USERDATA 12 | canmount: off 13 | - name: USERDATA/user1_abcd 14 | mountpoint: /home/user1 15 | last_used: 2018-12-10T12:20:44+00:00 16 | bootfs_datasets: rpool/ROOT/ubuntu_1234 17 | 18 | - name: USERDATA/user2_unlinked 19 | mountpoint: /home/unlinked 20 | last_used: 2018-08-03T21:55:33+00:00 21 | bootfs_datasets: "-" 22 | snapshots: 23 | - name: snapshot 24 | mountpoint: /home/unlinked:local 25 | zsys_bootfs: yes:local 26 | canmount: on:local 27 | creation_time: 2019-12-16T18:00:00+00:00 28 | - name: user2_clone 29 | mountpoint: /home/unlinked 30 | last_used: 2018-08-03T21:55:33+00:00 31 | origin: rpool/USERDATA/user2_unlinked@snapshot 32 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_snapshot_with_separate_boot_with_children.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: bpool 17 | datasets: 18 | - name: BOOT 19 | canmount: off 20 | - name: BOOT/ubuntu_1234 21 | mountpoint: /boot 22 | snapshots: 23 | - name: snap1 24 | mountpoint: /boot:local 25 | canmount: on:local 26 | creation_time: 2018-12-10T12:20:44+00:00 27 | - name: BOOT/ubuntu_1234/grub 28 | snapshots: 29 | - name: snap1 30 | mountpoint: /boot/grub:inherited 31 | canmount: on:local 32 | creation_time: 2018-12-10T12:20:44+00:00 33 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_multiple_clones_recursive.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Bootfs": true, 5 | "LastUsed": 1599999999, 6 | "Mountpoint": "/", 7 | "CanMount": "on" 8 | }, 9 | { 10 | "Name": "rpool@snap1", 11 | "Bootfs": true, 12 | "LastUsed": 1588888888, 13 | "IsSnapshot": true, 14 | "Mountpoint": "/" 15 | }, 16 | { 17 | "Name": "rpool_clone", 18 | "Bootfs": true, 19 | "LastUsed": 1577777777, 20 | "Mountpoint": "/", 21 | "CanMount": "noauto", 22 | "Origin": "rpool@snap1" 23 | }, 24 | { 25 | "Name": "rpool_clone@snap2", 26 | "Bootfs": true, 27 | "LastUsed": 1566666666, 28 | "IsSnapshot": true, 29 | "Mountpoint": "/" 30 | }, 31 | { 32 | "Name": "rpool_clone2", 33 | "Bootfs": true, 34 | "LastUsed": 1555555555, 35 | "Mountpoint": "/", 36 | "CanMount": "noauto", 37 | "Origin": "rpool_clone@snap2" 38 | } 39 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/gc_system_with_unlinked_users_unmanaged_clone_bootfs_on_clone.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | 11 | - name: USERDATA 12 | canmount: off 13 | - name: USERDATA/user1_abcd 14 | mountpoint: /home/user1 15 | last_used: 2018-12-10T12:20:44+00:00 16 | bootfs_datasets: rpool/ROOT/ubuntu_1234 17 | 18 | - name: USERDATA/user2_unlinked 19 | mountpoint: /home/unlinked 20 | last_used: 2018-08-03T21:55:33+00:00 21 | snapshots: 22 | - name: snapshot 23 | mountpoint: /home/unlinked:local 24 | zsys_bootfs: yes:local 25 | canmount: on:local 26 | creation_time: 2019-12-16T18:00:00+00:00 27 | - name: USERDATA/user2_clone 28 | mountpoint: /home/unlinked 29 | last_used: 2018-08-03T21:55:33+00:00 30 | bootfs_datasets: "-" 31 | origin: rpool/USERDATA/user2_unlinked@snapshot 32 | -------------------------------------------------------------------------------- /internal/machines/testdata/gc_system_with_unlinked_users_unmanaged_clone_nobootfs_dataset.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | 11 | - name: USERDATA 12 | canmount: off 13 | - name: USERDATA/user1_abcd 14 | mountpoint: /home/user1 15 | last_used: 2018-12-10T12:20:44+00:00 16 | bootfs_datasets: rpool/ROOT/ubuntu_1234 17 | 18 | - name: USERDATA/user2_unlinked 19 | mountpoint: /home/unlinked 20 | last_used: 2018-08-03T21:55:33+00:00 21 | bootfs_datasets: "-" 22 | snapshots: 23 | - name: snapshot 24 | mountpoint: /home/unlinked:local 25 | zsys_bootfs: yes:local 26 | canmount: on:local 27 | creation_time: 2019-12-16T18:00:00+00:00 28 | - name: USERDATA/user2_clone 29 | mountpoint: /home/unlinked 30 | last_used: 2018-08-03T21:55:33+00:00 31 | origin: rpool/USERDATA/user2_unlinked@snapshot 32 | -------------------------------------------------------------------------------- /internal/machines/testdata/d_one_machine_with_multiple_clones_recursive_unordered.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Bootfs": true, 5 | "LastUsed": 1599999999, 6 | "Mountpoint": "/", 7 | "CanMount": "on" 8 | }, 9 | { 10 | "Name": "rpool_clone2", 11 | "Bootfs": true, 12 | "LastUsed": 1588888888, 13 | "Mountpoint": "/", 14 | "CanMount": "noauto", 15 | "Origin": "rpool_clone@snap2" 16 | }, 17 | { 18 | "Name": "rpool_clone", 19 | "Bootfs": true, 20 | "LastUsed": 1577777777, 21 | "Mountpoint": "/", 22 | "CanMount": "noauto", 23 | "Origin": "rpool@snap1" 24 | }, 25 | { 26 | "Name": "rpool_clone@snap2", 27 | "Bootfs": true, 28 | "LastUsed": 1566666666, 29 | "IsSnapshot": true, 30 | "Mountpoint": "/" 31 | }, 32 | { 33 | "Name": "rpool@snap1", 34 | "Bootfs": true, 35 | "LastUsed": 1555555555, 36 | "IsSnapshot": true, 37 | "Mountpoint": "/" 38 | } 39 | ] -------------------------------------------------------------------------------- /internal/generators/common.go: -------------------------------------------------------------------------------- 1 | // Package generators contains common helpers for generators 2 | package generators 3 | 4 | import ( 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | const installVar = "ZSYS_GENERATE_ONLY_INSTALL_SHARE_PREFIX" 10 | 11 | // CleanDirectory removes a directory and recreates it. 12 | func CleanDirectory(p string) error { 13 | if err := os.RemoveAll(p); err != nil { 14 | return fmt.Errorf("Couldn't delete %q: %v", p, err) 15 | } 16 | if err := os.MkdirAll(p, 0755); err != nil { 17 | return fmt.Errorf("Couldn't create %q: %v", p, err) 18 | } 19 | return nil 20 | } 21 | 22 | // InstallOnlyMode returns if we only want to install and not affect current repository. 23 | func InstallOnlyMode() bool { 24 | return os.Getenv(installVar) != "" 25 | } 26 | 27 | // DestDirectory returns the destination directory to generate to. 28 | // It will prefer the zsys install directory if available, or will return path otherwise 29 | func DestDirectory(p string) string { 30 | installDir := os.Getenv(installVar) 31 | if installDir == "" { 32 | installDir = p 33 | } 34 | return installDir 35 | } 36 | -------------------------------------------------------------------------------- /internal/machines/testdata/gc_system_with_unlinked_users_unmanaged_clone.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | 11 | - name: USERDATA 12 | canmount: off 13 | - name: USERDATA/user1_abcd 14 | mountpoint: /home/user1 15 | last_used: 2018-12-10T12:20:44+00:00 16 | bootfs_datasets: rpool/ROOT/ubuntu_1234 17 | 18 | - name: USERDATA/user2_unlinked 19 | mountpoint: /home/unlinked 20 | last_used: 2018-08-03T21:55:33+00:00 21 | bootfs_datasets: "-" 22 | snapshots: 23 | - name: snapshot 24 | mountpoint: /home/unlinked:local 25 | zsys_bootfs: yes:local 26 | canmount: on:local 27 | creation_time: 2019-12-16T18:00:00+00:00 28 | - name: USERDATA/user2_clone 29 | mountpoint: /home/unlinked 30 | last_used: 2018-08-03T21:55:33+00:00 31 | bootfs_datasets: "-" 32 | origin: rpool/USERDATA/user2_unlinked@snapshot 33 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_children_n_snapshots.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap_r1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | - name: ROOT/ubuntu/var 16 | snapshots: 17 | - name: snap_v1 18 | zsys_bootfs: yes:inherited 19 | mountpoint: /var:inherited 20 | canmount: on:local 21 | - name: ROOT/ubuntu/var/lib 22 | zsys_bootfs: no 23 | - name: ROOT/ubuntu/opt 24 | - name: ROOT/ubuntu2 25 | last_used: 2018-12-10T12:20:44+00:00 26 | mountpoint: / 27 | snapshots: 28 | - name: snap_u1 29 | mountpoint: /:local 30 | canmount: on:local 31 | - name: snap_u2 32 | mountpoint: /:local 33 | canmount: on:local 34 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_dataset_and_snapshot_attached.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: system-snapshot 12 | mountpoint: /:local 13 | creation_time: 2018-12-10T12:20:44+00:00 14 | - name: USERDATA 15 | canmount: off 16 | - name: USERDATA/user1_abcd 17 | mountpoint: /home/user1 18 | last_used: 2018-12-10T12:20:44+00:00 19 | bootfs_datasets: rpool/ROOT/ubuntu_1234 20 | snapshots: 21 | - name: system-snapshot 22 | mountpoint: /home/user1:local 23 | creation_time: 2018-12-10T12:20:44+00:00 24 | - name: USERDATA/user1_abcd/tools 25 | mountpoint: /home/user1/tools 26 | last_used: 2018-12-10T12:20:44+00:00 27 | snapshots: 28 | - name: system-snapshot 29 | mountpoint: /home/user1/tools:inherited 30 | creation_time: 2018-12-10T12:20:44+00:00 -------------------------------------------------------------------------------- /internal/zfs/testdata/two_pools_n_datasets_n_snapshots.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap_r1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | - name: snap_r2 16 | zsys_bootfs: yes:local 17 | mountpoint: /:local 18 | canmount: on:local 19 | - name: bpool 20 | datasets: 21 | - name: BOOT 22 | canmount: off 23 | - name: BOOT/boot 24 | zsys_bootfs: yes 25 | last_used: 2019-04-18T02:45:55+00:00 26 | mountpoint: /boot 27 | snapshots: 28 | - name: snap_b1 29 | zsys_bootfs: yes:local 30 | mountpoint: /boot:local 31 | canmount: on:local 32 | - name: snap_b2 33 | zsys_bootfs: yes:local 34 | mountpoint: /boot:local 35 | canmount: on:local 36 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_main_dataset_without_suffix_and_clone.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | canmount: noauto 10 | mountpoint: / 11 | origin: rpool/ROOT/ubuntu_5678@snap1 12 | - name: ROOT/ubuntu/opt 13 | canmount: noauto 14 | mountpoint: /opt 15 | origin: rpool/ROOT/ubuntu_5678/opt@snap1 16 | - name: ROOT/ubuntu_5678 17 | zsys_bootfs: yes 18 | last_used: 2019-12-31T07:36:17+00:00 19 | mountpoint: / 20 | snapshots: 21 | - name: snap1 22 | zsys_bootfs: yes:local 23 | mountpoint: /:local 24 | canmount: on:local 25 | creation_time: 2018-12-10T12:20:44+00:00 26 | - name: ROOT/ubuntu_5678/opt 27 | mountpoint: /opt 28 | snapshots: 29 | - name: snap1 30 | mountpoint: /opt:inherited 31 | canmount: on:local 32 | creation_time: 2018-12-10T12:20:44+00:00 33 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: zsys 2 | Section: admin 3 | Priority: optional 4 | Maintainer: Ubuntu Developers 5 | Build-Depends: debhelper-compat (= 13), 6 | dh-apport, 7 | dh-golang, 8 | golang-go, 9 | libzfslinux-dev (>= 2.1.99), 10 | zfsutils-linux, 11 | grub2-common, 12 | dbus, 13 | Standards-Version: 4.1.3 14 | Rules-Requires-Root: no 15 | XS-Go-Import-Path: github.com/ubuntu/zsys 16 | Homepage: https://github.com/ubuntu/zsys 17 | 18 | Package: zsys 19 | Architecture: amd64 arm64 ppc64el riscv64 20 | Built-Using: ${misc:Built-Using}, 21 | Depends: ${shlibs:Depends}, 22 | ${misc:Depends}, 23 | grub2-common, 24 | zfs-zed, 25 | Recommends: zfsutils-linux, 26 | Description: ZFS SYStem integration 27 | ZSYS is a Zfs SYStem tool targetting an enhanced ZOL experience. 28 | It allows running multiple ZFS system in parallels on the same machine, 29 | get automated snapshots, managing complex zfs dataset layouts separating 30 | user data from system and persistent data, and more. 31 | -------------------------------------------------------------------------------- /internal/authorizer/export_test.go: -------------------------------------------------------------------------------- 1 | package authorizer 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/godbus/dbus/v5" 7 | ) 8 | 9 | var ( 10 | WithAuthority = withAuthority 11 | WithRoot = withRoot 12 | WithUserLookup = withUserLookup 13 | ) 14 | 15 | type PeerCredsInfo = peerCredsInfo 16 | 17 | func NewTestPeerCredsInfo(uid uint32, pid int32) PeerCredsInfo { 18 | return PeerCredsInfo{uid: uid, pid: pid} 19 | } 20 | 21 | type DbusMock struct { 22 | IsAuthorized bool 23 | WantPolkitError bool 24 | 25 | actionRequested Action 26 | } 27 | 28 | func (d *DbusMock) Call(method string, flags dbus.Flags, args ...interface{}) *dbus.Call { 29 | var errPolkit error 30 | 31 | d.actionRequested = Action(args[1].(string)) 32 | 33 | if d.WantPolkitError { 34 | errPolkit = errors.New("Polkit error") 35 | } 36 | 37 | return &dbus.Call{ 38 | Err: errPolkit, 39 | Body: []interface{}{ 40 | []interface{}{ 41 | d.IsAuthorized, 42 | true, 43 | map[string]string{ 44 | "polkit.retains_authorization_after_challenge": "true", 45 | "polkit.dismissed": "true", 46 | }, 47 | }, 48 | }, 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_children_n_snapshots_canmount_off.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap_r1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | - name: ROOT/ubuntu/var 16 | canmount: off 17 | snapshots: 18 | - name: snap_v1 19 | zsys_bootfs: yes:inherited 20 | mountpoint: /var:inherited 21 | canmount: off:local 22 | - name: ROOT/ubuntu/var/lib 23 | zsys_bootfs: no 24 | - name: ROOT/ubuntu/opt 25 | - name: ROOT/ubuntu2 26 | last_used: 2018-12-10T12:20:44+00:00 27 | mountpoint: / 28 | snapshots: 29 | - name: snap_u1 30 | mountpoint: /:local 31 | canmount: on:local 32 | - name: snap_u2 33 | mountpoint: /:local 34 | canmount: on:local 35 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | #export DH_VERBOSE = 1 3 | 4 | export GOCACHE=$(shell mktemp -d /tmp/gocache-XXXX) 5 | export GOFLAGS=-ldflags=-X=github.com/ubuntu/zsys/internal/config.Version=$(shell dpkg-parsechangelog -S Version) --mod=vendor 6 | export DH_GOLANG_INSTALL_ALL=1 7 | 8 | # Tell go generate to only install on-the-fly assets 9 | export ZSYS_GENERATE_ONLY_INSTALL_SHARE_PREFIX=$(CURDIR)/debian/zsys/usr/share 10 | 11 | %: 12 | dh $@ --buildsystem=golang --with=golang,apport 13 | 14 | override_dh_auto_clean: 15 | dh_auto_clean 16 | # create the vendor directory when building the source package 17 | [ -d vendor/ ] || go mod vendor 18 | 19 | override_dh_auto_install: 20 | dh_auto_install -- --no-source 21 | # install in /sbin 22 | mv debian/zsys/usr/bin/ debian/zsys/sbin 23 | rmdir debian/zsys/usr/ 24 | # create zsysctl command 25 | ln -s zsysd debian/zsys/sbin/zsysctl 26 | # run go generate for only installed generated assets 27 | # TODO this sometimes fails on ppc64le 28 | go generate $(GOFLAGS) ./... 29 | ls -latr debian/zsys/usr/share/locale/de/LC_MESSAGES/ 30 | ls -latr debian/zsys/usr/share/locale/fr/LC_MESSAGES/ 31 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_main_dataset_without_suffix_and_clone_to_promote.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | origin: rpool/ROOT/ubuntu_5678@snap1 11 | - name: ROOT/ubuntu/opt 12 | mountpoint: /opt 13 | origin: rpool/ROOT/ubuntu_5678/opt@snap1 14 | - name: ROOT/ubuntu_5678 15 | zsys_bootfs: yes 16 | last_used: 2019-12-31T07:36:17+00:00 17 | mountpoint: / 18 | canmount: noauto 19 | snapshots: 20 | - name: snap1 21 | zsys_bootfs: yes:local 22 | mountpoint: /:local 23 | canmount: on:local 24 | creation_time: 2018-12-10T12:20:44+00:00 25 | - name: ROOT/ubuntu_5678/opt 26 | mountpoint: /opt 27 | canmount: noauto 28 | snapshots: 29 | - name: snap1 30 | mountpoint: /opt:inherited 31 | canmount: on:local 32 | creation_time: 2018-12-10T12:20:44+00:00 33 | -------------------------------------------------------------------------------- /debian/zsys.postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # The zsysd service fails to start if the zfs kernel module is not loaded, 5 | # so we make sure it's loaded here first. 6 | modprobe -v zfs || true 7 | 8 | is_zsys() { 9 | dsname="$(findmnt -o SOURCE -n /)" 10 | if [ -z "$dsname" ]; then 11 | return 1 12 | fi 13 | if [ "$(zfs get com.ubuntu.zsys:bootfs -H -o value "$dsname")" != "yes" ]; then 14 | return 1 15 | fi 16 | return 0 17 | } 18 | 19 | case "$1" in 20 | configure) 21 | # Enable autotrim for zsys pools 22 | if dpkg --compare-versions "$2" le-nl '0.5.0'; then 23 | if is_zsys; then 24 | for mountpoint in / /boot; do 25 | dsname="$(findmnt -o SOURCE -n ${mountpoint}||true)" 26 | if [ -n "$dsname" ]; then 27 | zpool set autotrim=on ${dsname%%/*} || true 28 | zpool trim ${dsname%%/*} || true 29 | fi 30 | done 31 | fi 32 | fi 33 | ;; 34 | esac 35 | 36 | 37 | #DEBHELPER# 38 | -------------------------------------------------------------------------------- /cmd/zsysd/daemon/boot.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io/ioutil" 7 | 8 | "github.com/ubuntu/zsys/internal/config" 9 | "github.com/ubuntu/zsys/internal/i18n" 10 | "github.com/ubuntu/zsys/internal/machines" 11 | ) 12 | 13 | func syncBootPrepare() (err error) { 14 | cmdline, err := procCmdline() 15 | if err != nil { 16 | return fmt.Errorf(i18n.G("couldn't parse kernel command line: %v"), err) 17 | } 18 | ms, err := machines.New(context.Background(), cmdline) 19 | if err != nil { 20 | return fmt.Errorf(i18n.G("couldn't create a new machine: %v"), err) 21 | } 22 | 23 | changed, err := ms.EnsureBoot(context.Background()) 24 | if err != nil { 25 | return fmt.Errorf(i18n.G("couldn't ensure boot: ")+config.ErrorFormat, err) 26 | } 27 | 28 | if changed { 29 | fmt.Println(config.ModifiedBoot) 30 | } else { 31 | fmt.Println(config.NoModifiedBoot) 32 | } 33 | 34 | return nil 35 | } 36 | 37 | // procCmdline returns kernel command line 38 | func procCmdline() (string, error) { 39 | content, err := ioutil.ReadFile("/proc/cmdline") 40 | if err != nil { 41 | return "", err 42 | } 43 | 44 | return string(content), nil 45 | } 46 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_separate_boot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: ROOT/ubuntu_5678 17 | zsys_bootfs: yes 18 | last_used: 2019-12-31T07:36:17+00:00 19 | mountpoint: / 20 | canmount: noauto 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: bpool 23 | datasets: 24 | - name: BOOT 25 | canmount: off 26 | - name: BOOT/ubuntu_1234 27 | mountpoint: /boot 28 | snapshots: 29 | - name: snap1 30 | mountpoint: /boot:local 31 | canmount: on:local 32 | creation_time: 2018-12-10T12:20:44+00:00 33 | - name: BOOT/ubuntu_5678 34 | mountpoint: /boot 35 | origin: bpool/BOOT/ubuntu_1234@snap1 36 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/one_pool_n_datasets_one_snapshot.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ROOT", 13 | "Mountpoint": "/ROOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | }, 20 | { 21 | "Name": "rpool/ROOT/ubuntu", 22 | "Mountpoint": "/", 23 | "CanMount": "on", 24 | "BootFS": true, 25 | "LastUsed": 1555555555, 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "CanMount": "local", 29 | "BootFS": "local", 30 | "LastUsed": "local" 31 | } 32 | }, 33 | { 34 | "Name": "rpool/ROOT/ubuntu@snap1", 35 | "IsSnapshot": true, 36 | "Mountpoint": "/", 37 | "CanMount": "on", 38 | "BootFS": true, 39 | "LastUsed": 2000000000, 40 | "Sources": { 41 | "Mountpoint": "local", 42 | "CanMount": "local", 43 | "BootFS": "local" 44 | } 45 | } 46 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/testremovestate/remove_system_state_complex_with_boot_children_and_user_datasets.golden: -------------------------------------------------------------------------------- 1 | { 2 | "Cmdline": "aaaaa bbbbb root=ZFS= ccccc", 3 | "UnmanagedDatasets": [ 4 | { 5 | "Name": "bpool", 6 | "Mountpoint": "/boot", 7 | "CanMount": "off" 8 | }, 9 | { 10 | "Name": "bpool/BOOT", 11 | "Mountpoint": "/boot/BOOT", 12 | "CanMount": "off" 13 | }, 14 | { 15 | "Name": "rpool", 16 | "Mountpoint": "/", 17 | "CanMount": "off" 18 | }, 19 | { 20 | "Name": "rpool/ROOT", 21 | "Mountpoint": "/ROOT", 22 | "CanMount": "off" 23 | }, 24 | { 25 | "Name": "rpool/USERDATA", 26 | "Mountpoint": "/USERDATA", 27 | "CanMount": "off" 28 | }, 29 | { 30 | "Name": "rpool/USERDATA/root_bcde", 31 | "Mountpoint": "/root", 32 | "CanMount": "on", 33 | "LastUsed": 1533333333 34 | }, 35 | { 36 | "Name": "rpool/USERDATA/user1_abcd", 37 | "Mountpoint": "/home/user1", 38 | "CanMount": "on", 39 | "LastUsed": 1544444444 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_separate_boot_to_promote.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | canmount: noauto 11 | snapshots: 12 | - name: snap1 13 | zsys_bootfs: yes:local 14 | mountpoint: /:local 15 | canmount: on:local 16 | creation_time: 2018-12-10T12:20:44+00:00 17 | - name: ROOT/ubuntu_5678 18 | zsys_bootfs: yes 19 | last_used: 2019-12-31T07:36:17+00:00 20 | mountpoint: / 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: bpool 23 | datasets: 24 | - name: BOOT 25 | canmount: off 26 | - name: BOOT/ubuntu_1234 27 | mountpoint: /boot 28 | canmount: noauto 29 | snapshots: 30 | - name: snap1 31 | mountpoint: /boot:local 32 | canmount: on:local 33 | creation_time: 2018-12-10T12:20:44+00:00 34 | - name: BOOT/ubuntu_5678 35 | mountpoint: /boot 36 | origin: bpool/BOOT/ubuntu_1234@snap1 37 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_separate_boot_with_children_manually_created.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: ROOT/ubuntu_5678 17 | zsys_bootfs: yes 18 | last_used: 2019-12-31T07:36:17+00:00 19 | mountpoint: / 20 | canmount: noauto 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: bpool 23 | datasets: 24 | - name: BOOT 25 | canmount: off 26 | - name: BOOT/ubuntu_1234 27 | mountpoint: /boot 28 | snapshots: 29 | - name: snap1 30 | mountpoint: /boot:local 31 | canmount: on:local 32 | creation_time: 2018-12-10T12:20:44+00:00 33 | - name: BOOT/ubuntu_5678 34 | mountpoint: /boot 35 | origin: "bpool/BOOT/ubuntu_1234@snap1" 36 | - name: BOOT/ubuntu_5678/grub 37 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/one_machine_with_unordered_children.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool": { 4 | "IsZsys": true, 5 | "ID": "rpool", 6 | "LastUsed": "2020-09-13T14:26:39+02:00", 7 | "Datasets": { 8 | "rpool": [ 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1599999999 15 | }, 16 | { 17 | "Name": "rpool/opt", 18 | "Mountpoint": "/opt", 19 | "CanMount": "on", 20 | "BootFS": true, 21 | "LastUsed": 1599999999 22 | } 23 | ] 24 | } 25 | } 26 | }, 27 | "AllSystemDatasets": [ 28 | { 29 | "Name": "rpool", 30 | "Mountpoint": "/", 31 | "CanMount": "on", 32 | "BootFS": true, 33 | "LastUsed": 1599999999 34 | }, 35 | { 36 | "Name": "rpool/opt", 37 | "Mountpoint": "/opt", 38 | "CanMount": "on", 39 | "BootFS": true, 40 | "LastUsed": 1599999999 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_and_multiple_snapshots.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: system_root_snapshot 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | creation_time: 2019-12-31T07:36:17+00:00 15 | - name: ROOT/ubuntu_1234/tools 16 | snapshots: 17 | - name: system_child_snapshot 18 | creation_time: 2019-12-31T07:36:17+00:00 19 | - name: USERDATA 20 | canmount: off 21 | - name: USERDATA/user1_abcd 22 | mountpoint: /home/user1 23 | last_used: 2018-12-10T12:20:44+00:00 24 | bootfs_datasets: rpool/ROOT/ubuntu_1234 25 | snapshots: 26 | - name: user_root_snapshot 27 | creation_time: 2019-12-31T07:36:17+00:00 28 | - name: USERDATA/user1_abcd/tools 29 | snapshots: 30 | - name: user_child_snapshot 31 | creation_time: 2019-12-31T07:36:17+00:00 32 | - name: USERDATA/root_bcde 33 | mountpoint: /root 34 | last_used: 2018-08-03T21:55:33+00:00 35 | bootfs_datasets: rpool/ROOT/ubuntu_1234 36 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/one_machine_with_children_last_used_from_root_is_used.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool": { 4 | "IsZsys": true, 5 | "ID": "rpool", 6 | "LastUsed": "2020-09-13T14:26:39+02:00", 7 | "Datasets": { 8 | "rpool": [ 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1599999999 15 | }, 16 | { 17 | "Name": "rpool/opt", 18 | "Mountpoint": "/opt", 19 | "CanMount": "on", 20 | "BootFS": true, 21 | "LastUsed": 1555555555 22 | } 23 | ] 24 | } 25 | } 26 | }, 27 | "AllSystemDatasets": [ 28 | { 29 | "Name": "rpool", 30 | "Mountpoint": "/", 31 | "CanMount": "on", 32 | "BootFS": true, 33 | "LastUsed": 1599999999 34 | }, 35 | { 36 | "Name": "rpool/opt", 37 | "Mountpoint": "/opt", 38 | "CanMount": "on", 39 | "BootFS": true, 40 | "LastUsed": 1555555555 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /internal/config/const.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import "time" 4 | 5 | const ( 6 | // ModifiedBoot is the message to print when the current boot has been modified 7 | ModifiedBoot = "zsys-meta:modified-boot" 8 | // NoModifiedBoot is the message to print when the current boot has no dataset modifications 9 | NoModifiedBoot = "zsys-meta:no-modified-boot" 10 | 11 | // defaultSocket path. 12 | defaultSocket = "/run/zsysd.sock" 13 | // socketEnv overrides default socket via environment variable 14 | socketEnv = "ZSYSD_SOCKET" 15 | 16 | // DefaultClientWaitOnServiceReady for client on waiting on service to start 17 | DefaultClientWaitOnServiceReady = time.Minute 18 | // DefaultClientTimeout for client requests between 2 pings 19 | DefaultClientTimeout = 30 * time.Second 20 | 21 | // DefaultServerIdleTimeout is the default time without a request before the server exits 22 | DefaultServerIdleTimeout = time.Minute 23 | 24 | // DefaultPath is the default configuration path 25 | DefaultPath = "/etc/zsys.conf" 26 | 27 | // UserConfirmationNeeded is a dedicated type for GRPC error which signal that we need more info from user 28 | UserConfirmationNeeded = "UserConfirmationNeeded" 29 | ) 30 | 31 | var ( 32 | // Version is the version of the executable 33 | Version = "dev" 34 | ) 35 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_children_to_promote.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | last_booted_kernel: vmlinuz-5.2.0-8-generic 10 | mountpoint: / 11 | canmount: noauto 12 | snapshots: 13 | - name: snap1 14 | zsys_bootfs: yes:local 15 | last_booted_kernel: vmlinuz-5.0.0-0-generic:local 16 | mountpoint: /:local 17 | canmount: on:local 18 | creation_time: 2018-12-10T12:20:44+00:00 19 | - name: ROOT/ubuntu_1234/opt 20 | canmount: noauto 21 | snapshots: 22 | - name: snap1 23 | zsys_bootfs: yes:inherited 24 | last_booted_kernel: vmlinuz-5.0.0-0-generic:inherited 25 | mountpoint: /opt:inherited 26 | canmount: on:local 27 | creation_time: 2018-12-10T12:20:44+00:00 28 | - name: ROOT/ubuntu_5678 29 | zsys_bootfs: yes 30 | mountpoint: / 31 | origin: rpool/ROOT/ubuntu_1234@snap1 32 | - name: ROOT/ubuntu_5678/opt 33 | mountpoint: /opt 34 | origin: rpool/ROOT/ubuntu_1234/opt@snap1 35 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_separate_boot_with_children_manually_created_to_promote.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | canmount: noauto 11 | snapshots: 12 | - name: snap1 13 | zsys_bootfs: yes:local 14 | mountpoint: /:local 15 | canmount: on:local 16 | creation_time: 2018-12-10T12:20:44+00:00 17 | - name: ROOT/ubuntu_5678 18 | zsys_bootfs: yes 19 | last_used: 2019-12-31T07:36:17+00:00 20 | mountpoint: / 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: bpool 23 | datasets: 24 | - name: BOOT 25 | canmount: off 26 | - name: BOOT/ubuntu_1234 27 | mountpoint: /boot 28 | canmount: noauto 29 | snapshots: 30 | - name: snap1 31 | mountpoint: /boot:local 32 | canmount: on:local 33 | creation_time: 2018-12-10T12:20:44+00:00 34 | - name: BOOT/ubuntu_5678 35 | mountpoint: /boot 36 | origin: "bpool/BOOT/ubuntu_1234@snap1" 37 | - name: BOOT/ubuntu_5678/grub 38 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_snapshot_with_userdata_with_children.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: USERDATA 17 | canmount: off 18 | - name: USERDATA/user1_abcd 19 | mountpoint: /home/user1 20 | bootfs_datasets: rpool/ROOT/ubuntu_1234 21 | last_used: 2018-12-10T12:20:44+00:00 22 | snapshots: 23 | - name: snap1 24 | mountpoint: /home/user1:local 25 | canmount: on:local 26 | creation_time: 2018-03-28T07:30:22+00:00 27 | - name: USERDATA/user1_abcd/tools 28 | snapshots: 29 | - name: snap1 30 | mountpoint: /home/user1/tools:inherited 31 | canmount: on:local 32 | creation_time: 2018-03-28T07:30:22+00:00 33 | - name: USERDATA/root_bcde 34 | mountpoint: /root 35 | bootfs_datasets: rpool/ROOT/ubuntu_1234 36 | last_used: 2018-08-03T21:55:33+00:00 37 | 38 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/one_machine_with_persistent_disabled.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool/ROOT/ubuntu_1234": { 4 | "IsZsys": true, 5 | "ID": "rpool/ROOT/ubuntu_1234", 6 | "LastUsed": "2019-04-18T04:45:55+02:00", 7 | "Datasets": { 8 | "rpool/ROOT/ubuntu_1234": [ 9 | { 10 | "Name": "rpool/ROOT/ubuntu_1234", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1555555555 15 | } 16 | ] 17 | } 18 | } 19 | }, 20 | "AllSystemDatasets": [ 21 | { 22 | "Name": "rpool/ROOT/ubuntu_1234", 23 | "Mountpoint": "/", 24 | "CanMount": "on", 25 | "BootFS": true, 26 | "LastUsed": 1555555555 27 | } 28 | ], 29 | "UnmanagedDatasets": [ 30 | { 31 | "Name": "rpool", 32 | "Mountpoint": "/", 33 | "CanMount": "off" 34 | }, 35 | { 36 | "Name": "rpool/ROOT", 37 | "Mountpoint": "/ROOT", 38 | "CanMount": "off" 39 | }, 40 | { 41 | "Name": "rpool/opt", 42 | "Mountpoint": "/opt", 43 | "CanMount": "noauto" 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/user_dataset_attached_to_nothing_but_ignored_with_canmount_off.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool/ROOT/ubuntu_1234": { 4 | "IsZsys": true, 5 | "ID": "rpool/ROOT/ubuntu_1234", 6 | "LastUsed": "2019-04-18T04:45:55+02:00", 7 | "Datasets": { 8 | "rpool/ROOT/ubuntu_1234": [ 9 | { 10 | "Name": "rpool/ROOT/ubuntu_1234", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1555555555 15 | } 16 | ] 17 | } 18 | } 19 | }, 20 | "AllSystemDatasets": [ 21 | { 22 | "Name": "rpool/ROOT/ubuntu_1234", 23 | "Mountpoint": "/", 24 | "CanMount": "on", 25 | "BootFS": true, 26 | "LastUsed": 1555555555 27 | } 28 | ], 29 | "UnmanagedDatasets": [ 30 | { 31 | "Name": "rpool", 32 | "Mountpoint": "/", 33 | "CanMount": "off" 34 | }, 35 | { 36 | "Name": "rpool/ROOT", 37 | "Mountpoint": "/ROOT", 38 | "CanMount": "off" 39 | }, 40 | { 41 | "Name": "rpool/USERDATA", 42 | "Mountpoint": "/USERDATA", 43 | "CanMount": "off" 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_children.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | last_booted_kernel: vmlinuz-5.2.0-8-generic 10 | mountpoint: / 11 | snapshots: 12 | - name: snap1 13 | zsys_bootfs: yes:local 14 | last_booted_kernel: vmlinuz-5.0.0-0-generic:local 15 | mountpoint: /:local 16 | canmount: on:local 17 | creation_time: 2018-12-10T12:20:44+00:00 18 | - name: ROOT/ubuntu_1234/opt 19 | snapshots: 20 | - name: snap1 21 | zsys_bootfs: yes:inherited 22 | last_booted_kernel: vmlinuz-5.0.0-0-generic:inherited 23 | mountpoint: /opt:inherited 24 | canmount: on:local 25 | creation_time: 2018-12-10T12:20:44+00:00 26 | - name: ROOT/ubuntu_5678 27 | zsys_bootfs: yes 28 | last_used: 2019-12-31T07:36:17+00:00 29 | last_booted_kernel: vmlinuz-5.1.1-1-generic 30 | mountpoint: / 31 | canmount: noauto 32 | origin: rpool/ROOT/ubuntu_1234@snap1 33 | - name: ROOT/ubuntu_5678/opt 34 | canmount: noauto 35 | origin: rpool/ROOT/ubuntu_1234/opt@snap1 36 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/two_machines_one_zsys_one_non_zsys.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool": { 4 | "IsZsys": true, 5 | "ID": "rpool", 6 | "LastUsed": "2020-09-13T14:26:39+02:00", 7 | "Datasets": { 8 | "rpool": [ 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1599999999 15 | } 16 | ] 17 | } 18 | }, 19 | "rpool2": { 20 | "ID": "rpool2", 21 | "LastUsed": "2020-05-08T00:01:28+02:00", 22 | "Datasets": { 23 | "rpool2": [ 24 | { 25 | "Name": "rpool2", 26 | "Mountpoint": "/", 27 | "CanMount": "on", 28 | "LastUsed": 1588888888 29 | } 30 | ] 31 | } 32 | } 33 | }, 34 | "AllSystemDatasets": [ 35 | { 36 | "Name": "rpool", 37 | "Mountpoint": "/", 38 | "CanMount": "on", 39 | "BootFS": true, 40 | "LastUsed": 1599999999 41 | }, 42 | { 43 | "Name": "rpool2", 44 | "Mountpoint": "/", 45 | "CanMount": "on", 46 | "LastUsed": 1588888888 47 | } 48 | ] 49 | } -------------------------------------------------------------------------------- /cmd/zsysd/client/zsysctl.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/ubuntu/zsys/cmd/zsysd/cmdhandler" 6 | "github.com/ubuntu/zsys/internal/config" 7 | "github.com/ubuntu/zsys/internal/i18n" 8 | ) 9 | 10 | var ( 11 | cmdErr error 12 | flagVerbosity int 13 | rootCmd = &cobra.Command{ 14 | Use: "zsysctl COMMAND", 15 | Short: i18n.G("ZFS SYStem integration control zsys daemon"), 16 | Long: i18n.G(`Zfs SYStem tool for an enhanced ZFS on Linux experience. 17 | It allows running multiple ZFS system in parallels on the same machine, 18 | get automated snapshots, managing complex zfs dataset layouts separating 19 | user data from system and persistent data, and more.`), 20 | PersistentPreRun: func(cmd *cobra.Command, args []string) { 21 | config.SetVerboseMode(flagVerbosity) 22 | }, 23 | Args: cmdhandler.SubcommandsRequiredWithSuggestions, 24 | Run: cmdhandler.NoCmd, 25 | // We display usage error ourselves 26 | SilenceErrors: true, 27 | } 28 | ) 29 | 30 | func init() { 31 | rootCmd.PersistentFlags().CountVarP(&flagVerbosity, "verbose", "v", i18n.G("issue INFO (-v) and DEBUG (-vv) output")) 32 | } 33 | 34 | // Cmd returns the zsysctl command and options 35 | func Cmd() *cobra.Command { 36 | return rootCmd 37 | } 38 | 39 | // Error returns the zsysctl command error 40 | func Error() error { 41 | return cmdErr 42 | } 43 | -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_children_n_snapshots_with_unset_user_properties.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: no 8 | last_used: 2019-04-18T02:45:55+00:00 9 | last_booted_kernel: vmlinuz-5.2.0-8-generic 10 | bootfs_datasets: something 11 | mountpoint: / 12 | snapshots: 13 | - name: snap_r1 14 | zsys_bootfs: yes:local 15 | mountpoint: /:local 16 | canmount: on:local 17 | last_booted_kernel: vmlinuz-5.0.0-0-generic:local 18 | - name: ROOT/ubuntu/inherit 19 | snapshots: 20 | - name: snap_r1 21 | zsys_bootfs: yes:inherited 22 | mountpoint: /inherit:inherited 23 | canmount: on:default 24 | last_booted_kernel: vmlinuz-5.0.0-0-generic:inherited 25 | - name: ROOT/ubuntu/overriden 26 | zsys_bootfs: yes 27 | last_used: 2018-12-10T12:20:44+00:00 28 | last_booted_kernel: vmlinuz-4.0.0-0-generic 29 | bootfs_datasets: something else on dataset 30 | snapshots: 31 | - name: snap_r1 32 | zsys_bootfs: yes:local 33 | mountpoint: /overriden:inherited 34 | canmount: on:default 35 | last_booted_kernel: vmlinuz-4.0.0-0-generic:local 36 | -------------------------------------------------------------------------------- /internal/zfs/testdata/m_with_userdata_linked_and_unlinked_and_snapshot.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | - name: USERDATA 11 | canmount: off 12 | - name: USERDATA/user1_abcd 13 | mountpoint: /home/user1 14 | last_used: 2018-12-10T12:20:44+00:00 15 | bootfs_datasets: rpool/ROOT/ubuntu_1234 16 | snapshots: 17 | - name: snapshot 18 | mountpoint: /home/user1:local 19 | - name: USERDATA/user1_abcd/tools 20 | mountpoint: /home/user1/tools 21 | last_used: 2018-12-10T12:20:44+00:00 22 | snapshots: 23 | - name: snapshot 24 | mountpoint: /home/user1/tools:inherited 25 | - name: USERDATA/user1_unlinked 26 | mountpoint: /home/user1 27 | last_used: 2018-12-10T12:20:44+00:00 28 | bootfs_datasets: "-" 29 | - name: USERDATA/user1_manual 30 | mountpoint: /home/user1 31 | last_used: 2018-12-10T12:20:44+00:00 32 | - name: USERDATA/user1_manual/tools 33 | mountpoint: /home/user1/tools 34 | last_used: 2018-12-10T12:20:44+00:00 35 | - name: user1_other 36 | mountpoint: /home/user1 37 | last_used: 2018-12-10T12:20:44+00:00 38 | bootfs_datasets: rpool/ROOT/ubuntu_1234 39 | 40 | -------------------------------------------------------------------------------- /internal/daemon/timeout.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/ubuntu/zsys/internal/i18n" 8 | "github.com/ubuntu/zsys/internal/log" 9 | ) 10 | 11 | type idler struct { 12 | timeout time.Duration 13 | 14 | requestsInFlights int 15 | newRequest chan struct{} 16 | reset chan struct{} 17 | } 18 | 19 | func newIdler(timeout time.Duration) idler { 20 | return idler{ 21 | timeout: timeout, 22 | 23 | newRequest: make(chan struct{}), 24 | reset: make(chan struct{}), 25 | } 26 | } 27 | 28 | func (i idler) addRequest() { 29 | i.newRequest <- struct{}{} 30 | } 31 | 32 | func (i idler) endRequest() { 33 | i.reset <- struct{}{} 34 | } 35 | 36 | func (i idler) start(s *Server) { 37 | defer s.Stop() 38 | t := time.NewTimer(i.timeout) 39 | 40 | for { 41 | select { 42 | case <-t.C: 43 | log.Debug(context.Background(), i18n.G("Idle timeout expired")) 44 | return 45 | case <-i.newRequest: 46 | i.requestsInFlights++ 47 | // Stop can return false if the timeout has fired OR if it's already stopped. Use requestsInFlights 48 | // to only drain the timeout channel if the timeout has already fired. 49 | if i.requestsInFlights == 1 && !t.Stop() { 50 | <-t.C 51 | } 52 | case <-i.reset: 53 | i.requestsInFlights-- 54 | if i.requestsInFlights > 0 { 55 | continue 56 | } 57 | t.Reset(i.timeout) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/boot_dataset_attached_to_nothing_but_ignored_with_canmount_off.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool/ROOT/ubuntu_1234": { 4 | "IsZsys": true, 5 | "ID": "rpool/ROOT/ubuntu_1234", 6 | "LastUsed": "2019-04-18T04:45:55+02:00", 7 | "Datasets": { 8 | "rpool/ROOT/ubuntu_1234": [ 9 | { 10 | "Name": "rpool/ROOT/ubuntu_1234", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1555555555 15 | } 16 | ] 17 | } 18 | } 19 | }, 20 | "AllSystemDatasets": [ 21 | { 22 | "Name": "rpool/ROOT/ubuntu_1234", 23 | "Mountpoint": "/", 24 | "CanMount": "on", 25 | "BootFS": true, 26 | "LastUsed": 1555555555 27 | } 28 | ], 29 | "UnmanagedDatasets": [ 30 | { 31 | "Name": "bpool", 32 | "Mountpoint": "/", 33 | "CanMount": "off" 34 | }, 35 | { 36 | "Name": "bpool/BOOT", 37 | "Mountpoint": "/BOOT", 38 | "CanMount": "off" 39 | }, 40 | { 41 | "Name": "rpool", 42 | "Mountpoint": "/", 43 | "CanMount": "off" 44 | }, 45 | { 46 | "Name": "rpool/ROOT", 47 | "Mountpoint": "/ROOT", 48 | "CanMount": "off" 49 | } 50 | ] 51 | } -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/select_existing_dataset_machine.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool": { 4 | "IsZsys": true, 5 | "ID": "rpool", 6 | "LastUsed": "2020-09-13T14:26:39+02:00", 7 | "Datasets": { 8 | "rpool": [ 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1599999999, 15 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 16 | } 17 | ] 18 | } 19 | } 20 | }, 21 | "Cmdline": "aaaaa bbbbb root=ZFS=rpool ccccc", 22 | "Current": { 23 | "IsZsys": true, 24 | "ID": "rpool", 25 | "LastUsed": "2020-09-13T14:26:39+02:00", 26 | "Datasets": { 27 | "rpool": [ 28 | { 29 | "Name": "rpool", 30 | "Mountpoint": "/", 31 | "CanMount": "on", 32 | "BootFS": true, 33 | "LastUsed": 1599999999, 34 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 35 | } 36 | ] 37 | } 38 | }, 39 | "AllSystemDatasets": [ 40 | { 41 | "Name": "rpool", 42 | "Mountpoint": "/", 43 | "CanMount": "on", 44 | "BootFS": true, 45 | "LastUsed": 1599999999, 46 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 47 | } 48 | ] 49 | } -------------------------------------------------------------------------------- /cmd/zsysd/client/version.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/ubuntu/zsys" 9 | "github.com/ubuntu/zsys/internal/config" 10 | "github.com/ubuntu/zsys/internal/i18n" 11 | "github.com/ubuntu/zsys/internal/streamlogger" 12 | ) 13 | 14 | var ( 15 | versionCmd = &cobra.Command{ 16 | Use: "version", 17 | Short: i18n.G("Returns version of client and server"), 18 | Args: cobra.NoArgs, 19 | Run: func(cmd *cobra.Command, args []string) { cmdErr = getVersion() }, 20 | } 21 | ) 22 | 23 | func init() { 24 | rootCmd.AddCommand(versionCmd) 25 | } 26 | 27 | // getVersion returns the current server and client versions. 28 | func getVersion() (err error) { 29 | fmt.Printf(i18n.G("zsysctl\t%s")+"\n", config.Version) 30 | 31 | client, err := newClient() 32 | if err != nil { 33 | return err 34 | } 35 | defer client.Close() 36 | 37 | ctx, cancel, reset := contextWithResettableTimeout(client.Ctx, config.DefaultClientTimeout) 38 | defer cancel() 39 | 40 | stream, err := client.Version(ctx, &zsys.Empty{}) 41 | if err = checkConn(err, reset); err != nil { 42 | return err 43 | } 44 | 45 | for { 46 | r, err := stream.Recv() 47 | if err == streamlogger.ErrLogMsg { 48 | reset <- struct{}{} 49 | continue 50 | } 51 | if err == io.EOF { 52 | break 53 | } 54 | if err != nil { 55 | return err 56 | } 57 | fmt.Printf(i18n.G("zsysd\t%s")+"\n", r.GetVersion()) 58 | } 59 | 60 | return nil 61 | } 62 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testclone/simple_clone_ignore_canmount_set_to_noauto_(default).golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ROOT", 13 | "Mountpoint": "/ROOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | }, 20 | { 21 | "Name": "rpool/ROOT/ubuntu", 22 | "Mountpoint": "/", 23 | "CanMount": "on", 24 | "BootFS": true, 25 | "LastUsed": 1555555555, 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "CanMount": "local", 29 | "BootFS": "local", 30 | "LastUsed": "local" 31 | } 32 | }, 33 | { 34 | "Name": "rpool/ROOT/ubuntu@snap1", 35 | "IsSnapshot": true, 36 | "Mountpoint": "/", 37 | "CanMount": "noauto", 38 | "BootFS": true, 39 | "LastUsed": 2000000000, 40 | "Sources": { 41 | "Mountpoint": "local", 42 | "BootFS": "local" 43 | } 44 | }, 45 | { 46 | "Name": "rpool/ROOT/ubuntu_5678", 47 | "Mountpoint": "/", 48 | "CanMount": "on", 49 | "BootFS": true, 50 | "Origin": "rpool/ROOT/ubuntu@snap1", 51 | "Sources": { 52 | "Mountpoint": "local", 53 | "BootFS": "local" 54 | } 55 | } 56 | ] -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ubuntu/zsys 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/bicomsystems/go-libzfs v0.3.3 7 | github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf 8 | github.com/godbus/dbus/v5 v5.1.0 9 | github.com/google/go-cmp v0.6.0 10 | github.com/k0kubun/pp v3.0.1+incompatible 11 | github.com/sirupsen/logrus v1.9.3 12 | github.com/snapcore/go-gettext v0.0.0-20230721153050-9082cdc2db05 13 | github.com/spf13/cobra v1.8.0 14 | github.com/spf13/pflag v1.0.5 15 | github.com/stretchr/testify v1.8.4 16 | golang.org/x/sys v0.15.0 17 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 18 | google.golang.org/grpc v1.60.1 19 | google.golang.org/protobuf v1.32.0 20 | gopkg.in/yaml.v3 v3.0.1 21 | ) 22 | 23 | require ( 24 | github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect 25 | github.com/davecgh/go-spew v1.1.1 // indirect 26 | github.com/golang/protobuf v1.5.3 // indirect 27 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 28 | github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect 29 | github.com/mattn/go-colorable v0.1.2 // indirect 30 | github.com/mattn/go-isatty v0.0.8 // indirect 31 | github.com/pmezard/go-difflib v1.0.0 // indirect 32 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 33 | golang.org/x/net v0.19.0 // indirect 34 | golang.org/x/text v0.14.0 // indirect 35 | ) 36 | 37 | replace github.com/bicomsystems/go-libzfs => github.com/ubuntu/go-libzfs v0.2.2-0.20230711233110-6b487f8211c2 38 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/one_machine_with_children.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool": { 4 | "IsZsys": true, 5 | "ID": "rpool", 6 | "LastUsed": "2020-09-13T14:26:39+02:00", 7 | "Datasets": { 8 | "rpool": [ 9 | { 10 | "Name": "rpool", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1599999999, 15 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 16 | }, 17 | { 18 | "Name": "rpool/opt", 19 | "Mountpoint": "/opt", 20 | "CanMount": "on", 21 | "BootFS": true, 22 | "LastUsed": 1599999999, 23 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 24 | } 25 | ] 26 | } 27 | } 28 | }, 29 | "AllSystemDatasets": [ 30 | { 31 | "Name": "rpool", 32 | "Mountpoint": "/", 33 | "CanMount": "on", 34 | "BootFS": true, 35 | "LastUsed": 1599999999, 36 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 37 | }, 38 | { 39 | "Name": "rpool/opt", 40 | "Mountpoint": "/opt", 41 | "CanMount": "on", 42 | "BootFS": true, 43 | "LastUsed": 1599999999, 44 | "LastBootedKernel": "vmlinuz-5.2.0-8-generic" 45 | } 46 | ] 47 | } -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_separate_boot_with_children.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: ROOT/ubuntu_5678 17 | zsys_bootfs: yes 18 | last_used: 2019-12-31T07:36:17+00:00 19 | mountpoint: / 20 | canmount: noauto 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: bpool 23 | datasets: 24 | - name: BOOT 25 | canmount: off 26 | - name: BOOT/ubuntu_1234 27 | mountpoint: /boot 28 | snapshots: 29 | - name: snap1 30 | mountpoint: /boot:local 31 | canmount: on:local 32 | creation_time: 2018-12-10T12:20:44+00:00 33 | - name: BOOT/ubuntu_1234/grub 34 | snapshots: 35 | - name: snap1 36 | mountpoint: /boot/grub:inherited 37 | canmount: on:local 38 | creation_time: 2018-12-10T12:20:44+00:00 39 | - name: BOOT/ubuntu_5678 40 | mountpoint: /boot 41 | origin: bpool/BOOT/ubuntu_1234@snap1 42 | - name: BOOT/ubuntu_5678/grub 43 | origin: bpool/BOOT/ubuntu_1234/grub@snap1 44 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testclone/simple_clone_keeps_canmount_off_as_off.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ROOT", 13 | "Mountpoint": "/ROOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | }, 20 | { 21 | "Name": "rpool/ROOT/ubuntu", 22 | "Mountpoint": "/", 23 | "CanMount": "on", 24 | "BootFS": true, 25 | "LastUsed": 1555555555, 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "CanMount": "local", 29 | "BootFS": "local", 30 | "LastUsed": "local" 31 | } 32 | }, 33 | { 34 | "Name": "rpool/ROOT/ubuntu@snap1", 35 | "IsSnapshot": true, 36 | "Mountpoint": "/", 37 | "CanMount": "off", 38 | "BootFS": true, 39 | "LastUsed": 2000000000, 40 | "Sources": { 41 | "Mountpoint": "local", 42 | "CanMount": "local", 43 | "BootFS": "local" 44 | } 45 | }, 46 | { 47 | "Name": "rpool/ROOT/ubuntu_5678", 48 | "Mountpoint": "/", 49 | "CanMount": "off", 50 | "BootFS": true, 51 | "Origin": "rpool/ROOT/ubuntu@snap1", 52 | "Sources": { 53 | "Mountpoint": "local", 54 | "CanMount": "local", 55 | "BootFS": "local" 56 | } 57 | } 58 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/user_dataset_attached_to_nothing.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool/ROOT/ubuntu_1234": { 4 | "IsZsys": true, 5 | "ID": "rpool/ROOT/ubuntu_1234", 6 | "LastUsed": "2019-04-18T04:45:55+02:00", 7 | "Datasets": { 8 | "rpool/ROOT/ubuntu_1234": [ 9 | { 10 | "Name": "rpool/ROOT/ubuntu_1234", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1555555555 15 | } 16 | ] 17 | } 18 | } 19 | }, 20 | "AllSystemDatasets": [ 21 | { 22 | "Name": "rpool/ROOT/ubuntu_1234", 23 | "Mountpoint": "/", 24 | "CanMount": "on", 25 | "BootFS": true, 26 | "LastUsed": 1555555555 27 | } 28 | ], 29 | "UnmanagedDatasets": [ 30 | { 31 | "Name": "rpool", 32 | "Mountpoint": "/", 33 | "CanMount": "off" 34 | }, 35 | { 36 | "Name": "rpool/ROOT", 37 | "Mountpoint": "/ROOT", 38 | "CanMount": "off" 39 | }, 40 | { 41 | "Name": "rpool/USERDATA", 42 | "Mountpoint": "/USERDATA", 43 | "CanMount": "off" 44 | }, 45 | { 46 | "Name": "rpool/USERDATA/root_bcde", 47 | "Mountpoint": "/root", 48 | "CanMount": "on", 49 | "LastUsed": 1533333333, 50 | "BootfsDatasets": "rpool/ROOT/ubuntu_none" 51 | } 52 | ] 53 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/testclone/simple_clone_set_canmount_on_to_noauto.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ROOT", 13 | "Mountpoint": "/ROOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | }, 20 | { 21 | "Name": "rpool/ROOT/ubuntu", 22 | "Mountpoint": "/", 23 | "CanMount": "on", 24 | "BootFS": true, 25 | "LastUsed": 1555555555, 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "CanMount": "local", 29 | "BootFS": "local", 30 | "LastUsed": "local" 31 | } 32 | }, 33 | { 34 | "Name": "rpool/ROOT/ubuntu@snap1", 35 | "IsSnapshot": true, 36 | "Mountpoint": "/", 37 | "CanMount": "on", 38 | "BootFS": true, 39 | "LastUsed": 2000000000, 40 | "Sources": { 41 | "Mountpoint": "local", 42 | "CanMount": "local", 43 | "BootFS": "local" 44 | } 45 | }, 46 | { 47 | "Name": "rpool/ROOT/ubuntu_5678", 48 | "Mountpoint": "/", 49 | "CanMount": "noauto", 50 | "BootFS": true, 51 | "Origin": "rpool/ROOT/ubuntu@snap1", 52 | "Sources": { 53 | "Mountpoint": "local", 54 | "CanMount": "local", 55 | "BootFS": "local" 56 | } 57 | } 58 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/one_machine_with_persistent_datasets.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool/ROOT/ubuntu_1234": { 4 | "IsZsys": true, 5 | "ID": "rpool/ROOT/ubuntu_1234", 6 | "LastUsed": "2019-04-18T04:45:55+02:00", 7 | "Datasets": { 8 | "rpool/ROOT/ubuntu_1234": [ 9 | { 10 | "Name": "rpool/ROOT/ubuntu_1234", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1555555555 15 | } 16 | ] 17 | }, 18 | "PersistentDatasets": [ 19 | { 20 | "Name": "rpool/opt", 21 | "Mountpoint": "/opt", 22 | "CanMount": "on" 23 | } 24 | ] 25 | } 26 | }, 27 | "AllSystemDatasets": [ 28 | { 29 | "Name": "rpool/ROOT/ubuntu_1234", 30 | "Mountpoint": "/", 31 | "CanMount": "on", 32 | "BootFS": true, 33 | "LastUsed": 1555555555 34 | } 35 | ], 36 | "AllPersistentDatasets": [ 37 | { 38 | "Name": "rpool/opt", 39 | "Mountpoint": "/opt", 40 | "CanMount": "on" 41 | } 42 | ], 43 | "UnmanagedDatasets": [ 44 | { 45 | "Name": "rpool", 46 | "Mountpoint": "/", 47 | "CanMount": "off" 48 | }, 49 | { 50 | "Name": "rpool/ROOT", 51 | "Mountpoint": "/ROOT", 52 | "CanMount": "off" 53 | } 54 | ] 55 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/one_pool_n_datasets_n_children_n_snapshots_with_dependencies.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap_r1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | - name: ROOT/ubuntu/var 16 | snapshots: 17 | - name: snap_v1 18 | zsys_bootfs: yes:inherited 19 | mountpoint: /var:inherited 20 | canmount: on:local 21 | - name: ROOT/ubuntu/var/lib 22 | zsys_bootfs: no 23 | - name: ROOT/ubuntu/var/lib/apt 24 | - name: ROOT/ubuntu/opt 25 | snapshots: 26 | - name: snap_opt 27 | zsys_bootfs: yes:inherited 28 | mountpoint: /opt:inherited 29 | canmount: on:local 30 | - name: ROOT/ubuntu/opt/tools 31 | snapshots: 32 | - name: snap_opt 33 | zsys_bootfs: yes:inherited 34 | mountpoint: /opt/tools:inherited 35 | canmount: on:local 36 | - name: ROOT/ubuntu2 37 | last_used: 2018-12-10T12:20:44+00:00 38 | mountpoint: / 39 | snapshots: 40 | - name: snap_u1 41 | mountpoint: /:local 42 | canmount: on:local 43 | - name: snap_u2 44 | mountpoint: /:local 45 | canmount: on:local 46 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testclone/simple_clone_keeps_canmount_noauto_as_noauto.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ROOT", 13 | "Mountpoint": "/ROOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | }, 20 | { 21 | "Name": "rpool/ROOT/ubuntu", 22 | "Mountpoint": "/", 23 | "CanMount": "on", 24 | "BootFS": true, 25 | "LastUsed": 1555555555, 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "CanMount": "local", 29 | "BootFS": "local", 30 | "LastUsed": "local" 31 | } 32 | }, 33 | { 34 | "Name": "rpool/ROOT/ubuntu@snap1", 35 | "IsSnapshot": true, 36 | "Mountpoint": "/", 37 | "CanMount": "noauto", 38 | "BootFS": true, 39 | "LastUsed": 2000000000, 40 | "Sources": { 41 | "Mountpoint": "local", 42 | "CanMount": "local", 43 | "BootFS": "local" 44 | } 45 | }, 46 | { 47 | "Name": "rpool/ROOT/ubuntu_5678", 48 | "Mountpoint": "/", 49 | "CanMount": "noauto", 50 | "BootFS": true, 51 | "Origin": "rpool/ROOT/ubuntu@snap1", 52 | "Sources": { 53 | "Mountpoint": "local", 54 | "CanMount": "local", 55 | "BootFS": "local" 56 | } 57 | } 58 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_userdata.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: ROOT/ubuntu_5678 17 | zsys_bootfs: yes 18 | last_used: 2019-12-31T07:36:17+00:00 19 | mountpoint: / 20 | canmount: noauto 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: USERDATA 23 | canmount: off 24 | - name: USERDATA/user1_abcd 25 | mountpoint: /home/user1 26 | bootfs_datasets: rpool/ROOT/ubuntu_1234 27 | last_used: 2018-12-10T12:20:44+00:00 28 | snapshots: 29 | - name: snap1 30 | mountpoint: /home/user1:local 31 | canmount: on:local 32 | creation_time: 2018-03-28T07:30:22+00:00 33 | - name: USERDATA/user1_efgh 34 | mountpoint: /home/user1 35 | canmount: noauto 36 | bootfs_datasets: rpool/ROOT/ubuntu_5678 37 | last_used: 2017-11-19T17:05:11+00:00 38 | origin: rpool/USERDATA/user1_abcd@snap1 39 | - name: USERDATA/root_bcde 40 | mountpoint: /root 41 | bootfs_datasets: rpool/ROOT/ubuntu_1234 42 | last_used: 2018-08-03T21:55:33+00:00 43 | -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/boot_dataset_attached_to_nothing.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool/ROOT/ubuntu_1234": { 4 | "IsZsys": true, 5 | "ID": "rpool/ROOT/ubuntu_1234", 6 | "LastUsed": "2019-04-18T04:45:55+02:00", 7 | "Datasets": { 8 | "rpool/ROOT/ubuntu_1234": [ 9 | { 10 | "Name": "rpool/ROOT/ubuntu_1234", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1555555555 15 | } 16 | ] 17 | } 18 | } 19 | }, 20 | "AllSystemDatasets": [ 21 | { 22 | "Name": "bpool/BOOT/ubuntu_none", 23 | "Mountpoint": "/boot", 24 | "CanMount": "on" 25 | }, 26 | { 27 | "Name": "rpool/ROOT/ubuntu_1234", 28 | "Mountpoint": "/", 29 | "CanMount": "on", 30 | "BootFS": true, 31 | "LastUsed": 1555555555 32 | } 33 | ], 34 | "UnmanagedDatasets": [ 35 | { 36 | "Name": "bpool", 37 | "Mountpoint": "/", 38 | "CanMount": "off" 39 | }, 40 | { 41 | "Name": "bpool/BOOT", 42 | "Mountpoint": "/BOOT", 43 | "CanMount": "off" 44 | }, 45 | { 46 | "Name": "rpool", 47 | "Mountpoint": "/", 48 | "CanMount": "off" 49 | }, 50 | { 51 | "Name": "rpool/ROOT", 52 | "Mountpoint": "/ROOT", 53 | "CanMount": "off" 54 | } 55 | ] 56 | } -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_clone_has_more_users.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: snap1 12 | zsys_bootfs: yes:local 13 | mountpoint: /:local 14 | canmount: on:local 15 | creation_time: 2018-12-10T12:20:44+00:00 16 | - name: ROOT/ubuntu_5678 17 | zsys_bootfs: yes 18 | last_used: 2019-12-31T07:36:17+00:00 19 | mountpoint: / 20 | canmount: noauto 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: USERDATA 23 | canmount: off 24 | - name: USERDATA/user1_abcd 25 | mountpoint: /home/user1 26 | bootfs_datasets: rpool/ROOT/ubuntu_1234 27 | last_used: 2018-12-10T12:20:44+00:00 28 | snapshots: 29 | - name: snap1 30 | mountpoint: /home/user1:local 31 | canmount: on:local 32 | creation_time: 2018-03-28T07:30:22+00:00 33 | - name: USERDATA/user1_efgh 34 | mountpoint: /home/user1 35 | canmount: noauto 36 | bootfs_datasets: rpool/ROOT/ubuntu_5678 37 | last_used: 2017-11-19T17:05:11+00:00 38 | origin: rpool/USERDATA/user1_abcd@snap1 39 | - name: USERDATA/root_bcde 40 | mountpoint: /root 41 | bootfs_datasets: rpool/ROOT/ubuntu_5678 42 | last_used: 2018-08-03T21:55:33+00:00 43 | -------------------------------------------------------------------------------- /internal/zfs/testdata/testclone/simple_clone_on_non_root_local_mountpoint_keeps_mountpoints.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "rpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "rpool/ROOT", 13 | "Mountpoint": "/ROOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | }, 20 | { 21 | "Name": "rpool/ROOT/ubuntu", 22 | "Mountpoint": "/", 23 | "CanMount": "on", 24 | "BootFS": true, 25 | "LastUsed": 1555555555, 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "CanMount": "local", 29 | "BootFS": "local", 30 | "LastUsed": "local" 31 | } 32 | }, 33 | { 34 | "Name": "rpool/ROOT/ubuntu@snap1", 35 | "IsSnapshot": true, 36 | "Mountpoint": "/foo", 37 | "CanMount": "on", 38 | "BootFS": true, 39 | "LastUsed": 2000000000, 40 | "Sources": { 41 | "Mountpoint": "local", 42 | "CanMount": "local", 43 | "BootFS": "local" 44 | } 45 | }, 46 | { 47 | "Name": "rpool/ROOT/ubuntu_5678", 48 | "Mountpoint": "/foo", 49 | "CanMount": "noauto", 50 | "BootFS": true, 51 | "Origin": "rpool/ROOT/ubuntu@snap1", 52 | "Sources": { 53 | "Mountpoint": "local", 54 | "CanMount": "local", 55 | "BootFS": "local" 56 | } 57 | } 58 | ] -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_separate_boot_with_children_to_promote.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | canmount: noauto 11 | snapshots: 12 | - name: snap1 13 | zsys_bootfs: yes:local 14 | mountpoint: /:local 15 | canmount: on:local 16 | creation_time: 2018-12-10T12:20:44+00:00 17 | - name: ROOT/ubuntu_5678 18 | zsys_bootfs: yes 19 | last_used: 2019-12-31T07:36:17+00:00 20 | mountpoint: / 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: bpool 23 | datasets: 24 | - name: BOOT 25 | canmount: off 26 | - name: BOOT/ubuntu_1234 27 | mountpoint: /boot 28 | canmount: noauto 29 | snapshots: 30 | - name: snap1 31 | mountpoint: /boot:local 32 | canmount: on:local 33 | creation_time: 2018-12-10T12:20:44+00:00 34 | - name: BOOT/ubuntu_1234/grub 35 | canmount: noauto 36 | snapshots: 37 | - name: snap1 38 | mountpoint: /boot/grub:inherited 39 | canmount: on:local 40 | creation_time: 2018-12-10T12:20:44+00:00 41 | - name: BOOT/ubuntu_5678 42 | mountpoint: /boot 43 | origin: bpool/BOOT/ubuntu_1234@snap1 44 | - name: BOOT/ubuntu_5678/grub 45 | origin: bpool/BOOT/ubuntu_1234/grub@snap1 46 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_userdata_to_promote_no_user_revert.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | canmount: noauto 11 | snapshots: 12 | - name: snap1 13 | zsys_bootfs: yes:local 14 | mountpoint: /:local 15 | canmount: on:local 16 | creation_time: 2018-12-10T12:20:44+00:00 17 | - name: ROOT/ubuntu_5678 18 | zsys_bootfs: yes 19 | last_used: 2019-12-31T07:36:17+00:00 20 | mountpoint: / 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: USERDATA 23 | canmount: off 24 | - name: USERDATA/user1_abcd 25 | mountpoint: /home/user1 26 | bootfs_datasets: rpool/ROOT/ubuntu_1234 27 | last_used: 2018-12-10T12:20:44+00:00 28 | snapshots: 29 | - name: snap1 30 | mountpoint: /home/user1:local 31 | canmount: on:local 32 | creation_time: 2018-03-28T07:30:22+00:00 33 | - name: USERDATA/user1_efgh 34 | mountpoint: /home/user1 35 | canmount: noauto 36 | bootfs_datasets: rpool/ROOT/ubuntu_5678 37 | last_used: 2017-11-19T17:05:11+00:00 38 | origin: rpool/USERDATA/user1_abcd@snap1 39 | - name: USERDATA/root_bcde 40 | mountpoint: /root 41 | bootfs_datasets: rpool/ROOT/ubuntu_1234 42 | last_used: 2018-08-03T21:55:33+00:00 43 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_clone_with_userdata_to_promote_user_revert.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | canmount: noauto 11 | snapshots: 12 | - name: snap1 13 | zsys_bootfs: yes:local 14 | mountpoint: /:local 15 | canmount: on:local 16 | creation_time: 2018-12-10T12:20:44+00:00 17 | - name: ROOT/ubuntu_5678 18 | zsys_bootfs: yes 19 | last_used: 2019-12-31T07:36:17+00:00 20 | mountpoint: / 21 | origin: rpool/ROOT/ubuntu_1234@snap1 22 | - name: USERDATA 23 | canmount: off 24 | - name: USERDATA/user1_abcd 25 | mountpoint: /home/user1 26 | canmount: noauto 27 | bootfs_datasets: rpool/ROOT/ubuntu_1234 28 | last_used: 2018-12-10T12:20:44+00:00 29 | snapshots: 30 | - name: snap1 31 | mountpoint: /home/user1:local 32 | canmount: on:local 33 | creation_time: 2018-03-28T07:30:22+00:00 34 | - name: USERDATA/user1_efgh 35 | mountpoint: /home/user1 36 | bootfs_datasets: rpool/ROOT/ubuntu_5678 37 | last_used: 2017-11-19T17:05:11+00:00 38 | origin: rpool/USERDATA/user1_abcd@snap1 39 | - name: USERDATA/root_bcde 40 | mountpoint: /root 41 | canmount: noauto 42 | bootfs_datasets: rpool/ROOT/ubuntu_1234 43 | last_used: 2018-08-03T21:55:33+00:00 44 | -------------------------------------------------------------------------------- /internal/machines/testdata/m_with_userdata_snapshot_attached_with_clone.yaml: -------------------------------------------------------------------------------- 1 | pools: 2 | - name: rpool 3 | datasets: 4 | - name: ROOT 5 | canmount: off 6 | - name: ROOT/ubuntu_1234 7 | zsys_bootfs: yes 8 | last_used: 2019-04-18T02:45:55+00:00 9 | mountpoint: / 10 | snapshots: 11 | - name: system-snapshot 12 | mountpoint: /:local 13 | creation_time: 2018-12-10T12:20:44+00:00 14 | - name: USERDATA 15 | canmount: off 16 | - name: USERDATA/user1_abcd 17 | canmount: noauto 18 | mountpoint: /home/user1 19 | last_used: 2018-12-10T12:20:44+00:00 20 | snapshots: 21 | - name: system-snapshot 22 | canmount: noauto:local 23 | mountpoint: /home/user1:local 24 | creation_time: 2018-12-10T12:20:44+00:00 25 | - name: USERDATA/user1_abcd/tools 26 | canmount: noauto 27 | mountpoint: /home/user1/tools 28 | last_used: 2018-12-10T12:20:44+00:00 29 | snapshots: 30 | - name: system-snapshot 31 | canmount: noauto:local 32 | mountpoint: /home/user1/tools:inherited 33 | creation_time: 2018-12-10T12:20:44+00:00 34 | - name: USERDATA/user1_clone1 35 | canmount: noauto 36 | mountpoint: /home/user1 37 | last_used: 2018-12-10T12:20:44+00:00 38 | origin: rpool/USERDATA/user1_abcd@system-snapshot 39 | - name: USERDATA/user1_clone1/tools 40 | canmount: noauto 41 | mountpoint: /home/user1/tools 42 | last_used: 2018-12-10T12:20:44+00:00 43 | origin: rpool/USERDATA/user1_abcd/tools@system-snapshot -------------------------------------------------------------------------------- /internal/machines/testdata/testnew/select_existing_dataset_but_not_a_machine.golden: -------------------------------------------------------------------------------- 1 | { 2 | "All": { 3 | "rpool/ROOT/ubuntu_1234": { 4 | "IsZsys": true, 5 | "ID": "rpool/ROOT/ubuntu_1234", 6 | "LastUsed": "2019-04-18T04:45:55+02:00", 7 | "Datasets": { 8 | "rpool/ROOT/ubuntu_1234": [ 9 | { 10 | "Name": "rpool/ROOT/ubuntu_1234", 11 | "Mountpoint": "/", 12 | "CanMount": "on", 13 | "BootFS": true, 14 | "LastUsed": 1555555555 15 | } 16 | ] 17 | }, 18 | "PersistentDatasets": [ 19 | { 20 | "Name": "rpool/opt", 21 | "Mountpoint": "/opt", 22 | "CanMount": "on" 23 | } 24 | ] 25 | } 26 | }, 27 | "Cmdline": "aaaaa bbbbb root=ZFS=rpool/ROOT ccccc", 28 | "AllSystemDatasets": [ 29 | { 30 | "Name": "rpool/ROOT/ubuntu_1234", 31 | "Mountpoint": "/", 32 | "CanMount": "on", 33 | "BootFS": true, 34 | "LastUsed": 1555555555 35 | } 36 | ], 37 | "AllPersistentDatasets": [ 38 | { 39 | "Name": "rpool/opt", 40 | "Mountpoint": "/opt", 41 | "CanMount": "on" 42 | } 43 | ], 44 | "UnmanagedDatasets": [ 45 | { 46 | "Name": "rpool", 47 | "Mountpoint": "/", 48 | "CanMount": "off" 49 | }, 50 | { 51 | "Name": "rpool/ROOT", 52 | "Mountpoint": "/ROOT", 53 | "CanMount": "off" 54 | } 55 | ] 56 | } -------------------------------------------------------------------------------- /internal/zfs/testdata/testnew/two_pools_n_datasets.golden: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "bpool", 4 | "Mountpoint": "/", 5 | "CanMount": "off", 6 | "Sources": { 7 | "Mountpoint": "local", 8 | "CanMount": "local" 9 | } 10 | }, 11 | { 12 | "Name": "bpool/BOOT", 13 | "Mountpoint": "/BOOT", 14 | "CanMount": "off", 15 | "Sources": { 16 | "Mountpoint": "inherited", 17 | "CanMount": "local" 18 | } 19 | }, 20 | { 21 | "Name": "bpool/BOOT/boot", 22 | "Mountpoint": "/boot", 23 | "CanMount": "on", 24 | "BootFS": true, 25 | "LastUsed": 1555555555, 26 | "Sources": { 27 | "Mountpoint": "local", 28 | "CanMount": "local", 29 | "BootFS": "local", 30 | "LastUsed": "local" 31 | } 32 | }, 33 | { 34 | "Name": "rpool", 35 | "Mountpoint": "/", 36 | "CanMount": "off", 37 | "Sources": { 38 | "Mountpoint": "local", 39 | "CanMount": "local" 40 | } 41 | }, 42 | { 43 | "Name": "rpool/ROOT", 44 | "Mountpoint": "/ROOT", 45 | "CanMount": "off", 46 | "Sources": { 47 | "Mountpoint": "inherited", 48 | "CanMount": "local" 49 | } 50 | }, 51 | { 52 | "Name": "rpool/ROOT/ubuntu", 53 | "Mountpoint": "/", 54 | "CanMount": "on", 55 | "BootFS": true, 56 | "LastUsed": 1555555555, 57 | "Sources": { 58 | "Mountpoint": "local", 59 | "CanMount": "local", 60 | "BootFS": "local", 61 | "LastUsed": "local" 62 | } 63 | } 64 | ] --------------------------------------------------------------------------------