Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F1914289
LocalDiskSudoFileStorageEngine.php
No One
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Authored By
avivey
Nov 10 2016, 10:42 PM
2016-11-10 22:42:15 (UTC+0)
Size
4 KB
Referenced Files
None
Subscribers
None
LocalDiskSudoFileStorageEngine.php
View Options
<?php
/**
* Keeps files on local disk, but sudo-s as the daemon user for it.
*
* @task internal Internals
*/
final
class
LocalDiskSudoFileStorageEngine
extends
PhabricatorFileStorageEngine
{
/* -( Engine Metadata )---------------------------------------------------- */
public
function
getEngineIdentifier
()
{
return
'local-disk-sudo'
;
}
public
function
getEnginePriority
()
{
return
4
;
// Just below the regular disk one.
}
public
function
canWriteFiles
()
{
$path
=
PhabricatorEnv
::
getEnvConfig
(
'storage.local-disk.path'
);
$user
=
PhabricatorEnv
::
getEnvConfig
(
'phd.user'
);
return
(
bool
)
strlen
(
$path
)
&&
(
bool
)
$user
;
}
/* -( Managing File Data )------------------------------------------------- */
/**
* Write the file data to local disk. Returns the relative path as the
* file data handle.
* @task impl
*/
public
function
writeFile
(
$data
,
array
$params
)
{
$root
=
$this
->
getLocalDiskFileStorageRoot
();
// Generate a random, unique file path like "ab/29/1f918a9ac39201ff". We
// put a couple of subdirectories up front to avoid a situation where we
// have one directory with a zillion files in it, since this is generally
// bad news.
do
{
$name
=
md5
(
mt_rand
());
$name
=
preg_replace
(
'/^(..)(..)(.*)$/'
,
'
\\
1/
\\
2/
\\
3'
,
$name
);
if
(!
Filesystem
::
pathExists
(
$root
.
'/'
.
$name
))
{
break
;
}
}
while
(
true
);
AphrontWriteGuard
::
willWrite
();
$binary
=
Filesystem
::
resolveBinary
(
'write-file-to-storage.sh'
);
$command
=
csprintf
(
'%s %s'
,
$binary
,
$root
.
'/'
.
$name
);
$command
=
PhabricatorDaemon
::
sudoCommandAsDaemonUser
(
$command
);
id
(
new
ExecFuture
(
'%C'
,
$command
))
->
write
(
$data
)
->
resolvex
();
return
$name
;
}
/**
* Read the file data off local disk.
* @task impl
*/
public
function
readFile
(
$handle
)
{
$path
=
$this
->
getLocalDiskFileStorageFullPath
(
$handle
);
return
Filesystem
::
readFile
(
$path
);
}
/**
* Deletes the file from local disk, if it exists.
* @task impl
*/
public
function
deleteFile
(
$handle
)
{
$path
=
$this
->
getLocalDiskFileStorageFullPath
(
$handle
);
if
(
Filesystem
::
pathExists
(
$path
))
{
AphrontWriteGuard
::
willWrite
();
$binary
=
Filesystem
::
resolveBinary
(
'rm-file-from-storage.php'
);
$command
=
csprintf
(
'%s %s'
,
$binary
,
$path
);
$command
=
PhabricatorDaemon
::
sudoCommandAsDaemonUser
(
$command
);
execx
(
'%C'
,
$command
);
}
}
/* -( Internals )---------------------------------------------------------- */
/**
* Get the configured local disk path for file storage.
*
* @return string Absolute path to somewhere that files can be stored.
* @task internal
*/
private
function
getLocalDiskFileStorageRoot
()
{
$root
=
PhabricatorEnv
::
getEnvConfig
(
'storage.local-disk.path'
);
if
(!
$root
||
$root
==
'/'
||
$root
[
0
]
!=
'/'
)
{
throw
new
PhabricatorFileStorageConfigurationException
(
pht
(
"Malformed local disk storage root. You must provide an absolute "
.
"path, and can not use '%s' as the root."
,
'/'
));
}
return
rtrim
(
$root
,
'/'
);
}
/**
* Convert a handle into an absolute local disk path.
*
* @param string File data handle.
* @return string Absolute path to the corresponding file.
* @task internal
*/
private
function
getLocalDiskFileStorageFullPath
(
$handle
)
{
// Make sure there's no funny business going on here. Users normally have
// no ability to affect the content of handles, but double-check that
// we're only accessing local storage just in case.
if
(!
preg_match
(
'@^[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]{28}
\z
@'
,
$handle
))
{
throw
new
Exception
(
pht
(
"Local disk filesystem handle '%s' is malformed!"
,
$handle
));
}
$root
=
$this
->
getLocalDiskFileStorageRoot
();
return
$root
.
'/'
.
$handle
;
}
}
/**
// rm-file-from-storage.php:
#!/usr/bin/env php
<?php
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
$filename = $argv[1];
$root = PhabricatorEnv::getEnvConfig('storage.local-disk.path');
if (substr($filename, 0, strlen($root)) != $root) {
throw new Exception('File is not in storage directory!');
}
if (strstr($filename, '..') != false) {
throw new Exception('invalid filename!');
}
execx('rm %s', $filename);
*/
/**
// write-file-to-storage.sh:
#! /usr/bin/env bash
set -e
# Saves data from STDIO to this file
# run this as the daemon user
DEST_FILE=$1 # abs path
if [[ -z $DEST_FILE ]]
then
echo 'needs dst filename!' >&2
exit 3
fi
mkdir -p $(dirname $DEST_FILE)
cat - > $DEST_FILE
*/
File Metadata
Details
Attached
Mime Type
text/plain; charset=utf-8
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
313680
Default Alt Text
LocalDiskSudoFileStorageEngine.php (4 KB)
Attached To
Mode
P2016 LocalDiskSudoFileStorageEngine.php
Attached
Detach File
Event Timeline
Log In to Comment