diff --git a/.github/workflows/pki.yml b/.github/workflows/pki.yml index 9f4334dee71..2bea96efe72 100644 --- a/.github/workflows/pki.yml +++ b/.github/workflows/pki.yml @@ -48,20 +48,3 @@ jobs: run: | python tests/github/pki_wrong_cn.py - test_pki_cert_location: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up Python 3.8 - uses: actions/setup-python@v3 - with: - python-version: "3.8" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install . - - name: Test PKI - run: | - bash tests/github/test_pki_cert_location.sh torch_cnn_mnist aggregator col1 col2 $(hostname --all-fqdns | awk '{print $1}') --rounds-to-train 3 \ No newline at end of file diff --git a/openfl/interface/aggregator.py b/openfl/interface/aggregator.py index b22bb61d3f3..618adae2558 100644 --- a/openfl/interface/aggregator.py +++ b/openfl/interface/aggregator.py @@ -31,18 +31,14 @@ def aggregator(context): help='Federated learning plan [plan/plan.yaml]', default='plan/plan.yaml', type=ClickPath(exists=True)) -@option('-c', '--authorized_cols', required=False, +@option('-col', '--authorized_cols', required=False, help='Authorized collaborator list [plan/cols.yaml]', default='plan/cols.yaml', type=ClickPath(exists=True)) @option('-s', '--secure', required=False, help='Enable Intel SGX Enclave', is_flag=True, default=False) @option('-c', '--cert_path', help='The cert path where pki certs will reside', required=False) -@option('--fqdn', required=False, type=click_types.FQDN, - help=f'The fully qualified domain name of' - f' aggregator node [{getfqdn_env()}]', - default=getfqdn_env()) -def start_(plan, authorized_cols, secure, cert_path, fqdn): +def start_(plan, authorized_cols, secure, cert_path): """Start the aggregator service.""" from pathlib import Path @@ -61,19 +57,18 @@ def start_(plan, authorized_cols, secure, cert_path, fqdn): logger.info('🧿 Starting the Aggregator Service.') if cert_path: - CERT_PATH = Path(cert_path).absolute() - (CERT_PATH / 'cert').mkdir(parents=True, exist_ok=True) - CERT_DIR = CERT_PATH / 'cert' - if not Path(CERT_DIR).exists(): + cert_path = Path(cert_path).absolute() + (cert_path / 'cert').mkdir(parents=True, exist_ok=True) + cert_dir_path = cert_path / 'cert' + if not Path(cert_dir_path).exists(): echo(style('Certificate Path not found.', fg='red') + ' Please run `fx aggregator generate-cert-request --cert_path`' ' to generate certs under this directory first.') - if fqdn is None: - fqdn = getfqdn_env() - common_name = f'{fqdn}'.lower() - plan.get_server(root_certificate=f'{CERT_DIR}/cert_chain.crt', - private_key=f'{CERT_DIR}/server/agg_{common_name}.key', - certificate=f'{CERT_DIR}/server/agg_{common_name}.crt').serve() + + common_name = plan.config['network']['settings']['agg_addr'].lower() + plan.get_server(root_certificate=f'{cert_dir_path}/cert_chain.crt', + private_key=f'{cert_dir_path}/server/agg_{common_name}.key', + certificate=f'{cert_dir_path}/server/agg_{common_name}.crt').serve() else: plan.get_server().serve() @@ -111,17 +106,20 @@ def generate_cert_request(fqdn, cert_path=None): server_private_key, server_csr = generate_csr(common_name, server=True) if cert_path: - CERT_PATH = Path(cert_path).absolute() - (CERT_PATH / 'cert').mkdir(parents=True, exist_ok=True) - CERT_DIR = CERT_PATH/ 'cert' # NOQA - (CERT_DIR / 'server').mkdir(parents=True, exist_ok=True) + cert_path = Path(cert_path).absolute() + (cert_path / 'cert').mkdir(parents=True, exist_ok=True) + cert_dir_path = cert_path / 'cert' + else: + cert_dir_path = CERT_DIR + + (cert_dir_path / 'server').mkdir(parents=True, exist_ok=True) echo(' Writing AGGREGATOR certificate key pair to: ' + style( - f'{CERT_DIR}/server', fg='green')) + f'{cert_dir_path}/server', fg='green')) # Write aggregator csr and key to disk - write_crt(server_csr, CERT_DIR / 'server' / f'{file_name}.csr') - write_key(server_private_key, CERT_DIR / 'server' / f'{file_name}.key') + write_crt(server_csr, cert_dir_path / 'server' / f'{file_name}.csr') + write_key(server_private_key, cert_dir_path / 'server' / f'{file_name}.key') # TODO: function not used @@ -171,11 +169,13 @@ def certify(fqdn, silent, cert_path=None): # Load CSR if cert_path: - CERT_PATH = Path(cert_path).absolute() - (CERT_PATH / 'cert').mkdir(parents=True, exist_ok=True) - CERT_DIR = CERT_PATH/ 'cert' # NOQA + cert_path = Path(cert_path).absolute() + (cert_path / 'cert').mkdir(parents=True, exist_ok=True) + cert_dir_path = cert_path / 'cert' + else: + cert_dir_path = CERT_DIR - csr_path_absolute_path = Path(CERT_DIR / f'{cert_name}.csr').absolute() + csr_path_absolute_path = Path(cert_dir_path / f'{cert_name}.csr').absolute() if not csr_path_absolute_path.exists(): echo(style('Aggregator certificate signing request not found.', fg='red') + ' Please run `fx aggregator generate-cert-request`' @@ -184,7 +184,7 @@ def certify(fqdn, silent, cert_path=None): csr, csr_hash = read_csr(csr_path_absolute_path) # Load private signing key - private_sign_key_absolute_path = Path(CERT_DIR / signing_key_path).absolute() + private_sign_key_absolute_path = Path(cert_dir_path / signing_key_path).absolute() if not private_sign_key_absolute_path.exists(): echo(style('Signing key not found.', fg='red') + ' Please run `fx workspace certify`' @@ -193,7 +193,7 @@ def certify(fqdn, silent, cert_path=None): signing_key = read_key(private_sign_key_absolute_path) # Load signing cert - signing_crt_absolute_path = Path(CERT_DIR / signing_crt_path).absolute() + signing_crt_absolute_path = Path(cert_dir_path / signing_crt_path).absolute() if not signing_crt_absolute_path.exists(): echo(style('Signing certificate not found.', fg='red') + ' Please run `fx workspace certify`' @@ -206,7 +206,7 @@ def certify(fqdn, silent, cert_path=None): + ' = ' + style(f'{csr_hash}', fg='red')) - crt_path_absolute_path = Path(CERT_DIR / f'{cert_name}.crt').absolute() + crt_path_absolute_path = Path(cert_dir_path / f'{cert_name}.crt').absolute() if silent: diff --git a/openfl/interface/collaborator.py b/openfl/interface/collaborator.py index 1d2b42bd510..92ee1c23924 100644 --- a/openfl/interface/collaborator.py +++ b/openfl/interface/collaborator.py @@ -61,18 +61,18 @@ def start_(plan, collaborator_name, data_config, secure, cert_path): logger.info('🧿 Starting a Collaborator Service.') if cert_path: - CERT_PATH = Path(cert_path).absolute() - (CERT_PATH / 'cert').mkdir(parents=True, exist_ok=True) - CERT_DIR = CERT_PATH / 'cert' - if not Path(CERT_DIR).exists(): + cert_path = Path(cert_path).absolute() + (cert_path / 'cert').mkdir(parents=True, exist_ok=True) + cert_dir_path = cert_path / 'cert' + if not Path(cert_dir_path).exists(): echo(style('Certificate Path not found.', fg='red') + ' Please run `fx collaborator generate-cert-request --cert_path`' ' to generate certs under this directory first.') common_name = f'{collaborator_name}'.lower() plan.get_collaborator(collaborator_name, - root_certificate=f'{CERT_DIR}/cert_chain.crt', - private_key=f'{CERT_DIR}/client/col_{common_name}.key', - certificate=f'{CERT_DIR}/client/col_{common_name}.crt').run() + root_certificate=f'{cert_dir_path}/cert_chain.crt', + private_key=f'{cert_dir_path}/client/col_{common_name}.key', + certificate=f'{cert_dir_path}/client/col_{common_name}.crt').run() else: plan.get_collaborator(collaborator_name).run() @@ -167,18 +167,20 @@ def generate_cert_request(collaborator_name, data_path, silent, skip_package, ce client_private_key, client_csr = generate_csr(common_name, server=False) if cert_path: - CERT_PATH = Path(cert_path).absolute() - (CERT_PATH / 'cert').mkdir(parents=True, exist_ok=True) - CERT_DIR = CERT_PATH/ 'cert' # NOQA + cert_path = Path(cert_path).absolute() + (cert_path / 'cert').mkdir(parents=True, exist_ok=True) + cert_dir_path = cert_path / 'cert' + else: + cert_dir_path = CERT_DIR - (CERT_DIR / 'client').mkdir(parents=True, exist_ok=True) + (cert_dir_path / 'client').mkdir(parents=True, exist_ok=True) echo(' Moving COLLABORATOR certificate to: ' + style( - f'{CERT_DIR}', fg='green')) + f'{cert_dir_path}', fg='green')) # Write collaborator csr and key to disk - write_crt(client_csr, CERT_DIR / 'client' / f'{file_name}.csr') - write_key(client_private_key, CERT_DIR / 'client' / f'{file_name}.key') + write_crt(client_csr, cert_dir_path / 'client' / f'{file_name}.csr') + write_key(client_private_key, cert_dir_path / 'client' / f'{file_name}.key') if not skip_package: from shutil import copytree @@ -199,7 +201,7 @@ def generate_cert_request(collaborator_name, data_path, silent, skip_package, ce ignore = ignore_patterns('__pycache__', '*.key', '*.srl', '*.pem') # Copy the current directory into the temporary directory - copytree(f'{CERT_DIR}/client', tmp_dir, ignore=ignore) + copytree(f'{cert_dir_path}/client', tmp_dir, ignore=ignore) for f in glob(f'{tmp_dir}/*'): if common_name not in basename(f): @@ -312,15 +314,17 @@ def certify(collaborator_name, silent, request_pkg=None, import_=False, cert_pat common_name = f'{collaborator_name}'.lower() if cert_path: - CERT_PATH = Path(cert_path).absolute() - (CERT_PATH / 'cert').mkdir(parents=True, exist_ok=True) - CERT_DIR = CERT_PATH/ 'cert' # NOQA + cert_path = Path(cert_path).absolute() + (cert_path / 'cert').mkdir(parents=True, exist_ok=True) + cert_dir_path = cert_path / 'cert' + else: + cert_dir_path = CERT_DIR if not import_: if request_pkg: - Path(f'{CERT_DIR}/client').mkdir(parents=True, exist_ok=True) - unpack_archive(request_pkg, extract_dir=f'{CERT_DIR}/client') - csr = glob(f'{CERT_DIR}/client/*.csr')[0] + Path(f'{cert_dir_path}/client').mkdir(parents=True, exist_ok=True) + unpack_archive(request_pkg, extract_dir=f'{cert_dir_path}/client') + csr = glob(f'{cert_dir_path}/client/*.csr')[0] else: if collaborator_name is None: echo('collaborator_name can only be omitted if signing\n' @@ -329,8 +333,8 @@ def certify(collaborator_name, silent, request_pkg=None, import_=False, cert_pat 'Example: fx collaborator certify --request-pkg ' 'col_one_to_agg_cert_request.zip') return - csr = glob(f'{CERT_DIR}/client/col_{common_name}.csr')[0] - copy(csr, CERT_DIR) + csr = glob(f'{cert_dir_path}/client/col_{common_name}.csr')[0] + copy(csr, cert_dir_path) cert_name = splitext(csr)[0] file_name = basename(cert_name) signing_key_path = 'ca/signing-ca/private/signing-ca.key' @@ -345,20 +349,20 @@ def certify(collaborator_name, silent, request_pkg=None, import_=False, cert_pat csr, csr_hash = read_csr(f'{cert_name}.csr') # Load private signing key - if not Path(CERT_DIR / signing_key_path).exists(): + if not Path(cert_dir_path / signing_key_path).exists(): echo(style('Signing key not found.', fg='red') + ' Please run `fx workspace certify`' ' to initialize the local certificate authority.') - signing_key = read_key(CERT_DIR / signing_key_path) + signing_key = read_key(cert_dir_path / signing_key_path) # Load signing cert - if not Path(CERT_DIR / signing_crt_path).exists(): + if not Path(cert_dir_path / signing_crt_path).exists(): echo(style('Signing certificate not found.', fg='red') + ' Please run `fx workspace certify`' ' to initialize the local certificate authority.') - signing_crt = read_crt(CERT_DIR / signing_crt_path) + signing_crt = read_crt(cert_dir_path / signing_crt_path) echo('The CSR Hash for file ' + style(f'{file_name}.csr', fg='green') @@ -370,7 +374,7 @@ def certify(collaborator_name, silent, request_pkg=None, import_=False, cert_pat echo(' Signing COLLABORATOR certificate') signed_col_cert = sign_certificate(csr, signing_key, signing_crt.subject) write_crt(signed_col_cert, f'{cert_name}.crt') - register_collaborator(CERT_DIR / 'client' / f'{file_name}.crt') + register_collaborator(cert_dir_path / 'client' / f'{file_name}.crt') else: @@ -379,7 +383,7 @@ def certify(collaborator_name, silent, request_pkg=None, import_=False, cert_pat echo(' Signing COLLABORATOR certificate') signed_col_cert = sign_certificate(csr, signing_key, signing_crt.subject) write_crt(signed_col_cert, f'{cert_name}.crt') - register_collaborator(CERT_DIR / 'client' / f'{file_name}.crt') + register_collaborator(cert_dir_path / 'client' / f'{file_name}.crt') else: echo(style('Not signing certificate.', fg='red') @@ -403,18 +407,18 @@ def certify(collaborator_name, silent, request_pkg=None, import_=False, cert_pat Path(f'{tmp_dir}/client').mkdir(parents=True, exist_ok=True) # Copy the signed cert to the temporary directory - copy(f'{CERT_DIR}/client/{file_name}.crt', f'{tmp_dir}/client/') + copy(f'{cert_dir_path}/client/{file_name}.crt', f'{tmp_dir}/client/') # Copy the CA certificate chain to the temporary directory - copy(f'{CERT_DIR}/cert_chain.crt', tmp_dir) + copy(f'{cert_dir_path}/cert_chain.crt', tmp_dir) # Create Zip archive of directory make_archive(archive_name, archive_type, tmp_dir) else: # Copy the signed certificate and cert chain into PKI_DIR - previous_crts = glob(f'{CERT_DIR}/client/*.crt') - unpack_archive(import_, extract_dir=CERT_DIR) - updated_crts = glob(f'{CERT_DIR}/client/*.crt') + previous_crts = glob(f'{cert_dir_path}/client/*.crt') + unpack_archive(import_, extract_dir=cert_dir_path) + updated_crts = glob(f'{cert_dir_path}/client/*.crt') cert_difference = list(set(updated_crts) - set(previous_crts)) if len(cert_difference) != 0: crt = basename(cert_difference[0]) diff --git a/openfl/interface/workspace.py b/openfl/interface/workspace.py index 81e95b1da6a..b728b57eb51 100644 --- a/openfl/interface/workspace.py +++ b/openfl/interface/workspace.py @@ -235,24 +235,26 @@ def certify(cert_path=None): echo('1.1 Create Directories') if cert_path: - CERT_PATH = Path(cert_path).absolute() - (CERT_PATH / 'cert').mkdir(parents=True, exist_ok=True) - CERT_DIR = CERT_PATH/ 'cert' # NOQA + cert_path = Path(cert_path).absolute() + (cert_path / 'cert').mkdir(parents=True, exist_ok=True) + cert_dir_path = cert_path / 'cert' + else: + cert_dir_path = CERT_DIR - (CERT_DIR / 'ca/root-ca/private').mkdir( + (cert_dir_path / 'ca/root-ca/private').mkdir( parents=True, exist_ok=True, mode=0o700) - (CERT_DIR / 'ca/root-ca/db').mkdir(parents=True, exist_ok=True) + (cert_dir_path / 'ca/root-ca/db').mkdir(parents=True, exist_ok=True) echo('1.2 Create Database') - with open(CERT_DIR / 'ca/root-ca/db/root-ca.db', 'w', encoding='utf-8') as f: + with open(cert_dir_path / 'ca/root-ca/db/root-ca.db', 'w', encoding='utf-8') as f: pass # write empty file - with open(CERT_DIR / 'ca/root-ca/db/root-ca.db.attr', 'w', encoding='utf-8') as f: + with open(cert_dir_path / 'ca/root-ca/db/root-ca.db.attr', 'w', encoding='utf-8') as f: pass # write empty file - with open(CERT_DIR / 'ca/root-ca/db/root-ca.crt.srl', 'w', encoding='utf-8') as f: + with open(cert_dir_path / 'ca/root-ca/db/root-ca.crt.srl', 'w', encoding='utf-8') as f: f.write('01') # write file with '01' - with open(CERT_DIR / 'ca/root-ca/db/root-ca.crl.srl', 'w', encoding='utf-8') as f: + with open(cert_dir_path / 'ca/root-ca/db/root-ca.crl.srl', 'w', encoding='utf-8') as f: f.write('01') # write file with '01' echo('1.3 Create CA Request and Certificate') @@ -263,12 +265,12 @@ def certify(cert_path=None): root_private_key, root_cert = generate_root_cert() # Write root CA certificate to disk - with open(CERT_DIR / root_crt_path, 'wb') as f: + with open(cert_dir_path / root_crt_path, 'wb') as f: f.write(root_cert.public_bytes( encoding=serialization.Encoding.PEM, )) - with open(CERT_DIR / root_key_path, 'wb') as f: + with open(cert_dir_path / root_key_path, 'wb') as f: f.write(root_private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, @@ -278,20 +280,20 @@ def certify(cert_path=None): echo('2. Create Signing Certificate') echo('2.1 Create Directories') - (CERT_DIR / 'ca/signing-ca/private').mkdir( + (cert_dir_path / 'ca/signing-ca/private').mkdir( parents=True, exist_ok=True, mode=0o700) - (CERT_DIR / 'ca/signing-ca/db').mkdir(parents=True, exist_ok=True) + (cert_dir_path / 'ca/signing-ca/db').mkdir(parents=True, exist_ok=True) echo('2.2 Create Database') - with open(CERT_DIR / 'ca/signing-ca/db/signing-ca.db', 'w', encoding='utf-8') as f: + with open(cert_dir_path / 'ca/signing-ca/db/signing-ca.db', 'w', encoding='utf-8') as f: pass # write empty file - with open(CERT_DIR / 'ca/signing-ca/db/signing-ca.db.attr', 'w', encoding='utf-8') as f: + with open(cert_dir_path / 'ca/signing-ca/db/signing-ca.db.attr', 'w', encoding='utf-8') as f: pass # write empty file - with open(CERT_DIR / 'ca/signing-ca/db/signing-ca.crt.srl', 'w', encoding='utf-8') as f: + with open(cert_dir_path / 'ca/signing-ca/db/signing-ca.crt.srl', 'w', encoding='utf-8') as f: f.write('01') # write file with '01' - with open(CERT_DIR / 'ca/signing-ca/db/signing-ca.crl.srl', 'w', encoding='utf-8') as f: + with open(cert_dir_path / 'ca/signing-ca/db/signing-ca.crl.srl', 'w', encoding='utf-8') as f: f.write('01') # write file with '01' echo('2.3 Create Signing Certificate CSR') @@ -303,12 +305,12 @@ def certify(cert_path=None): signing_private_key, signing_csr = generate_signing_csr() # Write Signing CA CSR to disk - with open(CERT_DIR / signing_csr_path, 'wb') as f: + with open(cert_dir_path / signing_csr_path, 'wb') as f: f.write(signing_csr.public_bytes( encoding=serialization.Encoding.PEM, )) - with open(CERT_DIR / signing_key_path, 'wb') as f: + with open(cert_dir_path / signing_key_path, 'wb') as f: f.write(signing_private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, @@ -319,7 +321,7 @@ def certify(cert_path=None): signing_cert = sign_certificate(signing_csr, root_private_key, root_cert.subject, ca=True) - with open(CERT_DIR / signing_crt_path, 'wb') as f: + with open(cert_dir_path / signing_crt_path, 'wb') as f: f.write(signing_cert.public_bytes( encoding=serialization.Encoding.PEM, )) @@ -327,10 +329,10 @@ def certify(cert_path=None): echo('3 Create Certificate Chain') # create certificate chain file by combining root-ca and signing-ca - with open(CERT_DIR / 'cert_chain.crt', 'w', encoding='utf-8') as d: - with open(CERT_DIR / 'ca/root-ca.crt', encoding='utf-8') as s: + with open(cert_dir_path / 'cert_chain.crt', 'w', encoding='utf-8') as d: + with open(cert_dir_path / 'ca/root-ca.crt', encoding='utf-8') as s: d.write(s.read()) - with open(CERT_DIR / 'ca/signing-ca.crt') as s: + with open(cert_dir_path / 'ca/signing-ca.crt') as s: d.write(s.read()) echo('\nDone.') diff --git a/tests/github/test_pki_cert_location.sh b/tests/github/test_pki_cert_location.sh deleted file mode 100755 index 1161834e9d3..00000000000 --- a/tests/github/test_pki_cert_location.sh +++ /dev/null @@ -1,146 +0,0 @@ -set -e -# Test the pipeline - -TEMPLATE=${1:-'keras_cnn_mnist'} # ['torch_cnn_mnist', 'keras_cnn_mnist'] -FED_WORKSPACE=${2:-'fed_work12345alpha81671'} # This can be whatever unique directory name you want -COL1=${3:-'one123dragons'} # This can be any unique label (lowercase) -COL2=${4:-'beta34unicorns'} # This can be any unique label (lowercase) - -FQDN=${5:-$(hostname --all-fqdns | awk '{print $1}')} - -CERT_PATH_AG=${6:-"${HOME}/.openfl/aggregator"} -CERT_PATH_COL1=${7:-"${HOME}/.openfl/one123dragons"} -CERT_PATH_COL2=${8:-"${HOME}/.openfl/beta34unicorns"} - -COL1_DATA_PATH=1 -COL2_DATA_PATH=2 - -help() { - echo "Usage: test_hello_federation.sh TEMPLATE FED_WORKSPACE COL1 COL2 [OPTIONS]" - echo - echo "Options:" - echo "--rounds-to-train rounds to train" - echo "--col1-data-path data path for collaborator 1" - echo "--col2-data-path data path for collaborator 2" - echo "--save-model path to save model in native format" - echo "-h, --help display this help and exit" -} - -# Getting additional options -ADD_OPTS=$(getopt -o "h" -l "rounds-to-train:,col1-data-path:, -col2-data-path:,save-model:,help" -n test_hello_federation.sh -- "$@") -eval set -- "$ADD_OPTS" -while (($#)); do - case "${1:-}" in - (--rounds-to-train) ROUNDS_TO_TRAIN="$2" ; shift 2 ;; - (--col1-data-path) COL1_DATA_PATH="$2" ; shift 2 ;; - (--col2-data-path) COL2_DATA_PATH="$2" ; shift 2 ;; - (--save-model) SAVE_MODEL="$2" ; shift 2 ;; - (-h|--help) help ; exit 0 ;; - - (--) shift ; break ;; - (*) echo "Invalid option: ${1:-}"; exit 1 ;; - esac -done - - - -create_collaborator() { - - FED_WORKSPACE=$1 - FED_DIRECTORY=$2 - COL=$3 - COL_DIRECTORY=$4 - DATA_PATH=$5 - CERT_PATH_COL=$6 - CERT_PATH=$7 - - ARCHIVE_NAME="${FED_WORKSPACE}.zip" - - # Copy workspace to collaborator directories (these can be on different machines) - rm -rf ${COL_DIRECTORY} # Remove any existing directory - mkdir -p ${COL_DIRECTORY} # Create a new directory for the collaborator - cd ${COL_DIRECTORY} - fx workspace import --archive ${FED_DIRECTORY}/${ARCHIVE_NAME} # Import the workspace to this collaborator - - # Create collaborator certificate request - cd ${COL_DIRECTORY}/${FED_WORKSPACE} - fx collaborator generate-cert-request -d ${DATA_PATH} -n ${COL} -c ${CERT_PATH_COL} --silent # Remove '--silent' if you run this manually - - # Sign collaborator certificate - cd ${FED_DIRECTORY} # Move back to the Aggregator - fx collaborator certify --request-pkg ${COL_DIRECTORY}/${FED_WORKSPACE}/col_${COL}_to_agg_cert_request.zip -c ${CERT_PATH} --silent # Remove '--silent' if you run this manually - - #Import the signed certificate from the aggregator - cd ${COL_DIRECTORY}/${FED_WORKSPACE} - fx collaborator certify --import ${FED_DIRECTORY}/agg_to_col_${COL}_signed_cert.zip -c ${CERT_PATH_COL} - -} - -# START -# ===== -# Make sure you are in a Python virtual environment with the FL package installed. - -# Create FL workspace -rm -rf ${FED_WORKSPACE} -fx workspace create --prefix ${FED_WORKSPACE} --template ${TEMPLATE} -cd ${FED_WORKSPACE} -FED_DIRECTORY=`pwd` # Get the absolute directory path for the workspace - -# Initialize FL plan -fx plan initialize -a ${FQDN} - -# Set rounds to train if given -if [[ ! -z "$ROUNDS_TO_TRAIN" ]] -then - sed -i "/rounds_to_train/c\ rounds_to_train: $ROUNDS_TO_TRAIN" plan/plan.yaml -fi - -# Create certificate authority for workspace -fx workspace certify -c ${CERT_PATH_AG} - -# Export FL workspace -fx workspace export - -# Create aggregator certificate -fx aggregator generate-cert-request --fqdn ${FQDN} -c ${CERT_PATH_AG} - -# Sign aggregator certificate -fx aggregator certify --fqdn ${FQDN} -c ${CERT_PATH_AG} --silent # Remove '--silent' if you run this manually - -# Create collaborator #1 -COL1_DIRECTORY=${FED_DIRECTORY}/${COL1} -create_collaborator ${FED_WORKSPACE} ${FED_DIRECTORY} ${COL1} ${COL1_DIRECTORY} ${COL1_DATA_PATH} ${CERT_PATH_COL1} ${CERT_PATH_AG} - -# Create collaborator #2 -COL2_DIRECTORY=${FED_DIRECTORY}/${COL2} -create_collaborator ${FED_WORKSPACE} ${FED_DIRECTORY} ${COL2} ${COL2_DIRECTORY} ${COL2_DATA_PATH} ${CERT_PATH_COL2} ${CERT_PATH_AG} - -# # Run the federation -cd ${FED_DIRECTORY} -fx aggregator start -c ${CERT_PATH_AG} --fqdn ${FQDN} & -sleep 5 -cd ${COL1_DIRECTORY}/${FED_WORKSPACE} -fx collaborator start -n ${COL1} -c ${CERT_PATH_COL1} & -cd ${COL2_DIRECTORY}/${FED_WORKSPACE} -fx collaborator start -n ${COL2} -c ${CERT_PATH_COL2} -wait - -# # Convert model to native format -if [[ ! -z "$SAVE_MODEL" ]] -then - cd ${FED_DIRECTORY} - fx model save -i "./save/${TEMPLATE}_last.pbuf" -o ${SAVE_MODEL} -fi - -# Clear cert directories - -cd ${FED_DIRECTORY} -fx aggregator uninstall-cert -c ${CERT_PATH_AG} -cd ${COL1_DIRECTORY}/${FED_WORKSPACE} -fx collaborator uninstall-cert -c ${CERT_PATH_COL1} -cd ${COL2_DIRECTORY}/${FED_WORKSPACE} -fx collaborator uninstall-cert -c ${CERT_PATH_COL2} - -rm -rf ${FED_DIRECTORY} -