softwarecontainer  0.18.0-739e8d7 2017-05-04
devicenode.cpp
1 /*
2  * Copyright (C) 2017 Pelagicore AB
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
9  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
11  * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
12  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
13  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
14  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15  * SOFTWARE.
16  *
17  * For further information see LICENSE
18  */
19 
20 #include <sys/stat.h>
21 
22 #include "devicenode.h"
23 #include "functionjob.h"
24 
25 namespace softwarecontainer {
26 
27 Device::Device(std::string name, int mode) :
28  m_name(name),
29  m_mode(mode),
30  m_isConfigured(false)
31 { }
32 
33 Device::Device(const Device &dev) :
34  m_name(dev.m_name),
35  m_mode(dev.m_mode),
36  m_isConfigured(false)
37 { }
38 
39 bool Device::parse(const json_t *element)
40 {
41 
42  m_name = "";
43  if (!JSONParser::read(element, "name", m_name)) {
44  log_error() << "Key \"name\" missing or not a string in json configuration";
45  return false;
46  }
47 
48  m_mode = -1;
49 
50  // Mode is optional, i.e. do not do anything if it is not specified.
51  if (nullptr != json_object_get(element, "mode")) {
52  const bool modeParses = JSONParser::read(element, "mode", m_mode);
53 
54  if (!modeParses) {
55  log_error() << "Mode specified with bad format";
56  return false;
57  }
58  }
59 
60  return true;
61 }
62 
63 bool Device::activate(std::shared_ptr<ContainerAbstractInterface> container)
64 {
65  if (!m_isConfigured) {
66  log_info() << "Mapping device " << m_name;
67  // Mount device in container
68  if (!container->mountDevice(m_name)) {
69  log_error() << "Unable to mount device " << m_name;
70  return false;
71  }
72 
73  // If mode is specified, try to set mode for the mounted device.
74  if (m_mode != -1) {
75  FunctionJob job(container, [&] () {
76  return chmod(m_name.c_str(), m_mode);
77  });
78  job.start();
79  job.wait();
80  if (job.isError()) {
81  log_error() << "Could not 'chmod " << m_mode
82  << "' the mounted device " << m_name;
83  return false;
84  }
85  }
86  m_isConfigured = true;
87  }
88  return true;
89 }
90 
91 void Device::calculateDeviceMode(const int appliedMode)
92 {
93  int modeResult = m_mode;
94 
95  if (m_mode != appliedMode) {
96  //apply more permissive option for owner
97  ((appliedMode / 100) >= (m_mode / 100)) ?
98  modeResult = (appliedMode / 100) * 100 : modeResult = (m_mode / 100) * 100;
99  //apply more permissive option for group
100  (((appliedMode / 10) % 10) >= ((m_mode / 10) % 10)) ?
101  modeResult += (((appliedMode / 10) % 10) * 10) : modeResult += (((m_mode / 10) % 10) * 10);
102  //apply more permissive option for others
103  ((appliedMode % 10) >= (m_mode % 10)) ?
104  modeResult += (appliedMode % 10) : modeResult += (m_mode % 10);
105 
106  }
107 
108  if (modeResult > m_mode) {
109  m_isConfigured = false;
110  m_mode = modeResult;
111  }
112 }
113 
114 const std::string Device::getName()
115 {
116  return m_name;
117 }
118 
119 int Device::getMode()
120 {
121  return m_mode;
122 }
123 
124 bool Device::getIsconfigured ()
125 {
126  return m_isConfigured;
127 }
128 
129 void Device::setMode(int mode)
130 {
131  if ((mode/100) < 8 && (mode%100)/10 < 8 && (mode%10) < 8) {
132  m_mode = mode;
133  }
134 }
135 
136 
137 
138 } // namespace softwarecontainer
bool activate(std::shared_ptr< ContainerAbstractInterface > container)
Activates this device by running mknod and chmod commands which are run in the container.
Definition: devicenode.cpp:63
Run a C++ function lambda inside a SoftwareContainer.
Definition: functionjob.h:30
bool parse(const json_t *element)
Configures this device by parsing the supplied JSON configuration string.
Definition: devicenode.cpp:39
Developers guide to adding a config item:
static bool read(const json_t *element, const char *key, std::string &result)
Reads a string from a JSON Object.
Definition: jsonparser.cpp:51