aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2024-02-28 19:16:14 -0500
committerJoseph Hunkeler <jhunkeler@gmail.com>2024-02-28 19:16:14 -0500
commitd5010cdff912411faa41ab997019b7929030356c (patch)
treeb214bf1bc67d31060e72a7d1932f193def5e746f
parenta797d4faae5ed13fa8b3280a9566566040f0cece (diff)
downloadstasis-d5010cdff912411faa41ab997019b7929030356c.tar.gz
Document functions and usage
-rw-r--r--include/artifactory.h252
-rw-r--r--include/conda.h154
-rw-r--r--include/omc.h19
3 files changed, 376 insertions, 49 deletions
diff --git a/include/artifactory.h b/include/artifactory.h
index 0fcf073..c8ce6d3 100644
--- a/include/artifactory.h
+++ b/include/artifactory.h
@@ -1,3 +1,4 @@
+//! @file artifactory.h
#ifndef OMC_ARTIFACTORY_H
#define OMC_ARTIFACTORY_H
@@ -5,46 +6,48 @@
#include <stdlib.h>
#include "omc.h"
+//! JFrog Artifactory Authentication struct
struct JFRT_Auth {
- bool insecure_tls;
- char *access_token;
- char *password;
- char *client_cert_key_path;
- char *client_cert_path;
- char *ssh_key_path;
- char *ssh_passphrase;
- char *user;
- char *server_id;
- char *url;
+ bool insecure_tls; //!< Disable TLS
+ char *access_token; //!< Generated access token
+ char *password; //!< Password
+ char *client_cert_key_path; //!< Path to where SSL key is stored
+ char *client_cert_path; //!< Path to where SSL cert is stored
+ char *ssh_key_path; //!< Path to SSH private key
+ char *ssh_passphrase; //!< Passphrase for SSH private key
+ char *user; //!< Account to authenticate as
+ char *server_id; //!< Artifactory server identification (unused)
+ char *url; //!< Artifactory server address
};
+//! JFrog Artifactory Upload struct
struct JFRT_Upload {
- bool quiet;
- char *project;
- bool ant;
- bool archive;
- char *build_name;
- char *build_number;
- bool deb;
- bool detailed_summary;
- bool dry_run;
- char *exclusions;
- bool explode;
- bool fail_no_op;
- bool flat;
- bool include_dirs;
- char *module;
- bool recursive;
- bool regexp;
- int retries;
- int retry_wait_time;
- char *spec;
+ bool quiet; //!< Enable quiet mode
+ char *project; //!< Destination project name
+ bool ant; //!< Enable Ant style regex
+ bool archive; //!< Generate a ZIP archive of the uploaded file(s)
+ char *build_name; //!< Build name
+ char *build_number; //!< Build number
+ bool deb; //!< Is Debian package?
+ bool detailed_summary; //!< Enable upload summary
+ bool dry_run; //!< Enable dry run (no-op)
+ char *exclusions; //!< Exclude patterns (separated by semicolons)
+ bool explode; //!< If uploaded file is an archive, extract it at the destination
+ bool fail_no_op; //!< Exit 2 when no file are affected
+ bool flat; //!< Upload with exact file system structure
+ bool include_dirs; //!< Enable to upload empty directories
+ char *module; //!< Build-info module name (optional)
+ bool recursive; //!< Upload files recursively
+ bool regexp; //!< Use regular expressions instead of wildcards
+ int retries; //!< Number of retries before giving up
+ int retry_wait_time; //!< Seconds between retries
+ char *spec; //!< Path to JSON upload spec
char *spec_vars;
- bool symlinks;
- bool sync_deletes;
- char *target_props;
- int threads;
- bool workaround_parent_only;
+ bool symlinks; //!< Preserve symbolic links
+ bool sync_deletes; //!< Destination is replaced by uploaded files
+ char *target_props; //!< Properties (separated by semicolons)
+ int threads; //!< Thread count
+ bool workaround_parent_only; //!< Change directory to local parent directory before uploading files
};
struct JFRT_Download {
@@ -85,6 +88,34 @@ struct JFRT_Download {
bool validate_symlinks;
};
+/**
+ * Download the JFrog CLI tool from jfrog.com
+ * ```c
+ * if (artifactory_download_cli(".",
+ * "https://releases.jfrog.io/artifactory",
+ * "jfrog-cli",
+ * "v2-jf",
+ * "[RELEASE]",
+ * "Linux",
+ * "x86_64",
+ * "jf") {
+ * remove("./jf");
+ * fprintf(stderr, "Failed to download JFrog CLI\n");
+ * exit(1);
+ * }
+ *
+ * ```
+ *
+ * @param dest Directory path
+ * @param jfrog_artifactory_base_url jfrog.com base URL
+ * @param jfrog_artifactory_product jfrog.com project (jfrog-cli)
+ * @param cli_major_ver Version series (v1, v2-jf, vX-jf)
+ * @param version Version to download. "[RELEASE]" will download the latest version available
+ * @param os Operating system name
+ * @param arch System CPU architecture
+ * @param remote_filename File to download (jf)
+ * @return
+ */
int artifactory_download_cli(char *dest,
char *jfrog_artifactory_base_url,
char *jfrog_artifactory_product,
@@ -93,12 +124,161 @@ int artifactory_download_cli(char *dest,
char *os,
char *arch,
char *remote_filename);
+
+/**
+ * JFrog CLI binding. Executes the "jf" tool with arguments.
+ *
+ * ```c
+ * struct JFRT_Auth auth_ctx;
+ * memset(auth_ctx, 0, sizeof(auth_context);
+ * auth_ctx.user = strdup("myuser");
+ * auth_ctx.password = strdup("mypassword");
+ * auth_ctx.url = strdup("https://myserver.tld/artifactory");
+ *
+ * if (jfrog_cli(&auth_ctx, "ping") {
+ * fprintf(stderr, "Failed to ping artifactory server: %s\n", auth_ctx.url);
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param auth JFRT_Auth structure
+ * @param args Command line arguments to pass to "jf" tool
+ * @return exit code from "jf"
+ */
int jfrog_cli(struct JFRT_Auth *auth, char *args);
+
+/**
+ * Issue an Artifactory server ping
+ *
+ * ```c
+ * struct JFRT_Auth auth_ctx;
+ * memset(auth_ctx, 0, sizeof(auth_context);
+ * auth_ctx.user = strdup("myuser");
+ * auth_ctx.password = strdup("mypassword");
+ * auth_ctx.url = strdup("https://myserver.tld/artifactory");
+ *
+ * if (jfrog_cli_ping(&auth_ctx)) {
+ * fprintf(stderr, "Failed to ping artifactory server: %s\n", auth_ctx.url);
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param auth JFRT_Auth structure
+ * @return exit code from "jf"
+ */
int jfrog_cli_rt_ping(struct JFRT_Auth *auth);
+
+/**
+ * Upload files to an Artifactory repository
+ *
+ * ```c
+ * struct JFRT_Auth auth_ctx;
+ * memset(auth_ctx, 0, sizeof(auth_context);
+ * auth_ctx.user = strdup("myuser");
+ * auth_ctx.password = strdup("mypassword");
+ * auth_ctx.url = strdup("https://myserver.tld/artifactory");
+ *
+ * struct JFRT_Upload upload_ctx;
+ * jfrt_upload_set_defaults(&upload_ctx);
+ *
+ * if (jfrt_cli_rt_upload(&auth_ctx, &upload_ctx,
+ * "local/files_*.ext", "repo_name/ext_files/")) {
+ * fprintf(stderr, "Upload failed\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param auth JFRT_Auth structure
+ * @param ctx JFRT_Upload structure
+ * @param src local pattern to upload
+ * @param repo_path remote Artifactory destination path
+ * @return exit code from "jf"
+ */
int jfrog_cli_rt_upload(struct JFRT_Auth *auth, struct JFRT_Upload *ctx, char *src, char *repo_path);
+
+/**
+ * Download a file from an Artifactory repository
+ *
+ * ```c
+ * struct JFRT_Auth auth_ctx;
+ * memset(auth_ctx, 0, sizeof(auth_context);
+ * auth_ctx.user = strdup("myuser");
+ * auth_ctx.password = strdup("mypassword");
+ * auth_ctx.url = strdup("https://myserver.tld/artifactory");
+ *
+ * struct JFRT_Download download_ctx;
+ * memset(download_ctx, 0, sizeof(download_ctx));
+ *
+ * if (jfrt_cli_rt_download(&auth_ctx, &download_ctx,
+ * "repo_name/ext_files/", "local/files_*.ext")) {
+ * fprintf(stderr, "Upload failed\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param auth JFRT_Auth structure
+ * @param ctx JFRT_Download structure
+ * @param repo_path Remote repository w/ file pattern
+ * @param dest Local destination path
+ * @return exit code from "jf"
+ */
int jfrog_cli_rt_download(struct JFRT_Auth *auth, struct JFRT_Download *ctx, char *repo_path, char *dest);
+
+/**
+ * Collect runtime data for Artifactory build object.
+ *
+ * ```c
+ * struct JFRT_Auth auth_ctx;
+ * memset(auth_ctx, 0, sizeof(auth_context);
+ * auth_ctx.user = strdup("myuser");
+ * auth_ctx.password = strdup("mypassword");
+ * auth_ctx.url = strdup("https://myserver.tld/artifactory");
+ *
+ * if (jfrog_cli_rt_build_collect_env(&auth_ctx, "mybuildname", "1.2.3+gabcdef")) {
+ * fprintf(stderr, "Failed to collect runtime data for Artifactory build object\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param auth JFRT_Auth structure
+ * @param build_name Artifactory build name
+ * @param build_number Artifactory build number
+ * @return exit code from "jf"
+ */
int jfrog_cli_rt_build_collect_env(struct JFRT_Auth *auth, char *build_name, char *build_number);
+
+/**
+ * Publish build object to Artifactory server
+ *
+ * ```c
+ * struct JFRT_Auth auth_ctx;
+ * memset(auth_ctx, 0, sizeof(auth_context);
+ * auth_ctx.user = strdup("myuser");
+ * auth_ctx.password = strdup("mypassword");
+ * auth_ctx.url = strdup("https://myserver.tld/artifactory");
+ *
+ * if (jfrog_cli_rt_build_collect_env(&auth_ctx, "mybuildname", "1.2.3+gabcdef")) {
+ * fprintf(stderr, "Failed to collect runtime data for Artifactory build object\n");
+ * exit(1);
+ * }
+ *
+ * if (jfrog_cli_rt_build_publish(&auth_ctx, "mybuildname", "1.2.3+gabcdef")) {
+ * fprintf(stderr, "Failed to publish Artifactory build object\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param auth JFRT_Auth structure
+ * @param build_name Artifactory build name
+ * @param build_number Artifactory build number
+ * @return exit code from "jf"
+ */
int jfrog_cli_rt_build_publish(struct JFRT_Auth *auth, char *build_name, char *build_number);
+
+/**
+ * Zero-out and apply likely defaults to a JFRT_Upload structure
+ * @param ctx JFRT_Upload structure
+ */
void jfrt_upload_set_defaults(struct JFRT_Upload *ctx);
-#endif //OMC_ARTIFACTORY_H
+#endif //OMC_ARTIFACTORY_H \ No newline at end of file
diff --git a/include/conda.h b/include/conda.h
index 3565bda..9cbbf9c 100644
--- a/include/conda.h
+++ b/include/conda.h
@@ -1,7 +1,4 @@
-//
-// Created by jhunk on 5/14/23.
-//
-
+//! @file conda.h
#ifndef OMC_CONDA_H
#define OMC_CONDA_H
@@ -11,14 +8,163 @@
#define CONDA_INSTALL_PREFIX "conda"
+/**
+ * Execute Python
+ * Python interpreter is determined by PATH
+ *
+ * ```c
+ * if (python_exec("-c 'printf(\"Hello world\")'")) {
+ * fprintf(stderr, "Hello world failed\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param args arguments to pass to interpreter
+ * @return exit code from python interpreter
+ */
int python_exec(const char *args);
+
+/**
+ * Execute Pip
+ * Pip is determined by PATH
+ *
+ * ```c
+ * if (pip_exec("freeze")) {
+ * fprintf(stderr, "pip freeze failed\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param args arguments to pass to Pip
+ * @return exit code from Pip
+ */
int pip_exec(const char *args);
+
+/**
+ * Execute conda (or if possible, mamba)
+ * Conda/Mamba is determined by PATH
+ *
+ * ```c
+ * if (conda_exec("env list")) {
+ * fprintf(stderr, "Failed to list conda environments\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param args arguments to pass to Conda
+ * @return exit code from Conda
+ */
int conda_exec(const char *args);
+
+/**
+ * Configure the runtime environment to use Conda/Mamba
+ *
+ * ```c
+ * if (conda_activate("/path/to/conda/installation", "base")) {
+ * fprintf(stderr, "Failed to activate conda's base environment\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param root directory where conda is installed
+ * @param env_name the conda environment to activate
+ * @return 0 on success, -1 on error
+ */
int conda_activate(const char *root, const char *env_name);
+
+/**
+ * Configure the active conda installation for headless operation
+ */
void conda_setup_headless();
+
+/**
+ * Creates a Conda environment from a YAML config
+ *
+ * ```c
+ * if (conda_env_create_from_uri("myenv", "https://myserver.tld/environment.yml")) {
+ * fprintf(stderr, "Environment creation failed\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param name Name of new environment to create
+ * @param uri /path/to/environment.yml
+ * @param uri file:///path/to/environment.yml
+ * @param uri http://myserver.tld/environment.yml
+ * @param uri https://myserver.tld/environment.yml
+ * @param uri ftp://myserver.tld/environment.yml
+ * @return exit code from "conda"
+ */
int conda_env_create_from_uri(char *name, char *uri);
+
+/**
+ * Create a Conda environment using generic package specs
+ *
+ * ```c
+ * // Create a basic environment without any conda packages
+ * if (conda_env_create("myenv", "3.11", NULL)) {
+ * fprintf(stderr, "Environment creation failed\n");
+ * exit(1);
+ * }
+ *
+ * // Create a basic environment and install conda packages
+ * if (conda_env_create("myenv", "3.11", "hstcal fitsverify")) {
+ * fprintf(stderr, "Environment creation failed\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param name Environment name
+ * @param python_version Desired version of Python
+ * @param packages Packages to install (or NULL)
+ * @return exit code from "conda"
+ */
int conda_env_create(char *name, char *python_version, char *packages);
+
+/**
+ * Remove a Conda environment
+ *
+ * ```c
+ * if (conda_env_remove("myenv")) {
+ * fprintf(stderr, "Unable to remove conda environment\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param name Environment name
+ * @return exit code from "conda"
+ */
int conda_env_remove(char *name);
+
+/**
+ * Export a Conda environment in YAML format
+ *
+ * ```c
+ * if (conda_env_export("myenv", "./", "myenv.yml")) {
+ * fprintf(stderr, "Unable to export environment\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param name Environment name to export
+ * @param output_dir Destination directory
+ * @param output_filename Destination file name
+ * @return exit code from "conda"
+ */
int conda_env_export(char *name, char *output_dir, char *output_filename);
+
+/**
+ * Run "conda index" on a local conda channel
+ *
+ * ```c
+ * if (conda_index("/path/to/channel")) {
+ * fprintf(stderr, "Unable to index requested path\n");
+ * exit(1);
+ * }
+ * ```
+ *
+ * @param path Top-level directory of conda channel
+ * @return exit code from "conda"
+ */
int conda_index(const char *path);
#endif //OMC_CONDA_H
diff --git a/include/omc.h b/include/omc.h
index 86add4e..99e2eba 100644
--- a/include/omc.h
+++ b/include/omc.h
@@ -1,3 +1,4 @@
+//! @file omc.h
#ifndef OMC_OMC_H
#define OMC_OMC_H
@@ -46,15 +47,15 @@
}
struct OMC_GLOBAL {
- bool verbose;
- bool always_update_base_environment;
- bool continue_on_error;
- bool conda_fresh_start;
- struct StrList *conda_packages;
- struct StrList *pip_packages;
- char *tmpdir;
- char *conda_install_prefix;
- char *sysconfdir;
+ bool verbose; //!< Enable verbose output
+ bool always_update_base_environment; //!< Update base environment immediately after activation
+ bool continue_on_error; //!< Do not stop on test failures
+ bool conda_fresh_start; //!< Always install a new copy of Conda
+ struct StrList *conda_packages; //!< Conda packages to install after initial activation
+ struct StrList *pip_packages; //!< Pip packages to install after initial activation
+ char *tmpdir; //!< Path to temporary storage directory
+ char *conda_install_prefix; //!< Path to install conda
+ char *sysconfdir; //!< Path where OMC reads its configuration files (mission directory, etc)
struct Jfrog {
char *jfrog_artifactory_base_url;
char *jfrog_artifactory_product;