The Challenge
When I purchased my Western Digital MyCloud EX2 Ultra NAS for running a Plex media server and storing family photos, I discovered a significant limitation: the built-in backup solutions were either non-functional or required expensive subscriptions. Initially, I attempted to develop a native app for the NAS using their SDK, but I quickly ran into several roadblocks:
- Outdated documentation (last updated in 2019)
- Broken SDK links and examples
- Limited community support and resources
- Inconsistent API behaviors
- Poor development environment setup instructions
After spending considerable time trying to work with the native app approach, I decided to pivot to a more reliable solution: developing a custom Python script that would:
The Solution ๐ ๏ธ
class S3Uploader:
def __init__(self, config_path='/mnt/HD/HD_a2/Nas_Prog/config.json'):
self.setup_logging()
self.load_config(config_path)
The solution is structured around a main S3Uploader
class that handles all core functionalities:
def sign_request(self, string_to_sign):
"""Signs the request with the secret key using SHA1 HMAC"""
signature = base64.b64encode(
hmac.new(
self.config['aws_secret_key'].encode('utf-8'),
string_to_sign.encode('utf-8'),
hashlib.sha1
).digest()
).decode('utf-8')
return signature
def upload_file(self, file_path):
"""
Uploads a file to S3 Glacier with proper date-based organization
Returns True if successful, False otherwise
"""
try:
file_name = os.path.basename(file_path)
date = formatdate(timeval=None, localtime=False, usegmt=True)
content_type = 'application/octet-stream'
# Create S3 path with date prefix
date_prefix = datetime.now().strftime('%Y/%m/%d')
s3_key = f"{date_prefix}/{file_name}"
Robust Error Handling ๐
def setup_logging(self):
"""Configures the logging system with proper formatting and file output"""
logging.basicConfig(
filename=os.path.join(log_dir, 'backup.log'),
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
Future Improvements ๐
I'm considering several enhancements to make the system even more robust:
- Incremental backup support
- File change detection using checksums
- Pre-upload compression for better cost efficiency
- Multi-threading for larger datasets
- Backup verification system
- Integration with cloud monitoring services
Cost & Benefits of AWS S3 Glacier ๐ฐ
One of the biggest advantages of AWS S3 Glacier is its extremely low cost for long-term storage. Hereโs an estimate of the current pricing:
- Standard Glacier Storage: Approximately $0.004 per GB per month.
- Data Retrieval: Varies based on urgency, starting from $0.01 per GB.
This means you can back up 100 GB of critical data for less than $0.50 per month. The low price makes it an excellent solution for keeping a secure backup of important files without breaking the bank.
Why Not a Native App?
My initial attempt to create a native app for the WD MyCloud EX2 Ultra revealed several challenges in the NAS development ecosystem:
Documentation Issues
The official SDK documentation was last updated in 2019, making it largely incompatible with current firmware versions. Many example endpoints either returned 404 errors or had completely different parameter requirements than documented.
Development Environment
Setting up a development environment for native apps required:
- Using an outdated Docker container
- Installing deprecated dependencies
- Working with unmaintained build tools
This made the native app approach unrealistic for a modern, maintainable solution.
Conclusion
While the native app development path proved challenging due to ecosystem limitations, the resulting Python solution actually provided more flexibility and control. By leveraging AWS S3 Glacier and pure Python implementation, I've created a reliable backup system that meets all requirements without any additional cost or dependency on the NAS's development ecosystem.