当前位置: 首页 > news >正文

网站建设用到什么软件免费服务器空间申请

网站建设用到什么软件,免费服务器空间申请,国内新闻最新消息10条简短2022,百度快照 查看指定网站镜像导入是由image/tarexport/load.go#tarexporter.Load()完成的 以下代码参考github.com/docker/docker版本v0.0.0-20181129155816-baab736a3649 主要是注册镜像信息以及解包镜像tar流到新root 导出和保存的区别在于 导出(export): 仅导出文件结构保存(save): 保存镜像历史和元…镜像导入是由image/tarexport/load.go#tarexporter.Load()完成的 以下代码参考github.com/docker/docker版本v0.0.0-20181129155816-baab736a3649 主要是注册镜像信息以及解包镜像tar流到新root 导出和保存的区别在于 导出(export): 仅导出文件结构保存(save): 保存镜像历史和元数据 这意味着导出将不会包含USER、EXPOSE等Dockerfile里面的命令也就无法转移镜像到另一台机器上了 func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {var progressOutput progress.Outputif !quiet {progressOutput streamformatter.NewJSONProgressOutput(outStream, false)}outStream streamformatter.NewStdoutWriter(outStream)// 1. 创建docker-import的临时目录tmpDir, err : ioutil.TempDir(, docker-import-)if err ! nil {return err}defer os.RemoveAll(tmpDir)// 2. 解包tar流到临时目录if err : chrootarchive.Untar(inTar, tmpDir, nil); err ! nil {return err}// 3. 打开manifest文件并解析manifestPath, err : safePath(tmpDir, manifestFileName)if err ! nil {return err}manifestFile, err : os.Open(manifestPath)if err ! nil {if os.IsNotExist(err) {return l.legacyLoad(tmpDir, outStream, progressOutput)}return err}defer manifestFile.Close()var manifest []manifestItemif err : json.NewDecoder(manifestFile).Decode(manifest); err ! nil {return err}var parentLinks []parentLinkvar imageIDsStr stringvar imageRefCount int// 4. 从manifest中读取并解析到imagefor _, m : range manifest {configPath, err : safePath(tmpDir, m.Config)if err ! nil {return err}config, err : ioutil.ReadFile(configPath)if err ! nil {return err}img, err : image.NewFromJSON(config)if err ! nil {return err}if err : checkCompatibleOS(img.OS); err ! nil {return err}rootFS : *img.RootFSrootFS.DiffIDs nil// 若image rootFS diffID数量与manifest中记录的层数不一致则报错if expected, actual : len(m.Layers), len(img.RootFS.DiffIDs); expected ! actual {return fmt.Errorf(invalid manifest, layers length mismatch: expected %d, got %d, expected, actual)}// On Windows, validate the platform, defaulting to windows if not present.os : img.OSif os {os runtime.GOOS}if runtime.GOOS windows {if (os ! windows) (os ! linux) {return fmt.Errorf(configuration for this image has an unsupported operating system: %s, os)}}// 5. 注册层for i, diffID : range img.RootFS.DiffIDs {layerPath, err : safePath(tmpDir, m.Layers[i])if err ! nil {return err}r : rootFSr.Append(diffID)newLayer, err : l.lss[os].Get(r.ChainID())if err ! nil {// 如果没有注册那就注册layernewLayer, err l.loadLayer(layerPath, rootFS, diffID.String(), os, m.LayerSources[diffID], progressOutput)if err ! nil {return err}}defer layer.ReleaseAndLog(l.lss[os], newLayer)// 若manifest与缓存中layer diffID不一致则报错if expected, actual : diffID, newLayer.DiffID(); expected ! actual {return fmt.Errorf(invalid diffID for layer %d: expected %q, got %q, i, expected, actual)}rootFS.Append(diffID)}// 6. 缓存该层镜像配置imgID, err : l.is.Create(config)if err ! nil {return err}imageIDsStr fmt.Sprintf(Loaded image ID: %s\n, imgID)imageRefCount 0for _, repoTag : range m.RepoTags {named, err : reference.ParseNormalizedNamed(repoTag)if err ! nil {return err}ref, ok : named.(reference.NamedTagged)if !ok {return fmt.Errorf(invalid tag %q, repoTag)}// 设置已加载的id、referencel.setLoadedTag(ref, imgID.Digest(), outStream)outStream.Write([]byte(fmt.Sprintf(Loaded image: %s\n, reference.FamiliarString(ref))))imageRefCount}parentLinks append(parentLinks, parentLink{imgID, m.Parent})l.loggerImgEvent.LogImageEvent(imgID.String(), imgID.String(), load)}for _, p : range validatedParentLinks(parentLinks) {if p.parentID ! {if err : l.setParentID(p.id, p.parentID); err ! nil {return err}}}if imageRefCount 0 {outStream.Write([]byte(imageIDsStr))}return nil }Untar 主要过程是将tar流解包到新root untar操作实际由chrootarchive/archive_unix.go untar()执行 // untar is the entry-point for docker-untar on re-exec. This is not used on // Windows as it does not support chroot, hence no point sandboxing through // chroot and rexec. func untar() {runtime.LockOSThread()flag.Parse()var options *archive.TarOptions//read the options from the pipe ExtraFilesif err : json.NewDecoder(os.NewFile(3, options)).Decode(options); err ! nil {fatal(err)}// Linux上的Chroot使用pivot_root而不是Chroot。 pivot_root需要一个新根和一个旧根。旧根必须是新根的子目录它是调用pivot_root后当前rootfs驻留的位置。New root是新rootfs设置的位置。在调用pivot_root之后旧根会被移除因此在新根下不再可用。这类似于libcontainer设置容器rootfs的方式// 在这里是以前面创建的临时目录作为新root并在其下创建privot_root作为老root最后切换到新rootif err : chroot(flag.Arg(0)); err ! nil {fatal(err)}// 将tar流解包到新rootif err : archive.Unpack(os.Stdin, /, options); err ! nil {fatal(err)}// fully consume stdin in case it is zero paddedif _, err : flush(os.Stdin); err ! nil {fatal(err)}os.Exit(0) }loadLayer 注册镜像层以及加载层tar流到对应目录下 image/tarexport/load.go#tarexpoter.loadLayer() func (l *tarexporter) loadLayer(filename string, rootFS image.RootFS, id string, os string, foreignSrc distribution.Descriptor, progressOutput progress.Output) (layer.Layer, error) {// We use system.OpenSequential to use sequential file access on Windows, avoiding// depleting the standby list. On Linux, this equates to a regular os.Open.rawTar, err : system.OpenSequential(filename)if err ! nil {logrus.Debugf(Error reading embedded tar: %v, err)return nil, err}defer rawTar.Close()var r io.Readerif progressOutput ! nil {fileInfo, err : rawTar.Stat()if err ! nil {logrus.Debugf(Error statting file: %v, err)return nil, err}r progress.NewProgressReader(rawTar, progressOutput, fileInfo.Size(), stringid.TruncateID(id), Loading layer)} else {r rawTar}inflatedLayerData, err : archive.DecompressStream(r)if err ! nil {return nil, err}defer inflatedLayerData.Close()if ds, ok : l.lss[os].(layer.DescribableStore); ok {return ds.RegisterWithDescriptor(inflatedLayerData, rootFS.ChainID(), foreignSrc)}// 到这里是去注册层tar流和本层镜像的chainIDreturn l.lss[os].Register(inflatedLayerData, rootFS.ChainID()) } func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, descriptor distribution.Descriptor) (Layer, error) {// err is used to hold the error which will always trigger// cleanup of creates sources but may not be an error returned// to the caller (already exists).var err errorvar pid stringvar p *roLayer// 1. 从缓存中获取到给定chainID的层信息if string(parent) ! {p ls.get(parent)if p nil {return nil, ErrLayerDoesNotExist}pid p.cacheID// Release parent chain if errordefer func() {if err ! nil {ls.layerL.Lock()ls.releaseLayer(p)ls.layerL.Unlock()}}()if p.depth() maxLayerDepth {err ErrMaxDepthExceededreturn nil, err}}// 2. 创建新的只读层layer : roLayer{parent: p,cacheID: stringid.GenerateRandomID(),referenceCount: 1,layerStore: ls,references: map[Layer]struct{}{},descriptor: descriptor,}// 3. 准备文件系统(overlay2)文件目录结构if err ls.driver.Create(layer.cacheID, pid, nil); err ! nil {return nil, err}tx, err : ls.store.StartTransaction()if err ! nil {return nil, err}defer func() {if err ! nil {logrus.Debugf(Cleaning up layer %s: %v, layer.cacheID, err)if err : ls.driver.Remove(layer.cacheID); err ! nil {logrus.Errorf(Error cleaning up cache layer %s: %v, layer.cacheID, err)}if err : tx.Cancel(); err ! nil {logrus.Errorf(Error canceling metadata transaction %q: %s, tx.String(), err)}}}()// 4. 从给定读写层流中提取变化的内容到镜像层挂载点if err ls.applyTar(tx, ts, pid, layer); err ! nil {return nil, err}// 5. 若本层无父层那么chainID就是自己的diffID。否则从parent和自己的diffID中生成if layer.parent nil {layer.chainID ChainID(layer.diffID)} else {layer.chainID createChainIDFromParent(layer.parent.chainID, layer.diffID)}// 6. 储存层diffID、size、cacheID、descriptor、parent、os等信息if err storeLayer(tx, layer); err ! nil {return nil, err}ls.layerL.Lock()defer ls.layerL.Unlock()if existingLayer : ls.getWithoutLock(layer.chainID); existingLayer ! nil {// Set error for cleanup, but do not return the errorerr errors.New(layer already exists)return existingLayer.getReference(), nil}if err tx.Commit(layer.chainID); err ! nil {return nil, err}ls.layerMap[layer.chainID] layerreturn layer.getReference(), nil }driver.Create 为镜像层创建diff、work、lower目录并写入镜像层tar流lower内容到对应lower目录 func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) {dir : d.dir(id)// 1. 获取当前用户在宿主机对应的userID、groupIDrootUID, rootGID, err : idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)if err ! nil {return err}root : idtools.Identity{UID: rootUID, GID: rootGID}// 2. 为当前用户创建镜像目录if err : idtools.MkdirAllAndChown(path.Dir(dir), 0700, root); err ! nil {return err}if err : idtools.MkdirAndChown(dir, 0700, root); err ! nil {return err}defer func() {// Clean up on failureif retErr ! nil {os.RemoveAll(dir)}}()// 3. 解析储存选项if opts ! nil len(opts.StorageOpt) 0 {driver : Driver{}if err : d.parseStorageOpt(opts.StorageOpt, driver); err ! nil {return err}// 4. 设置储存配额if driver.options.quota.Size 0 {// Set container disk quota limitif err : d.quotaCtl.SetQuota(dir, driver.options.quota); err ! nil {return err}}}// 5. 创建镜像diff目录if err : idtools.MkdirAndChown(path.Join(dir, diff), 0755, root); err ! nil {return err}// 6. 创建指向diff目录的链接lid : generateID(idLength)if err : os.Symlink(path.Join(.., id, diff), path.Join(d.home, linkDir, lid)); err ! nil {return err}// 7. 将链接id写入链接文件if err : ioutil.WriteFile(path.Join(dir, link), []byte(lid), 0644); err ! nil {return err}// 8. 父层不存在就直接返回if parent {return nil}// 9. 创建镜像work目录作为overlay2内部使用if err : idtools.MkdirAndChown(path.Join(dir, work), 0700, root); err ! nil {return err}// 10. 找到父层(也就是tar中的镜像层)lower文件并写入到当前层lower文件中lower, err : d.getLower(parent)if err ! nil {return err}if lower ! {if err : ioutil.WriteFile(path.Join(dir, lowerFile), []byte(lower), 0666); err ! nil {return err}}return nil }applyTar 将层tar流解包到层挂载点 func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, diff io.Reader) (size int64, err error) {driver : gdw.ProtoDriver// Mount the root filesystem so we can apply the diff/layer.// 返回由id引用的分层文件系统的挂载点layerRootFs, err : driver.Get(id, )if err ! nil {return}defer driver.Put(id)layerFs : layerRootFs.Path()options : archive.TarOptions{UIDMaps: gdw.uidMaps,GIDMaps: gdw.gidMaps}start : time.Now().UTC()logrus.WithField(id, id).Debug(Start untar layer)// 将层tar流解包到层挂载点if size, err ApplyUncompressedLayer(layerFs, diff, options); err ! nil {return}logrus.WithField(id, id).Debugf(Untar time: %vs, time.Now().UTC().Sub(start).Seconds())return }Create 创建就是在缓存中添加镜像信息保存配置 func (is *store) Create(config []byte) (ID, error) {var img Imageerr : json.Unmarshal(config, img)if err ! nil {return , err}// Must reject any config that references diffIDs from the history// which arent among the rootfs layers.rootFSLayers : make(map[layer.DiffID]struct{})for _, diffID : range img.RootFS.DiffIDs {rootFSLayers[diffID] struct{}{}}// 如果记录的创建历史非空层大于rootFS层数报错layerCounter : 0for _, h : range img.History {if !h.EmptyLayer {layerCounter}}if layerCounter len(img.RootFS.DiffIDs) {return , errors.New(too many non-empty layers in History section)}// 将解析配置写入content目录dgst, err : is.fs.Set(config)if err ! nil {return , err}imageID : IDFromDigest(dgst)is.Lock()defer is.Unlock()// 若镜像已经存在镜像元数据缓存中就直接返回if _, exists : is.images[imageID]; exists {return imageID, nil}layerID : img.RootFS.ChainID()var l layer.Layer// 获取镜像只读层并缓存if layerID ! {if !system.IsOSSupported(img.OperatingSystem()) {return , system.ErrNotSupportedOperatingSystem}l, err is.lss[img.OperatingSystem()].Get(layerID)if err ! nil {return , errors.Wrapf(err, failed to get layer %s, layerID)}}imageMeta : imageMeta{layer: l,children: make(map[ID]struct{}),}is.images[imageID] imageMeta// 添加reference和id缓存if err : is.digestSet.Add(imageID.Digest()); err ! nil {delete(is.images, imageID)return , err}return imageID, nil }创建容器时是如何使用image的 从缓存获取镜像配置进行校验以及合并容器配置以镜像chainID作为容器挂载层(也是读写层)的parent复制镜像目录内容到容器目录 Ref https://stackoverflow.com/questions/22655867/what-is-the-difference-between-save-and-export-in-docker
http://wiki.neutronadmin.com/news/53718/

