"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1387],{2314:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});var i=r(5893),s=r(1151);const o={},c="The Drives CLI",t={id:"guides/drives/cli",title:"The Drives CLI",description:"The zrok drives CLI tools allow for simple, ergonomic management and synchronization of local and remote files.",source:"@site/../docs/guides/drives/cli.md",sourceDirName:"guides/drives",slug:"/guides/drives/cli",permalink:"/docs/guides/drives/cli",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/drives/cli.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Instance Config",permalink:"/docs/guides/self-hosting/instance-configuration"},next:{title:"VPN",permalink:"/docs/guides/vpn/"}},a={},d=[{value:"Sharing a Drive",id:"sharing-a-drive",level:2},{value:"Working with a Private Drive Share",id:"working-with-a-private-drive-share",level:2},{value:"Working with Public Shares",id:"working-with-public-shares",level:2},{value:"One-way Synchronization",id:"one-way-synchronization",level:2},{value:"Drive-to-Drive Copies and Synchronization",id:"drive-to-drive-copies-and-synchronization",level:2},{value:"Copying from Drives to the Local Filesystem",id:"copying-from-drives-to-the-local-filesystem",level:2},{value:"Unique Names and Reserved Shares",id:"unique-names-and-reserved-shares",level:2},{value:"Future Enhancements",id:"future-enhancements",level:2}];function l(e){const n={code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"the-drives-cli",children:"The Drives CLI"}),"\n",(0,i.jsx)(n.p,{children:"The zrok drives CLI tools allow for simple, ergonomic management and synchronization of local and remote files."}),"\n",(0,i.jsx)(n.h2,{id:"sharing-a-drive",children:"Sharing a Drive"}),"\n",(0,i.jsxs)(n.p,{children:["Virtual drives are shared through the ",(0,i.jsx)(n.code,{children:"zrok"})," CLI using the ",(0,i.jsx)(n.code,{children:"--backend-mode drive"})," flag through the ",(0,i.jsx)(n.code,{children:"zrok share"})," command, using either the ",(0,i.jsx)(n.code,{children:"public"})," or ",(0,i.jsx)(n.code,{children:"private"})," sharing modes. We'll use the ",(0,i.jsx)(n.code,{children:"private"})," sharing mode for this example:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ mkdir /tmp/junk\n$ zrok share private --headless --backend-mode drive /tmp/junk\n[ 0.124] INFO sdk-golang/ziti.(*listenerManager).createSessionWithBackoff: {session token=[cf640aac-2706-49ae-9cc9-9a497d67d9c5]} new service session\n[ 0.145] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:\nzrok access private wkcfb58vj51l\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The command shown above creates an ephemeral, ",(0,i.jsx)(n.code,{children:"private"})," drive share pointed at the local ",(0,i.jsx)(n.code,{children:"/tmp/junk"})," folder."]}),"\n",(0,i.jsxs)(n.p,{children:["Notice that the share token allocated by ",(0,i.jsx)(n.code,{children:"zrok"})," is ",(0,i.jsx)(n.code,{children:"wkcfb58vj51l"}),". We'll use that share token to identify our virtual drive in the following operations."]}),"\n",(0,i.jsx)(n.h2,{id:"working-with-a-private-drive-share",children:"Working with a Private Drive Share"}),"\n",(0,i.jsxs)(n.p,{children:["First, let's copy a file into our virtual drive using the ",(0,i.jsx)(n.code,{children:"zrok copy"})," command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok copy LICENSE zrok://wkcfb58vj51l\n[ 0.119] INFO zrok/drives/sync.OneWay: => /LICENSE\ncopy complete!\n"})}),"\n",(0,i.jsxs)(n.p,{children:["We used the URL scheme ",(0,i.jsx)(n.code,{children:"zrok://"})," to refer to the private virtual drive we allocated above using the ",(0,i.jsx)(n.code,{children:"zrok share private"})," command. Use ",(0,i.jsx)(n.code,{children:"zrok://"})," URLs with the drives CLI tools to refer to contents of private virtual drives."]}),"\n",(0,i.jsx)(n.p,{children:"Next, let's get a directory listing of the virtual drive:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok ls zrok://wkcfb58vj51l\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 TYPE \u2502 NAME \u2502 SIZE \u2502 MODIFIED \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 \u2502 LICENSE \u2502 11.3 kB \u2502 2024-01-19 12:16:46 -0500 EST \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n"})}),"\n",(0,i.jsx)(n.p,{children:"We can make directories on the virtual drive:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok mkdir zrok://wkcfb58vj51l/stuff\n$ zrok ls zrok://wkcfb58vj51l\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 TYPE \u2502 NAME \u2502 SIZE \u2502 MODIFIED \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 \u2502 LICENSE \u2502 11.3 kB \u2502 2024-01-19 12:16:46 -0500 EST \u2502\n\u2502 DIR \u2502 stuff \u2502 \u2502 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n"})}),"\n",(0,i.jsx)(n.p,{children:"We can copy the contents of a local directory into the new directory on the virtual drive:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ls -l util/\ntotal 20\n-rw-rw-r-- 1 michael michael 329 Jul 21 13:17 email.go\n-rw-rw-r-- 1 michael michael 456 Jul 21 13:17 headers.go\n-rw-rw-r-- 1 michael michael 609 Jul 21 13:17 proxy.go\n-rw-rw-r-- 1 michael michael 361 Jul 21 13:17 size.go\n-rw-rw-r-- 1 michael michael 423 Jan 2 11:57 uniqueName.go\n$ zrok copy util/ zrok://wkcfb58vj51l/stuff\n[ 0.123] INFO zrok/drives/sync.OneWay: => /email.go\n[ 0.194] INFO zrok/drives/sync.OneWay: => /headers.go\n[ 0.267] INFO zrok/drives/sync.OneWay: => /proxy.go\n[ 0.337] INFO zrok/drives/sync.OneWay: => /size.go\n[ 0.408] INFO zrok/drives/sync.OneWay: => /uniqueName.go\ncopy complete!\n$ zrok ls zrok://wkcfb58vj51l/stuff\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 TYPE \u2502 NAME \u2502 SIZE \u2502 MODIFIED \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 \u2502 email.go \u2502 329 B \u2502 2024-01-19 12:26:45 -0500 EST \u2502\n\u2502 \u2502 headers.go \u2502 456 B \u2502 2024-01-19 12:26:45 -0500 EST \u2502\n\u2502 \u2502 proxy.go \u2502 609 B \u2502 2024-01-19 12:26:45 -0500 EST \u2502\n\u2502 \u2502 size.go \u2502 361 B \u2502 2024-01-19 12:26:45 -0500 EST \u2502\n\u2502 \u2502 uniqueName.go \u2502 423 B \u2502 2024-01-19 12:26:45 -0500 EST \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n"})}),"\n",(0,i.jsx)(n.p,{children:"And we can remove files and directories from the virtual drive:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok rm zrok://wkcfb58vj51l/LICENSE\n$ zrok ls zrok://wkcfb58vj51l\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 TYPE \u2502 NAME \u2502 SIZE \u2502 MODIFIED \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 DIR \u2502 stuff \u2502 \u2502 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n$ zrok rm zrok://wkcfb58vj51l/stuff\n$ zrok ls zrok://wkcfb58vj51l\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 TYPE \u2502 NAME \u2502 SIZE \u2502 MODIFIED \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n"})}),"\n",(0,i.jsx)(n.h2,{id:"working-with-public-shares",children:"Working with Public Shares"}),"\n",(0,i.jsx)(n.p,{children:"Public shares work very similarly to private shares, they just use a different URL scheme:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok share public --headless --backend-mode drive /tmp/junk\n[ 0.708] INFO sdk-golang/ziti.(*listenerManager).createSessionWithBackoff: {session token=[05e0f48b-242b-4fd9-8edb-259488535c47]} new service session\n[ 0.878] INFO main.(*sharePublicCommand).run: access your zrok share at the following endpoints:\n https://6kiww4bn7iok.share.zrok.io\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The same commands, with a different URL scheme work with the ",(0,i.jsx)(n.code,{children:"zrok"})," drives CLI:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok copy util/ https://6kiww4bn7iok.share.zrok.io\n[ 0.268] INFO zrok/drives/sync.OneWay: => /email.go\n[ 0.406] INFO zrok/drives/sync.OneWay: => /headers.go\n[ 0.530] INFO zrok/drives/sync.OneWay: => /proxy.go\n[ 0.655] INFO zrok/drives/sync.OneWay: => /size.go\n[ 0.714] INFO zrok/drives/sync.OneWay: => /uniqueName.go\ncopy complete!\nmichael@fourtyfour Fri Jan 19 12:42:52 ~/Repos/nf/zrok \n$ zrok ls https://6kiww4bn7iok.share.zrok.io\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 TYPE \u2502 NAME \u2502 SIZE \u2502 MODIFIED \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 \u2502 email.go \u2502 329 B \u2502 2023-07-21 13:17:56 -0400 EDT \u2502\n\u2502 \u2502 headers.go \u2502 456 B \u2502 2023-07-21 13:17:56 -0400 EDT \u2502\n\u2502 \u2502 proxy.go \u2502 609 B \u2502 2023-07-21 13:17:56 -0400 EDT \u2502\n\u2502 \u2502 size.go \u2502 361 B \u2502 2023-07-21 13:17:56 -0400 EDT \u2502\n\u2502 \u2502 uniqueName.go \u2502 423 B \u2502 2024-01-02 11:57:14 -0500 EST \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For basic authentication provided by public shares, the ",(0,i.jsx)(n.code,{children:"zrok"})," drives CLI offers the ",(0,i.jsx)(n.code,{children:"--basic-auth"})," flag, which accepts a ",(0,i.jsx)(n.code,{children:":"})," parameter to specify the authentication for the public virtual drive (if it's required)."]}),"\n",(0,i.jsxs)(n.p,{children:["Alternatively, the authentication can be set using the ",(0,i.jsx)(n.code,{children:"ZROK_DRIVES_BASIC_AUTH"})," environment variable:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ export ZROK_DRIVES_BASIC_AUTH=username:password\n"})}),"\n",(0,i.jsx)(n.h2,{id:"one-way-synchronization",children:"One-way Synchronization"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"zrok copy"})," command includes a ",(0,i.jsx)(n.code,{children:"--sync"})," flag, which only copies files detected as ",(0,i.jsx)(n.em,{children:"modified"}),". ",(0,i.jsx)(n.code,{children:"zrok"})," considers a file with the same modification timestamp and size to be the same. Of course, this is not a strong guarantee that the files are equivalent. Future ",(0,i.jsx)(n.code,{children:"zrok"})," drives versions will provide a cryptographically strong mechanism (a-la ",(0,i.jsx)(n.code,{children:"rsync"})," and friends) to guarantee that files and trees of files are synchronized."]}),"\n",(0,i.jsxs)(n.p,{children:["For now, the ",(0,i.jsx)(n.code,{children:"--sync"})," flag provides a convenience mechanism to allow resuming copies of large file trees and provide a reasonable guarantee that the trees are in sync."]}),"\n",(0,i.jsxs)(n.p,{children:["Let's take a look at ",(0,i.jsx)(n.code,{children:"zrok copy --sync"})," in action:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok copy --sync docs/ https://glmv049c62p7.share.zrok.io\n[ 0.636] INFO zrok/drives/sync.OneWay: => /_attic/\n[ 0.760] INFO zrok/drives/sync.OneWay: => /_attic/network/\n[ 0.816] INFO zrok/drives/sync.OneWay: => /_attic/network/_category_.json\n[ 0.928] INFO zrok/drives/sync.OneWay: => /_attic/network/prod/\n[ 0.987] INFO zrok/drives/sync.OneWay: => /_attic/network/prod/ziti-ctrl.service\n[ 1.048] INFO zrok/drives/sync.OneWay: => /_attic/network/prod/ziti-ctrl.yml\n[ 1.107] INFO zrok/drives/sync.OneWay: => /_attic/network/prod/ziti-router0.service\n[ 1.167] INFO zrok/drives/sync.OneWay: => /_attic/network/prod/ziti-router0.yml\n[ 1.218] INFO zrok/drives/sync.OneWay: => /_attic/network/prod/zrok-access-public.service\n[ 1.273] INFO zrok/drives/sync.OneWay: => /_attic/network/prod/zrok-ctrl.service\n[ 1.328] INFO zrok/drives/sync.OneWay: => /_attic/network/prod/zrok-ctrl.yml\n[ 1.382] INFO zrok/drives/sync.OneWay: => /_attic/network/prod/zrok.io-network-skeleton.md\n[ 1.447] INFO zrok/drives/sync.OneWay: => /_attic/overview.md\n[ 1.572] INFO zrok/drives/sync.OneWay: => /_attic/sharing/\n[ 1.622] INFO zrok/drives/sync.OneWay: => /_attic/sharing/_category_.json\n[ 1.673] INFO zrok/drives/sync.OneWay: => /_attic/sharing/reserved_services.md\n[ 1.737] INFO zrok/drives/sync.OneWay: => /_attic/sharing/sharing_modes.md\n[ 1.793] INFO zrok/drives/sync.OneWay: => /_attic/v0.2_account_requests.md\n[ 1.902] INFO zrok/drives/sync.OneWay: => /_attic/v0.4_limits.md\n...\n[ 9.691] INFO zrok/drives/sync.OneWay: => /images/zrok_web_ui_empty_shares.png\n[ 9.812] INFO zrok/drives/sync.OneWay: => /images/zrok_web_ui_new_environment.png\n[ 9.870] INFO zrok/drives/sync.OneWay: => /images/zrok_zoom_to_fit.png\ncopy complete!\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Because the target drive was empty, ",(0,i.jsx)(n.code,{children:"zrok copy --sync"})," copied the entire contents of the local ",(0,i.jsx)(n.code,{children:"docs/"})," tree into the virtual drive. However, if we run that command again, we get:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok copy --sync docs/ https://glmv049c62p7.share.zrok.io\ncopy complete!\n"})}),"\n",(0,i.jsx)(n.p,{children:"The virtual drive contents are already in sync with the local filesystem tree, so there is nothing for it to copy."}),"\n",(0,i.jsxs)(n.p,{children:["Let's alter the contents of the drive and run the ",(0,i.jsx)(n.code,{children:"--sync"})," again:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok rm https://glmv049c62p7.share.zrok.io/images\n$ zrok copy --sync docs/ https://glmv049c62p7.share.zrok.io\n[ 0.364] INFO zrok/drives/sync.OneWay: => /images/\n[ 0.456] INFO zrok/drives/sync.OneWay: => /images/zrok.png\n[ 0.795] INFO zrok/drives/sync.OneWay: => /images/zrok_cover.png\n[ 0.866] INFO zrok/drives/sync.OneWay: => /images/zrok_deployment.drawio\n...\n[ 2.254] INFO zrok/drives/sync.OneWay: => /images/zrok_web_ui_empty_shares.png\n[ 2.340] INFO zrok/drives/sync.OneWay: => /images/zrok_web_ui_new_environment.png\n[ 2.391] INFO zrok/drives/sync.OneWay: => /images/zrok_zoom_to_fit.png\ncopy complete!\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Because we removed the ",(0,i.jsx)(n.code,{children:"images/"})," tree from the virtual drive, ",(0,i.jsx)(n.code,{children:"zrok copy --sync"})," detected this and copied the local ",(0,i.jsx)(n.code,{children:"images/"})," tree back onto the virtual drive."]}),"\n",(0,i.jsx)(n.h2,{id:"drive-to-drive-copies-and-synchronization",children:"Drive-to-Drive Copies and Synchronization"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"zrok copy"})," CLI can operate on pairs of virtual drives remotely, without ever having to store files locally. This allow for drive-to-drive copies and synchronization."]}),"\n",(0,i.jsx)(n.p,{children:"Here are a couple of examples:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok copy --sync https://glmv049c62p7.share.zrok.io https://glmv049c62p7.share.zrok.io\ncopy complete!\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Specifying the same URL for both the source and the target of a ",(0,i.jsx)(n.code,{children:"--sync"})," operation should always result in nothing being copied... they are the same drive with the same state."]}),"\n",(0,i.jsx)(n.p,{children:"We can copy files between two virtual drives with a single command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok copy --sync https://glmv049c62p7.share.zrok.io zrok://hsml272j3xzf\n[ 1.396] INFO zrok/drives/sync.OneWay: => /_attic/\n[ 2.083] INFO zrok/drives/sync.OneWay: => /_attic/overview.md\n[ 2.704] INFO zrok/drives/sync.OneWay: => /_attic/sharing/\n...\n[ 118.240] INFO zrok/drives/sync.OneWay: => /images/zrok_web_console_empty.png\n[ 118.920] INFO zrok/drives/sync.OneWay: => /images/zrok_enable_modal.png\n[ 119.589] INFO zrok/drives/sync.OneWay: => /images/zrok_cover.png\n[ 120.214] INFO zrok/drives/sync.OneWay: => /getting-started.mdx\ncopy complete!\n$ zrok copy --sync https://glmv049c62p7.share.zrok.io zrok://hsml272j3xzf\ncopy complete!\n"})}),"\n",(0,i.jsx)(n.h2,{id:"copying-from-drives-to-the-local-filesystem",children:"Copying from Drives to the Local Filesystem"}),"\n",(0,i.jsxs)(n.p,{children:["In the current version of the drives CLI, ",(0,i.jsx)(n.code,{children:"zrok copy"})," always assumes the destination is a directory. There is currently no way to do:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok copy somefile someotherfile\n"})}),"\n",(0,i.jsx)(n.p,{children:"What you'll end up with on the local filesystem is:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"somefile\nsomeotherfile/somefile\n"})}),"\n",(0,i.jsxs)(n.p,{children:["It's in the backlog to support file destinations in a future release of ",(0,i.jsx)(n.code,{children:"zrok"}),". So, when using ",(0,i.jsx)(n.code,{children:"zrok copy"}),", always take note of the destination."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"zrok copy"})," supports a default destination of ",(0,i.jsx)(n.code,{children:"file://."}),", so you can do single parameter ",(0,i.jsx)(n.code,{children:"zrok copy"})," commands like this:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok ls https://azc47r3cwjds.share.zrok.io\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 TYPE \u2502 NAME \u2502 SIZE \u2502 MODIFIED \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 \u2502 LICENSE \u2502 11.3 kB \u2502 2023-07-21 13:17:56 -0400 EDT \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n$ zrok copy https://azc47r3cwjds.share.zrok.io/LICENSE\n[ 0.260] INFO zrok/drives/sync.OneWay: => /LICENSE\ncopy complete!\n$ ls -l\ntotal 12\n-rw-rw-r-- 1 michael michael 11346 Jan 19 13:29 LICENSE\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can also specify a local folder as the destination for your copy:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok copy https://azc47r3cwjds.share.zrok.io/LICENSE /tmp/inbox\n[ 0.221] INFO zrok/drives/sync.OneWay: => /LICENSE\ncopy complete! \n$ l /tmp/inbox\ntotal 12\n-rw-rw-r-- 1 michael michael 11346 Jan 19 13:30 LICENSE\n"})}),"\n",(0,i.jsx)(n.h2,{id:"unique-names-and-reserved-shares",children:"Unique Names and Reserved Shares"}),"\n",(0,i.jsx)(n.p,{children:"Private reserved shares with unque names can be particularly useful with the drives CLI:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok reserve private -b drive --unique-name mydrive /tmp/junk\n[ 0.315] INFO main.(*reserveCommand).run: your reserved share token is 'mydrive'\n$ zrok share reserved --headless mydrive\n[ 0.289] INFO main.(*shareReservedCommand).run: sharing target: '/tmp/junk'\n[ 0.289] INFO main.(*shareReservedCommand).run: using existing backend target: /tmp/junk\n[ 0.767] INFO sdk-golang/ziti.(*listenerManager).createSessionWithBackoff: {session token=[d519a436-9fb5-4207-afd5-7cbc28fb779a]} new service session\n[ 0.927] INFO main.(*shareReservedCommand).run: use this command to access your zrok share: 'zrok access private mydrive'\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This makes working with ",(0,i.jsx)(n.code,{children:"zrok://"})," URLs particularly convenient:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ zrok ls zrok://mydrive\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 TYPE \u2502 NAME \u2502 SIZE \u2502 MODIFIED \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 \u2502 LICENSE \u2502 11.3 kB \u2502 2023-07-21 13:17:56 -0400 EDT \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n"})}),"\n",(0,i.jsx)(n.h2,{id:"future-enhancements",children:"Future Enhancements"}),"\n",(0,i.jsxs)(n.p,{children:["Coming in a future release of ",(0,i.jsx)(n.code,{children:"zrok"})," drives are features like:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:'two-way synchronization between multiple hosts... allowing for shared "dropbox-like" usage scenarios between multiple environments'}),"\n",(0,i.jsx)(n.li,{children:"better ergonomics for single-file destinations"}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>t,a:()=>c});var i=r(7294);const s={},o=i.createContext(s);function c(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]);