andreafabrizi / Dropbox-Uploader

Dropbox Uploader is a BASH script which can be used to upload, download, list or delete files from Dropbox, an online file sharing, synchronization and backup service.
https://www.andreafabrizi.it/2016/01/01/Dropbox-Uploader/
GNU General Public License v3.0
6.56k stars 1.08k forks source link

Feature reuest: Add command line to add access token #385

Open ghost opened 7 years ago

ghost commented 7 years ago

I would like to add a command line to add the access token instead of do ./dropbox_uploader.sh and manually add it.

th-lange commented 5 years ago

Hello GGJohny, a way to use environment variables with the tool is to just create the environment file it is looking for!

so the user that uses the tool just:

# remove existing config file:
rm ~/.dropbox_uploader

# We want to set the Keys via env-vars. This can be done by providing the script with an empty config file:
touch ~/.dropbox_uploader

Now you can set the Token using environment variables:

# like this:
export OAUTH_ACCESS_TOKEN=+++SUPER-SECRET++++
dropbox_uploader upload "${filename}" "${targetFolder}/${filename}"
necmettin commented 5 years ago

You should even be able to use different access tokens with that method, right?

OAUTH_ACCESS_TOKEN=+++SUPER-SECRET++++ dropbox_uploader upload "${filename}" "${targetFolder}/${filename}"
th-lange commented 5 years ago

Yes. Setting tokens like this is on a per call basis

barbalex commented 4 years ago

@th-lange Is this documented somewhere? If so I missed it. If not, it would be great help to see that in the readme.

barbalex commented 4 years ago

This makes it rather hard to add a token in docker: I am a docker noob and have no idea how to set ~/.dropbox_uploader or if that even is possible.

On the other hand only adding the token to the dropbox_uploader call like this:

OAUTH_ACCESS_TOKEN=+++SUPER-SECRET++++ dropbox_uploader upload "${filename}" "${targetFolder}/${filename}"

does not seem to work - because dropbox-uploader looks for that conf file and assumes there is no token if it can't find the file.

Also I don't even know if dropbox-uploader can write to the path desired inside docker.

I really wish adding the token to the call would work.

barbalex commented 4 years ago

Also: there is no documentation on the configuration file. So I can't even try to use the -f <FILENAME> parameter (which would allow me to place the file where I can write inside the container) as I have no idea what to write inside the file.

th-lange commented 4 years ago

@th-lange Is this documented somewhere? If so I missed it. If not, it would be great help to see that in the readme.

No. I would rather consider this a hack. We do this, because we do need to change them on a per call basis.

I would need your doker file for a better idea on what you want. Well, imho, you:

Then you set the env vars for your container.

OAUTH_ACCESS_TOKEN=+++SUPER-SECRET++++ dropbox_uploader upload "${filename}" "${targetFolder}/${filename}"

does not seem to work - because dropbox-uploader looks for that conf file and assumes there is no token if it can't find the file.

Yes, it will not work. The dropbox uploader looks for the file and then starts an interactive dialog (if it does not find it) on what to use as token. So your method will work, IFF you did a touch on the expected file before.

necmettin commented 4 years ago

No. I would rather consider this a hack. We do this, because we do need to change them on a per call basis.

If "this" in that sentence is being able to provide a token on the command line, setting an environment variable on the command line is standart Linux behavior actually. It would be nice (and a much more standard behavior) if Dropbox-Uploader used an environment variable instead of a file. But I'm fine the way things are. :)

th-lange commented 4 years ago

"this" in that sentence

The "this" refers to the proposed way to set or better "use" the env variable.

barbalex commented 4 years ago

@th-lange Thanks a lot for helping! And for this great tool. I have been using it for years. Only now I need to use it inside docker containers.

I have now managed to use it inside docker. I am explaining it here. Maybe this approach can be further optimized (thanks for feedback). Maybe it will help others:

I have a docker-compose.yml file to set up db, postgraphile and a server:

