blob: e2933102a4e28657b29c0a720fafdd229d639b35 [file] [log] [blame]
Amin Hassania69f32e2020-03-30 15:20:42 -07001// Copyright 2020 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef DLCSERVICE_DLC_H_
6#define DLCSERVICE_DLC_H_
7
Amin Hassani86649982020-03-31 16:03:37 -07008#include <map>
Amin Hassani40c0f112020-04-15 09:55:00 -07009#include <memory>
Amin Hassani86649982020-03-31 16:03:37 -070010#include <set>
Amin Hassania69f32e2020-03-30 15:20:42 -070011#include <string>
Andrewf67a7812020-05-07 10:48:00 -070012#include <utility>
Jae Hoon Kim9a27d152020-04-10 12:50:14 -070013#include <vector>
Amin Hassania69f32e2020-03-30 15:20:42 -070014
15#include <base/files/file_path.h>
Amin Hassani86649982020-03-31 16:03:37 -070016#include <brillo/errors/error.h>
Amin Hassania69f32e2020-03-30 15:20:42 -070017#include <dbus/dlcservice/dbus-constants.h>
18#include <dlcservice/proto_bindings/dlcservice.pb.h>
Amin Hassaniaa38c792020-04-06 15:52:44 -070019#include <gtest/gtest_prod.h> // for FRIEND_TEST
Amin Hassania69f32e2020-03-30 15:20:42 -070020#include <libimageloader/manifest.h>
21#include <chromeos/dbus/service_constants.h>
22
Amin Hassani86649982020-03-31 16:03:37 -070023#include "dlcservice/boot/boot_slot.h"
Amin Hassani40c0f112020-04-15 09:55:00 -070024#include "dlcservice/ref_count.h"
Amin Hassania69f32e2020-03-30 15:20:42 -070025
Amin Hassania69f32e2020-03-30 15:20:42 -070026namespace dlcservice {
27
Amin Hassani86649982020-03-31 16:03:37 -070028// |DlcId| is the ID of the DLC.
29using DlcId = std::string;
30
Amin Hassania69f32e2020-03-30 15:20:42 -070031class DlcBase {
32 public:
Vyshu Khota32388f92020-11-10 09:13:29 -080033 explicit DlcBase(DlcId id) : id_(std::move(id)) {}
Amin Hassania69f32e2020-03-30 15:20:42 -070034 virtual ~DlcBase() = default;
35
Jae Hoon Kim0c2b6cd2020-04-30 13:23:16 -070036 // Returns the list of directories related to a DLC for deletion.
37 static std::vector<base::FilePath> GetPathsToDelete(const DlcId& id);
38
Amin Hassania69f32e2020-03-30 15:20:42 -070039 // Initializes the DLC. This should be called right after creating the DLC
40 // object.
41 bool Initialize();
42
Jae Hoon Kime567b9e2020-04-08 14:43:59 -070043 // Returns the ID of the DLC.
Amin Hassani4ca7e1c2020-04-29 13:01:33 -070044 const DlcId& GetId() const;
Jae Hoon Kime567b9e2020-04-08 14:43:59 -070045
Amin Hassanid5fc8b22020-04-29 12:44:52 -070046 // Returns the human readable name of the DLC.
47 const std::string& GetName() const;
48
49 // Returns the description of the DLC.
50 const std::string& GetDescription() const;
51
Amin Hassania69f32e2020-03-30 15:20:42 -070052 // Returns the current state of the DLC.
53 DlcState GetState() const;
54
55 // Returns the root directory inside a mounted DLC module.
56 base::FilePath GetRoot() const;
57
58 // Returns true if the DLC is currently being installed.
59 bool IsInstalling() const;
60
61 // Returns true if the DLC is already installed and mounted.
62 bool IsInstalled() const;
63
Amin Hassanif27aac02020-04-23 21:56:26 -070064 // Returns true if the DLC is marked verified.
65 bool IsVerified() const;
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -070066
Amin Hassanid5fc8b22020-04-29 12:44:52 -070067 // Returns true if the DLC has any content on disk that is taking space. This
68 // means mainly if it has images on disk.
69 bool HasContent() const;
70
71 // Returns the amount of disk space this DLC is using right now.
72 uint64_t GetUsedBytesOnDisk() const;
73
Jae Hoon Kim0d4ff622020-05-14 14:47:40 -070074 // Returns true if the DLC has a boolean true for 'preload-allowed'
Amin Hassania69f32e2020-03-30 15:20:42 -070075 // attribute in the manifest for the given |id| and |package|.
76 bool IsPreloadAllowed() const;
77
Amin Hassani9a3f20c2020-05-25 16:38:33 -070078 // Creates the DLC image based on the fields from the manifest if the DLC is
79 // not installed. If the DLC image exists or is installed already, some
80 // verifications are passed to validate that the DLC is mounted.
Amin Hassania69f32e2020-03-30 15:20:42 -070081 // Initializes the installation like creating the necessary files, etc.
Amin Hassani9a3f20c2020-05-25 16:38:33 -070082 bool Install(brillo::ErrorPtr* err);
Amin Hassania69f32e2020-03-30 15:20:42 -070083
84 // This is called after the update_engine finishes the installation of a
85 // DLC. This marks the DLC as installed and mounts the DLC image.
Andrew0a534ed2020-05-06 09:59:17 -070086 bool FinishInstall(bool installed_by_ue, brillo::ErrorPtr* err);
Amin Hassania69f32e2020-03-30 15:20:42 -070087
88 // Cancels the ongoing installation of this DLC. The state will be set to
89 // uninstalled after this call if successful.
Andrewbcc4bd82020-06-11 14:23:55 -070090 // The |err_in| argument is the error that causes the install to be cancelled.
91 bool CancelInstall(const brillo::ErrorPtr& err_in, brillo::ErrorPtr* err);
Amin Hassania69f32e2020-03-30 15:20:42 -070092
Amin Hassani40c0f112020-04-15 09:55:00 -070093 // Uninstalls the DLC.
94 bool Uninstall(brillo::ErrorPtr* err);
95
Amin Hassania69f32e2020-03-30 15:20:42 -070096 // Deletes all files associated with the DLC.
Amin Hassani40c0f112020-04-15 09:55:00 -070097 bool Purge(brillo::ErrorPtr* err);
98
99 // Returns true if the DLC has to be removed/purged.
100 bool ShouldPurge();
Amin Hassania69f32e2020-03-30 15:20:42 -0700101
Amin Hassanif27aac02020-04-23 21:56:26 -0700102 // Is called when the DLC image is finally installed on the disk and is
103 // verified.
Amin Hassani4ca7e1c2020-04-29 13:01:33 -0700104 bool InstallCompleted(brillo::ErrorPtr* err);
Jae Hoon Kim9a27d152020-04-10 12:50:14 -0700105
Amin Hassanif27aac02020-04-23 21:56:26 -0700106 // Is called when the inactive DLC image is updated and verified.
Amin Hassani78a5ec82020-05-19 09:47:49 -0700107 bool UpdateCompleted(brillo::ErrorPtr* err);
Amin Hassanif27aac02020-04-23 21:56:26 -0700108
Amin Hassani48567772020-05-20 16:21:11 -0700109 // Makes the DLC ready to be updated (creates and resizes the inactive
110 // image). Returns false if anything goes wrong.
111 bool MakeReadyForUpdate() const;
Amin Hassani78a5ec82020-05-19 09:47:49 -0700112
113 // Changes the install progress on this DLC. Only changes if the |progress| is
114 // greater than the current progress value.
115 void ChangeProgress(double progress);
Jae Hoon Kim9a27d152020-04-10 12:50:14 -0700116
Amin Hassania69f32e2020-03-30 15:20:42 -0700117 private:
Amin Hassaniaa38c792020-04-06 15:52:44 -0700118 friend class DBusServiceTest;
119 FRIEND_TEST(DBusServiceTest, GetInstalled);
Amin Hassanid5fc8b22020-04-29 12:44:52 -0700120 FRIEND_TEST(DlcBaseTest, GetUsedBytesOnDisk);
Amin Hassani78a5ec82020-05-19 09:47:49 -0700121 FRIEND_TEST(DlcBaseTest, DefaultState);
122 FRIEND_TEST(DlcBaseTest, ChangeStateNotInstalled);
123 FRIEND_TEST(DlcBaseTest, ChangeStateInstalling);
124 FRIEND_TEST(DlcBaseTest, ChangeStateInstalled);
125 FRIEND_TEST(DlcBaseTest, ChangeProgress);
Amin Hassani48567772020-05-20 16:21:11 -0700126 FRIEND_TEST(DlcBaseTest, MakeReadyForUpdate);
Amin Hassani28ed9002020-05-28 12:37:01 -0700127 FRIEND_TEST(DlcBaseTest, MarkUnverified);
Amin Hassani6b7a9aa2020-05-29 14:23:47 -0700128 FRIEND_TEST(DlcBaseTest, MarkVerified);
Amin Hassani28ed9002020-05-28 12:37:01 -0700129 FRIEND_TEST(DlcBaseTest, PreloadCopyShouldMarkUnverified);
130 FRIEND_TEST(DlcBaseTest, PreloadCopyFailOnInvalidFileSize);
Jae Hoon Kim13e61512020-06-26 16:36:10 -0700131 FRIEND_TEST(DlcBaseTest, InstallingCorruptPreloadedImageCleansUp);
Jae Hoon Kimf49b6d72020-06-15 11:29:24 -0700132 FRIEND_TEST(DlcBaseTest, PreloadingSkippedOnAlreadyVerifiedDlc);
Jae Hoon Kimf9b2c9d2020-07-22 12:09:13 -0700133 FRIEND_TEST(DlcBaseTest, UnmountClearsMountPoint);
Amin Hassaniaa38c792020-04-06 15:52:44 -0700134
Amin Hassania69f32e2020-03-30 15:20:42 -0700135 // Returns the path to the DLC image given the slot number.
Amin Hassani4ca7e1c2020-04-29 13:01:33 -0700136 base::FilePath GetImagePath(BootSlot::Slot slot) const;
Amin Hassania69f32e2020-03-30 15:20:42 -0700137
Amin Hassanic0867b62020-04-16 09:44:34 -0700138 // Creates the DLC directories and files if they don't exist. This function
139 // should be used as fall-through. We should call this even if we presumably
140 // know the files are already there. This allows us to create any new DLC
141 // files that didn't exist on a previous version of the DLC.
142 bool CreateDlc(brillo::ErrorPtr* err);
Amin Hassania69f32e2020-03-30 15:20:42 -0700143
Amin Hassani6b7a9aa2020-05-29 14:23:47 -0700144 // Mark the current active DLC image as verified.
145 bool MarkVerified();
146
Amin Hassani28ed9002020-05-28 12:37:01 -0700147 // Mark the current active DLC image as unverified.
Amin Hassani6b7a9aa2020-05-29 14:23:47 -0700148 bool MarkUnverified();
Amin Hassani28ed9002020-05-28 12:37:01 -0700149
Jae Hoon Kim8ab26492020-05-07 13:49:36 -0700150 // Returns true if the DLC image in the current active slot matches the hash
151 // of that in the rootfs manifest for the DLC.
152 bool Verify();
153
Amin Hassania69f32e2020-03-30 15:20:42 -0700154 // Helper used to load in (copy + cleanup) preloadable files for the DLC.
Jae Hoon Kim0d4ff622020-05-14 14:47:40 -0700155 bool PreloadedCopier(brillo::ErrorPtr* err);
Amin Hassania69f32e2020-03-30 15:20:42 -0700156
157 // Mounts the DLC image.
Amin Hassani4ca7e1c2020-04-29 13:01:33 -0700158 bool Mount(brillo::ErrorPtr* err);
Amin Hassania69f32e2020-03-30 15:20:42 -0700159
160 // Unmounts the DLC image.
Amin Hassani4ca7e1c2020-04-29 13:01:33 -0700161 bool Unmount(brillo::ErrorPtr* err);
Amin Hassania69f32e2020-03-30 15:20:42 -0700162
Amin Hassania69f32e2020-03-30 15:20:42 -0700163 // Returns true if the active DLC image is present.
164 bool IsActiveImagePresent() const;
165
166 // Deletes all directories related to this DLC.
Amin Hassani4ca7e1c2020-04-29 13:01:33 -0700167 bool DeleteInternal(brillo::ErrorPtr* err);
Amin Hassania69f32e2020-03-30 15:20:42 -0700168
Amin Hassani78a5ec82020-05-19 09:47:49 -0700169 // Changes the state of the current DLC. It also notifies the state change
170 // reporter that a state change has been made.
171 void ChangeState(DlcState::State state);
172
Amin Hassani40c0f112020-04-15 09:55:00 -0700173 // Sets the DLC as being active or not based on |active| value.
174 void SetActiveValue(bool active);
175
Amin Hassania69f32e2020-03-30 15:20:42 -0700176 DlcId id_;
177 std::string package_;
178
179 DlcState state_;
180
181 base::FilePath mount_point_;
182
183 imageloader::Manifest manifest_;
184
185 // The directories on the stateful partition where the DLC image will reside.
186 base::FilePath content_id_path_;
187 base::FilePath content_package_path_;
Amin Hassanife63fc22020-04-07 11:34:34 -0700188 base::FilePath prefs_path_;
Jae Hoon Kimdcadbd42020-06-25 09:21:03 -0700189 base::FilePath prefs_package_path_;
Jae Hoon Kim0d4ff622020-05-14 14:47:40 -0700190 base::FilePath preloaded_image_path_;
Amin Hassania69f32e2020-03-30 15:20:42 -0700191
Amin Hassani40c0f112020-04-15 09:55:00 -0700192 // The object that keeps track of ref counts. NOTE: Do NOT access this object
193 // directly. Use |GetRefCount()| instead.
194 std::unique_ptr<RefCountInterface> ref_count_;
195
Amin Hassani6b010bf2020-06-04 17:26:58 -0700196 DlcBase(const DlcBase&) = delete;
197 DlcBase& operator=(const DlcBase&) = delete;
Amin Hassania69f32e2020-03-30 15:20:42 -0700198};
199
Amin Hassani86649982020-03-31 16:03:37 -0700200using DlcMap = std::map<DlcId, DlcBase>;
Amin Hassani9ca846f2020-04-17 12:41:01 -0700201using DlcIdList = std::vector<DlcId>;
Amin Hassani86649982020-03-31 16:03:37 -0700202
Amin Hassania69f32e2020-03-30 15:20:42 -0700203} // namespace dlcservice
204
205#endif // DLCSERVICE_DLC_H_