1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2019 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8 
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13 
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  * This is a Bacula plugin for backup/restore Docker using native tools.
21  *
22  * Author: Radosław Korzeniewski, MMXIX
23  * radoslaw@korzeniewski.net, radekk@inteos.pl
24  * Inteos Sp. z o.o. http://www.inteos.pl/
25  */
26 
27 #ifndef _DKINFO_H_
28 #define _DKINFO_H_
29 
30 #include "dkid.h"
31 #include "pluglib.h"
32 
33 /* The Docker container Power states */
34 typedef enum {
35    DKUNKNOWN = 0,
36    DKCREATED,
37    DKEXITED,
38    DKRUNNING,
39    DKPAUSED,
40 } DOCKER_POWER_T;
41 
42 /* Docker object types */
43 typedef enum {
44    DOCKER_CONTAINER,
45    DOCKER_IMAGE,
46    DOCKER_VOLUME,
47 } DKINFO_OBJ_t;
48 
49 /*
50  * Docker objects data variables.
51  */
52 typedef union {
53    struct {
54       DKID *containerid;
55       POOLMEM *names;
56       uint64_t size;
57       DOCKER_POWER_T status;
58       DKID *imagesave;
59       POOLMEM *imagesave_tag;
60       POOLMEM *mounts;
61       alist *vols;
62    } container;
63    struct {
64       DKID *imageid;
65       POOLMEM *repository;
66       uint64_t size;
67       POOLMEM *tag;
68       POOLMEM *repository_tag;
69       utime_t created;
70    } image;
71    struct {
72       POOLMEM *name;
73       utime_t created;
74       uint64_t size;
75       int linknr;
76    } volume;
77 } DOCKER_OBJ;
78 
79 /* forward reference */
80 class DKINFO;
81 
82 /*
83  * This is a simple special struct for handling docker mounts destination mappings
84  */
85 class DKVOLS : public SMARTALLOC {
86 public:
87    DKVOLS(DKINFO *dk);
88    ~DKVOLS();
89    DKINFO *vol;
90    POOLMEM *destination;
91 };
92 
93 /*
94  * The class which handles DKINFO operations
95  */
96 class DKINFO : public SMARTALLOC {
97  public:
98     DKINFO(DKINFO_OBJ_t t);
99     DKINFO(const DKINFO &dkinfo);
100     ~DKINFO();
101 
102     /* set methods dedicated to container */
set_container_id(DKID & id)103     inline void set_container_id(DKID &id) { if (Type == DOCKER_CONTAINER){ *data.container.containerid = id; }};
set_container_id(POOL_MEM & id)104     inline void set_container_id(POOL_MEM &id) { if (Type == DOCKER_CONTAINER){ *data.container.containerid = id; }};
set_container_id(POOLMEM * id)105     inline void set_container_id(POOLMEM *id) { if (Type == DOCKER_CONTAINER){ *data.container.containerid = (char*)id; }};
set_container_names(POOLMEM * n)106     inline void set_container_names(POOLMEM *n) { if (Type == DOCKER_CONTAINER){ pm_strcpy(data.container.names, n); }};
set_container_names(POOL_MEM & n)107     inline void set_container_names(POOL_MEM &n) { if (Type == DOCKER_CONTAINER){ pm_strcpy(data.container.names, n); }};
set_container_size(uint64_t s)108     inline void set_container_size(uint64_t s) { if (Type == DOCKER_CONTAINER){ data.container.size = s; }};
set_container_imagesave(DKID & id)109     inline void set_container_imagesave(DKID &id) { if (Type == DOCKER_CONTAINER){ *data.container.imagesave = id; }};
set_container_imagesave(POOL_MEM & id)110     inline void set_container_imagesave(POOL_MEM &id) { if (Type == DOCKER_CONTAINER){ *data.container.imagesave = id; }};
set_container_imagesave(POOLMEM * id)111     inline void set_container_imagesave(POOLMEM *id) { if (Type == DOCKER_CONTAINER){ *data.container.imagesave = (char*)id; }};
set_container_imagesave_tag(POOL_MEM & n)112     inline void set_container_imagesave_tag(POOL_MEM &n) { if (Type == DOCKER_CONTAINER){ pm_strcpy(data.container.imagesave_tag, n); }};
set_container_imagesave_tag(POOLMEM * n)113     inline void set_container_imagesave_tag(POOLMEM *n) { if (Type == DOCKER_CONTAINER){ pm_strcpy(data.container.imagesave_tag, n); }};
set_container_status(DOCKER_POWER_T s)114     inline void set_container_status(DOCKER_POWER_T s) { if (Type == DOCKER_CONTAINER){ data.container.status = s; }};
115     void set_container_status(POOL_MEM &s);
set_container_mounts(POOLMEM * n)116     inline void set_container_mounts(POOLMEM *n) { if (Type == DOCKER_CONTAINER){ pm_strcpy(data.container.mounts, n); }};
set_container_mounts(POOL_MEM & n)117     inline void set_container_mounts(POOL_MEM &n) { if (Type == DOCKER_CONTAINER){ pm_strcpy(data.container.mounts, n); }};
118 
119     /* special vols handling */
container_append_vols(DKVOLS * dk)120     inline void container_append_vols(DKVOLS *dk) { if (Type == DOCKER_CONTAINER){ data.container.vols->append(dk); }};
container_has_vols()121     inline bool container_has_vols() { return Type == DOCKER_CONTAINER ? !data.container.vols->empty() : false; };
container_first_vols()122     inline DKVOLS *container_first_vols() { return Type == DOCKER_CONTAINER ? (DKVOLS*)data.container.vols->first() : NULL; };
container_next_vols()123     inline DKVOLS *container_next_vols() { return Type == DOCKER_CONTAINER ? (DKVOLS*)data.container.vols->next() : NULL; };
124 
125     /* set methods dedicated to image */
set_image_id(DKID & id)126     inline void set_image_id(DKID &id) { if (Type == DOCKER_IMAGE){ *data.image.imageid = id; }};
set_image_id(POOLMEM * id)127     inline void set_image_id(POOLMEM *id) { if (Type == DOCKER_IMAGE){ *data.image.imageid = (char*)id; }};
set_image_id(POOL_MEM & id)128     inline void set_image_id(POOL_MEM &id) { if (Type == DOCKER_IMAGE){ *data.image.imageid = id; }};
set_image_repository(POOLMEM * n)129     inline void set_image_repository(POOLMEM *n) { if (Type == DOCKER_IMAGE){ pm_strcpy(data.image.repository, n); render_image_repository_tag(); }};
set_image_repository(POOL_MEM & n)130     inline void set_image_repository(POOL_MEM &n) { if (Type == DOCKER_IMAGE){ pm_strcpy(data.image.repository, n); render_image_repository_tag(); }};
set_image_tag(POOLMEM * n)131     inline void set_image_tag(POOLMEM *n) { if (Type == DOCKER_IMAGE){ pm_strcpy(data.image.tag, n); render_image_repository_tag(); }};
set_image_tag(POOL_MEM & n)132     inline void set_image_tag(POOL_MEM &n) { if (Type == DOCKER_IMAGE){ pm_strcpy(data.image.tag, n); render_image_repository_tag(); }};
set_image_size(uint64_t s)133     inline void set_image_size(uint64_t s) { if (Type == DOCKER_IMAGE){ data.image.size = s; }};
set_image_created(utime_t t)134     inline void set_image_created(utime_t t) { if (Type == DOCKER_IMAGE){ data.image.created = t; }};
135 
136     /* set methods dedicated to volume */
set_volume_name(POOLMEM * n)137     inline void set_volume_name(POOLMEM *n) { if (Type == DOCKER_VOLUME){ pm_strcpy(data.volume.name, n); }};
set_volume_name(POOL_MEM & n)138     inline void set_volume_name(POOL_MEM &n) { if (Type == DOCKER_VOLUME){ pm_strcpy(data.volume.name, n); }};
set_volume_created(utime_t t)139     inline void set_volume_created(utime_t t) { if (Type == DOCKER_VOLUME){ data.volume.created = t; }};
set_volume_size(uint64_t s)140     inline void set_volume_size(uint64_t s) { if (Type == DOCKER_VOLUME){ data.volume.size = s; }};
set_volume_linknr(int l)141     inline void set_volume_linknr(int l) { if (Type == DOCKER_VOLUME){ data.volume.linknr = l; }};
inc_volume_linknr()142     inline int inc_volume_linknr() { return Type == DOCKER_VOLUME ? ++data.volume.linknr : 0; };
143 
144     /* scanning methods */
145     void scan_container_size(POOLMEM *str);
146     void scan_image_size(POOLMEM *str);
147     void scan_image_repository_tag(POOL_MEM &rt);
148     void scan_volume_size(POOLMEM *str);
149 
150     /* get methods dedicated to container */
get_container_id()151     inline DKID *get_container_id() { return Type == DOCKER_CONTAINER ? data.container.containerid : NULL; };
get_container_imagesave()152     inline DKID *get_container_imagesave() { return Type == DOCKER_CONTAINER ? data.container.imagesave : NULL; };
get_container_names()153     inline POOLMEM *get_container_names() { return Type == DOCKER_CONTAINER ? data.container.names : NULL; };
get_container_status()154     inline DOCKER_POWER_T get_container_status() { return Type == DOCKER_CONTAINER ? data.container.status : DKUNKNOWN; };
get_container_size()155     inline uint64_t get_container_size() { return Type == DOCKER_CONTAINER ? data.container.size : 0; };
get_container_imagesave_tag()156     inline POOLMEM *get_container_imagesave_tag() { return Type == DOCKER_CONTAINER ? data.container.imagesave_tag : NULL; };
get_container_mounts()157     inline POOLMEM *get_container_mounts() { return Type == DOCKER_CONTAINER ? data.container.mounts : NULL; };
158 
159     /* get methods dedicated to image */
get_image_id()160     inline DKID *get_image_id() { return Type == DOCKER_IMAGE ? data.image.imageid : NULL; };
get_image_repository()161     inline POOLMEM *get_image_repository() { return Type == DOCKER_IMAGE ? data.image.repository : NULL; };
get_image_tag()162     inline POOLMEM *get_image_tag() { return Type == DOCKER_IMAGE ? data.image.tag : NULL; };
get_image_repository_tag()163     inline POOLMEM *get_image_repository_tag() { return Type == DOCKER_IMAGE ? data.image.repository_tag : NULL; };
get_image_size()164     inline uint64_t get_image_size() { return Type == DOCKER_IMAGE ? data.image.size : 0; };
get_image_created()165     inline utime_t get_image_created() { return Type == DOCKER_IMAGE ? data.image.created : 0; };
166 
167     /* get methods dedicated to volume */
get_volume_name()168     inline POOLMEM *get_volume_name() { return Type == DOCKER_VOLUME ? data.volume.name : NULL; };
get_volume_created()169     inline utime_t get_volume_created() { return Type == DOCKER_VOLUME ? data.volume.created : 0; };
get_volume_size()170     inline uint64_t get_volume_size() { return Type == DOCKER_VOLUME ? data.volume.size : 0; };
get_volume_linknr()171     inline int get_volume_linknr() { return Type == DOCKER_VOLUME ? data.volume.linknr : 0; };
172 
173     /* generic get methods which check dkinfo type */
174     DKID *id();
175     POOLMEM *name();
176     uint64_t size();
type()177     inline DKINFO_OBJ_t type() { return Type; };
178     const char *type_str();
179 
180  private:
181     DKINFO_OBJ_t Type;
182     DOCKER_OBJ data;
183 
184     void init(DKINFO_OBJ_t t);
render_image_repository_tag()185     inline void render_image_repository_tag()
186     {
187       pm_strcpy(data.image.repository_tag, data.image.repository);
188       pm_strcat(data.image.repository_tag, ":");
189       pm_strcat(data.image.repository_tag, data.image.tag);
190     };
191 };
192 
193 #endif   /* _DKINFO_H_ */