version: '3.7'
services:
  db:
    container_name: apf_db
    restart: always
    image: db
    build:
      context: ./db
    env_file:
      - ./.env
    networks:
      - network
    expose:
      - '5432'
    ports:
      - '5432:5432'
    volumes:
      - db_data:/var/lib/postgresql/data
      - sik_data:/sik_data
  graphql:
    container_name: apf_graphql
    restart: unless-stopped
    build:
      context: ./graphql
    networks:
      - network
    expose:
      - '5000'
    ports:
      - '5000:5000'
    depends_on:
      - db
    env_file:
      - ./.env
    command: [
        '--connection',
        '${DATABASE_URL}',
        '--schema',
        'apflora',
        '--append-plugins',
        'postgraphile-plugin-connection-filter,@graphile-contrib/pg-order-by-related,@graphile/postgis',
        '--jwt-token-identifier',
        'auth.jwt_token',
        '--default-role',
        'postgres',
        #'authenticator',
        '--jwt-secret',
        '${JWT_SECRET}',
        '--cors',
        '--disable-query-log',
        '--enable-query-batching',
        '--retry-on-init-fail',
      ]
  caddy:
    build:
      context: ./caddy
    container_name: apf_caddy
    networks:
      - network
    depends_on:
      - graphql
    restart: always
    # original image downgrades user but that seems not to work
    # see: https://caddy.community/t/basic-docker-compose-setup-failing/6892/7
    user: root
    ports:
      - '80:80'
      - '443:443'
    env_file:
      - ./.env
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - caddy_certs:/root/.local/share/caddy
      - caddy_config:/root/.config/caddy
volumes:
  db_data:
  sik_data:
  caddy_certs:
  caddy_config:
networks:
  network:

First I tried to build a separate service which would manage the backups. I gave that up because this service would have had to access the db container for the dump file. For that it would need to use the docker exe command which is not easy to achieve.

So I decided to add the backups to the db service itself. Here is the Dockerfile:

FROM postgis/postgis:12-3.0

COPY ./init/ /docker-entrypoint-initdb.d/
COPY ./apflora.backup /sik_data/apflora.backup

RUN chmod +x /docker-entrypoint-initdb.d/02_restore.sh

# Install Cron and curl
RUN apt-get update
RUN apt-get -y install cron
RUN apt-get -y install curl
RUN apt-get -y install bash
RUN apt-get -y install nano

# install dropbox uploader
ADD dropbox_uploader.conf /dropbox_uploader.conf
# this did not work as token was never written to the file
#RUN echo "OAUTH_ACCESS_TOKEN=$DROPBOX_OAUTH_ACCESS_TOKEN" >> /dropbox_uploader.conf
RUN curl "https://raw.githubusercontent.com/andreafabrizi/Dropbox-Uploader/master/dropbox_uploader.sh" -o dropbox_uploader.sh
RUN chmod +x dropbox_uploader.sh

# add the backup script
ADD backup.sh /backup.sh
RUN chmod +x /backup.sh

I found a hint as to how to build the .conf file here: https://github.com/andreafabrizi/Dropbox-Uploader/issues/454#issuecomment-437387746

So I am adding a dropbox_uploader.conf file into the container (tried to write it on build using env variables and RUN echo "OAUTH_ACCESS_TOKEN=$DROPBOX_OAUTH_ACCESS_TOKEN" >> /dropbox_uploader.conf but somehow the token never arrived in the conf file). It looks like this:

OAUTH_ACCESS_TOKEN=+++SUPER-SECRET++++

I also tried to cron from the db container. But this does not seem to work. So I am now adding a cron to the host (a digitalocean virtual server) that calls this script:

echo "creating dump file..."
FILENAME=$(date +"%Y-%m-%d_%H-%M-%S_apflora.backup")
PGPASSWORD=$POSTGRES_PASSWORD pg_dump -U postgres -h localhost --file=/sik_data/$FILENAME -Fc -Z9 apflora
echo "uploading dump file..."
/dropbox_uploader.sh -f dropbox_uploader.conf upload /sik_data/$FILENAME $FILENAME
rm /sik_data/$FILENAME
echo "backed up $FILENAME" >> /var/log/cron.log 2>&1

using a backup.sh-file on the host that looks like this:

docker exec -d apf_db bash ./backup.sh

And this works nicely.

I will soon have to upload the backup into two separate dropbox accounts (one belongs to the client). For that I can simply add another line to the backup.sh-file in the db container that uses a different conf file:

/dropbox_uploader.sh -f dropbox_uploader_2.conf upload /sik_data/$FILENAME $FILENAME

Again: Thanks a lot for this great tool. It would help though if the structure of the .conf file would be documented to enable what I am doing here.

th-lange commented 4 years ago

Nice! Happy to help!