相关文章:

  • 哪些门户网站可以做推广wordpress随机注册
  • 京东网站的建设与发展前景邢台润联科技有限公司
  • 无锡企业网站制作一般多少钱如何设计网站风格
  • 网赌网站怎么做的企业公众号如何开通
  • 网站设计专业wordpress顶部通知栏公告
  • 做网站漯河诸暨建设局网站
  • 网站建设工程师wordpress 农场模板
  • 高端定制站开发免费logo网站
  • 学做ps的网站有哪些拍摄制作公司宣传片
  • 泉州公司建设网站企业网站建设注意点
  • 需要手机端网站建设的企业网站建设常州麦策电商
  • 中国建设工程机械网站怎么做特色网站
  • 百度推广网站可以链接到同公司另一个网站吗福田祥菱怎么样
  • 组织网站建设应该注意什么wordpress变为中文
  • 个人网站模板大全免费国外网站模板
  • 山西格泰网站建设建筑网2016农村别墅图大全
  • 国外响应式网站模板安仁做网站
  • 手机网站模板代码网站更换备案号
  • 厦门网站建设阿里东莞多地调整为中高风险地区
  • 网站的二级目录怎么做网站备案网站简介
  • 部队网站建设招标淘宝客优惠卷网站怎么做的
  • 中国icp备案的有多少企业网站wordpress客户端被墙
  • 访问网站的原理龙岗网站建设网站制作
  • 无极app定制开发公司网站模板pc版网站生成App
  • 网站建设 技术方案模板企业门户网站开发任务书
  • 鹿城做网站如何自己建营销网站
  • 济宁网站建设流程合作加盟
  • 重庆网站制作服务自己的网站怎么编辑器
  • 用aspx做的网站wordpress又拍云插件
  • 商城微网站如何做图片下载网站哪个好