Esempio n. 1
0
def create_image(output,
                 identifier,
                 base=None,
                 layer=None,
                 metadata=None,
                 name=None,
                 repository=None):
    """Creates a Docker image.

  Args:
    output: the name of the docker image file to create.
    identifier: the identifier of the top layer for this image.
    base: a base layer (optional) to merge to current layer.
    layer: the layer content (a tar file).
    metadata: the json metadata file for the top layer.
    name: symbolic name for this docker image.
    repository: repository name for this docker image.
  """
    tar = archive.TarFileWriter(output)
    # Write our id to 'top' as we are now the topmost layer.
    tar.add_file('top', content=identifier)
    # Each layer is encoded as a directory in the larger tarball of the form:
    #  {id}\
    #    layer.tar
    #    VERSION
    #    json
    # Create the directory for us to now fill in.
    tar.add_file(identifier + '/', tarfile.DIRTYPE)
    # VERSION generally seems to contain 1.0, not entirely sure
    # what the point of this is.
    tar.add_file(identifier + '/VERSION', content=DATA_FORMAT_VERSION)
    # Add the layer file
    tar.add_file(identifier + '/layer.tar', file_content=layer)
    # Now the json metadata
    tar.add_file(identifier + '/json', file_content=metadata)
    # Merge the base if any
    if base:
        tar.add_tar(base, name_filter=_base_name_filter)
    # In addition to N layers of the form described above, there is
    # a single file at the top of the image called repositories.
    # This file contains a JSON blob of the form:
    # {
    #   'repo':{
    #     'tag-name': 'top-most layer hex',
    #     ...
    #   },
    #   ...
    # }
    if repository:
        tar.add_file('repositories',
                     content='\n'.join([
                         '{',
                         '  "%s": {' % repository,
                         '    "%s": "%s"' % (name, identifier), '  }', '}'
                     ]))
Esempio n. 2
0
 def testMergeTar(self):
   content = [
       {"name": "./a", "data": "a"},
       {"name": "./ab", "data": "ab"}
       ]
   for ext in ["", ".gz", ".bz2", ".xz"]:
     with archive.TarFileWriter(self.tempfile) as f:
       f.add_tar(os.path.join(testenv.TESTDATA_PATH, "archive",
                              "tar_test.tar" + ext),
                 name_filter=lambda n: n != "./b")
     self.assertTarFileContent(self.tempfile, content)
Esempio n. 3
0
 def testDottedFiles(self):
   with archive.TarFileWriter(self.tempfile) as f:
     f.add_file("a")
     f.add_file("/b")
     f.add_file("./c")
     f.add_file("./.d")
     f.add_file("..e")
     f.add_file(".f")
   content = [
       {"name": "./a"},
       {"name": "/b"},
       {"name": "./c"},
       {"name": "./.d"},
       {"name": "./..e"},
       {"name": "./.f"}
       ]
   self.assertTarFileContent(self.tempfile, content)
Esempio n. 4
0
 def testAddDir(self):
   # For some strange reason, ending slash is stripped by the test
   content = [
       {"name": ".", "mode": 0755},
       {"name": "./a", "mode": 0755},
       {"name": "./a/b", "data": "ab", "mode": 0644},
       {"name": "./a/c", "mode": 0755},
       {"name": "./a/c/d", "data": "acd", "mode": 0644},
       ]
   tempdir = os.path.join(os.environ["TEST_TMPDIR"], "test_dir")
   # Iterate over the `content` array to create the directory
   # structure it describes.
   for c in content:
     if "data" in c:
       p = os.path.join(tempdir, c["name"][2:])
       os.makedirs(os.path.dirname(p))
       with open(p, "w") as f:
         f.write(c["data"])
   with archive.TarFileWriter(self.tempfile) as f:
     f.add_dir("./", tempdir, mode=0644)
   self.assertTarFileContent(self.tempfile, content)
Esempio n. 5
0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A simple cross-platform helper to create a timestamped tar file."""
import datetime
import sys
import tarfile

from tools.build_defs.docker import archive

if __name__ == '__main__':
    mtime = int(datetime.datetime.now().strftime('%s'))
    with archive.TarFileWriter(sys.argv[1]) as f:
        f.add_file('./',
                   tarfile.DIRTYPE,
                   uname='root',
                   gname='root',
                   mtime=mtime)
        f.add_file('./usr/',
                   tarfile.DIRTYPE,
                   uname='root',
                   gname='root',
                   mtime=mtime)
        f.add_file('./usr/bin/',
                   tarfile.DIRTYPE,
                   uname='root',
                   gname='root',
                   mtime=mtime)
Esempio n. 6
0
 def __enter__(self):
   self.tarfile = archive.TarFileWriter(self.output)
   return self
Esempio n. 7
0
 def assertSimpleFileContent(self, names):
   with archive.TarFileWriter(self.tempfile) as f:
     for n in names:
       f.add_file(n, content=n)
   content = [{"name": n, "size": len(n), "data": n} for n in names]
   self.assertTarFileContent(self.tempfile, content)
Esempio n. 8
0
 def testEmptyTarFile(self):
   with archive.TarFileWriter(self.tempfile):
     pass
   self.assertTarFileContent(self.tempfile, [])