added ls function

This commit is contained in:
mik-tf 2024-10-02 12:00:45 -04:00
parent aadf417ad0
commit 3628e4f733

432
flist.v
View File

@ -1,44 +1,57 @@
import os import os
import net.http import net.http
import term import term
import json
const ( const (
token_file = os.join_path(os.home_dir(), '.config', 'tfhubtoken') token_file = os.join_path(os.home_dir(), '.config', 'tfhubtoken')
binary_location = if os.user_os() == 'windows' { binary_location = if os.user_os() == 'windows' {
'C:\\Program Files\\flist\\flist.exe' 'C:\\Program Files\\flist\\flist.exe'
} else { } else {
'/usr/local/bin/flist' '/usr/local/bin/flist'
} }
) )
struct FlistItem {
name string
}
struct Payload {
username string
}
struct Response {
payload Payload
}
fn error_message(msg string) { fn error_message(msg string) {
println(term.bold(term.red('Error: ')) + msg) println(term.bold(term.red('Error: ')) + msg)
println(term.yellow('Run \'flist help\' for usage information.')) println(term.yellow('Run \'flist help\' for usage information.'))
} }
fn install() { fn install() {
println('Installing Flist CLI...') println('Installing Flist CLI...')
current_exe := os.executable() current_exe := os.executable()
if os.exists(current_exe) { if os.exists(current_exe) {
os.mkdir_all(os.dir(binary_location)) or { panic(err) } os.mkdir_all(os.dir(binary_location)) or { panic(err) }
os.cp(current_exe, binary_location) or { panic(err) } os.cp(current_exe, binary_location) or { panic(err) }
os.chmod(binary_location, 0o755) or { panic(err) } os.chmod(binary_location, 0o755) or { panic(err) }
println('Flist CLI has been installed to ' + binary_location) println('Flist CLI has been installed to ' + binary_location)
println('You can now use it by running \'flist help\'') println('You can now use it by running \'flist help\'')
} else { } else {
error_message('Cannot find the executable file') error_message('Cannot find the executable file')
exit(1) exit(1)
} }
} }
fn uninstall() { fn uninstall() {
println('Uninstalling Flist CLI...') println('Uninstalling Flist CLI...')
if os.exists(binary_location) { if os.exists(binary_location) {
os.rm(binary_location) or { panic(err) } os.rm(binary_location) or { panic(err) }
println('Flist CLI has been removed from ' + binary_location) println('Flist CLI has been removed from ' + binary_location)
} else { } else {
println('Flist CLI is not installed at ' + binary_location) println('Flist CLI is not installed at ' + binary_location)
} }
} }
fn login() { fn login() {
@ -80,62 +93,62 @@ fn login() {
} }
fn logout() { fn logout() {
if !os.exists(token_file) { if !os.exists(token_file) {
error_message('You are not logged in.') error_message('You are not logged in.')
return return
} }
os.rm(token_file) or { panic(err) } os.rm(token_file) or { panic(err) }
println('Logging out from Docker Hub...')
exit_code := os.system('docker logout')
if exit_code != 0 {
error_message('Failed to log out from Docker Hub.')
}
println('You are now logged out of Docker Hub and your Flist Hub token has been removed.') println('Logging out from Docker Hub...')
exit_code := os.system('docker logout')
if exit_code != 0 {
error_message('Failed to log out from Docker Hub.')
}
println('You are now logged out of Docker Hub and your Flist Hub token has been removed.')
} }
fn push(tag string) { fn push(tag string) {
println('Logging in to Docker Hub...') println('Logging in to Docker Hub...')
if os.system('sudo docker login') != 0 { if os.system('sudo docker login') != 0 {
error_message('Failed to log in to Docker Hub.') error_message('Failed to log in to Docker Hub.')
exit(1) exit(1)
} }
docker_user_result := os.execute('sudo docker system info | grep \'Username\' | cut -d \' \' -f 3') docker_user_result := os.execute('sudo docker system info | grep \'Username\' | cut -d \' \' -f 3')
if docker_user_result.exit_code != 0 || docker_user_result.output.trim_space() == '' { if docker_user_result.exit_code != 0 || docker_user_result.output.trim_space() == '' {
error_message('Failed to get Docker username. Please ensure you are logged in to Docker.') error_message('Failed to get Docker username. Please ensure you are logged in to Docker.')
exit(1) exit(1)
} }
docker_user := docker_user_result.output.trim_space() docker_user := docker_user_result.output.trim_space()
println('Docker username: $docker_user') println('Docker username: $docker_user')
full_tag := '${docker_user}/${tag}' full_tag := '${docker_user}/${tag}'
tfhub_token := os.read_file(token_file) or { tfhub_token := os.read_file(token_file) or {
error_message('No token found. Please run \'flist login\' first.') error_message('No token found. Please run \'flist login\' first.')
exit(1) exit(1)
} }
println('Starting Docker build') println('Starting Docker build')
if os.system('sudo docker buildx build -t ${full_tag} .') != 0 { if os.system('sudo docker buildx build -t ${full_tag} .') != 0 {
error_message('Docker build failed') error_message('Docker build failed')
exit(1) exit(1)
} }
println('Finished local Docker build, now pushing to Docker Hub') println('Finished local Docker build, now pushing to Docker Hub')
if os.system('sudo docker push ${full_tag}') != 0 { if os.system('sudo docker push ${full_tag}') != 0 {
error_message('Docker push failed') error_message('Docker push failed')
exit(1) exit(1)
} }
println('Converting Docker image to flist now...') println('Converting Docker image to flist now...')
url := 'https://hub.grid.tf/api/flist/me/docker' url := 'https://hub.grid.tf/api/flist/me/docker'
data := 'image=$full_tag' data := 'image=$full_tag'
mut config := http.FetchConfig{ mut config := http.FetchConfig{
url: url url: url
method: .post method: .post
@ -146,7 +159,6 @@ fn push(tag string) {
) )
} }
// Add Content-Type header
config.header.add_custom('Content-Type', 'application/x-www-form-urlencoded') or { config.header.add_custom('Content-Type', 'application/x-www-form-urlencoded') or {
eprintln('Add custom failed: $err') eprintln('Add custom failed: $err')
exit(1) exit(1)
@ -166,123 +178,203 @@ fn push(tag string) {
eprintln(response.body) eprintln(response.body)
exit(1) exit(1)
} }
} }
fn delete(flist_name string) { fn delete(flist_name string) {
tfhub_token := os.read_file(token_file) or { tfhub_token := os.read_file(token_file) or {
error_message('No token found. Please run \'flist login\' first.') error_message('No token found. Please run \'flist login\' first.')
exit(1) exit(1)
} }
println('Deleting flist: ' + flist_name) println('Deleting flist: ' + flist_name)
url := 'https://hub.grid.tf/api/flist/me/' + flist_name url := 'https://hub.grid.tf/api/flist/me/' + flist_name
config := http.FetchConfig{ config := http.FetchConfig{
url: url url: url
method: .delete method: .delete
header: http.new_header(key: .authorization, value: 'bearer ' + tfhub_token) header: http.new_header(key: .authorization, value: 'bearer ' + tfhub_token)
} }
response := http.fetch(config) or { response := http.fetch(config) or {
error_message('Failed to send delete request: ' + err.msg()) error_message('Failed to send delete request: ' + err.msg())
exit(1) exit(1)
} }
if response.status_code == 200 { if response.status_code == 200 {
println('Deletion request sent successfully.') println('Deletion request sent successfully.')
} else { } else {
error_message('Deletion request failed with status code: ' + response.status_code.str()) error_message('Deletion request failed with status code: ' + response.status_code.str())
} }
} }
fn rename(flist_name string, new_flist_name string) { fn rename(flist_name string, new_flist_name string) {
tfhub_token := os.read_file(token_file) or { tfhub_token := os.read_file(token_file) or {
error_message('No token found. Please run \'flist login\' first.') error_message('No token found. Please run \'flist login\' first.')
exit(1) exit(1)
} }
println('Renaming flist: ' + flist_name + ' to ' + new_flist_name) println('Renaming flist: ' + flist_name + ' to ' + new_flist_name)
url := 'https://hub.grid.tf/api/flist/me/' + flist_name + '/rename/' + new_flist_name url := 'https://hub.grid.tf/api/flist/me/' + flist_name + '/rename/' + new_flist_name
config := http.FetchConfig{ config := http.FetchConfig{
url: url url: url
method: .get method: .get
header: http.new_header(key: .authorization, value: 'bearer ' + tfhub_token) header: http.new_header(key: .authorization, value: 'bearer ' + tfhub_token)
} }
response := http.fetch(config) or { response := http.fetch(config) or {
error_message('Failed to send rename request: ' + err.msg()) error_message('Failed to send rename request: ' + err.msg())
exit(1) exit(1)
} }
if response.status_code == 200 { if response.status_code == 200 {
println('Rename request sent successfully.') println('Rename request sent successfully.')
} else { } else {
error_message('Rename request failed with status code: ' + response.status_code.str()) error_message('Rename request failed with status code: ' + response.status_code.str())
} }
}
fn get_hub_username(tfhub_token string) ?string {
url := 'https://hub.grid.tf/api/flist/me'
config := http.FetchConfig{
url: url
method: .get
header: http.new_header(
key: .authorization
value: 'bearer $tfhub_token'
)
}
response := http.fetch(config) or {
error_message('Failed to fetch hub username: $err')
return none
}
if response.status_code != 200 {
error_message('Failed to fetch hub username. Status code: $response.status_code')
return none
}
parsed_response := json.decode(Response, response.body) or {
error_message('Failed to parse JSON response: $err')
return none
}
if parsed_response.payload.username != '' {
return parsed_response.payload.username
}
error_message('Username not found in response')
return none
}
fn ls() {
tfhub_token := os.read_file(token_file) or {
error_message('No token found. Please run \'flist login\' first.')
exit(1)
}
hub_user := get_hub_username(tfhub_token) or {
error_message('Failed to get hub username')
exit(1)
}
url := 'https://hub.grid.tf/api/flist/$hub_user'
config := http.FetchConfig{
url: url
method: .get
header: http.new_header(
key: .authorization
value: 'bearer $tfhub_token'
)
}
response := http.fetch(config) or {
error_message('Failed to fetch data: $err')
exit(1)
}
if response.status_code != 200 {
error_message('Failed to fetch data. Status code: $response.status_code')
exit(1)
}
data := json.decode([]FlistItem, response.body) or {
error_message('Failed to parse JSON: $err')
exit(1)
}
println('Flists for user $hub_user:')
for item in data {
println(item.name)
}
} }
fn help() { fn help() {
println(term.bold(term.green('\n Welcome to the Flist CLI!'))) println(term.bold(term.green('\n Welcome to the Flist CLI!')))
println('This tool turns Dockerfiles and Docker images directly into Flist on the TF Flist Hub, passing by the Docker Hub.\n') println('This tool turns Dockerfiles and Docker images directly into Flist on the TF Flist Hub, passing by the Docker Hub.\n')
println(term.bold('Available commands:')) println(term.bold('Available commands:'))
println(term.blue(' install ') + '- Install the Flist CLI') println(term.blue(' install ') + '- Install the Flist CLI')
println(term.blue(' uninstall ') + '- Uninstall the Flist CLI') println(term.blue(' uninstall ') + '- Uninstall the Flist CLI')
println(term.blue(' login ') + '- Log in to Docker Hub and save the Flist Hub token') println(term.blue(' login ') + '- Log in to Docker Hub and save the Flist Hub token')
println(term.blue(' logout ') + '- Log out of Docker Hub and remove the Flist Hub token') println(term.blue(' logout ') + '- Log out of Docker Hub and remove the Flist Hub token')
println(term.blue(' push ') + '- Build and push a Docker image to Docker Hub, then convert and push it as an flist to Flist Hub') println(term.blue(' push ') + '- Build and push a Docker image to Docker Hub, then convert and push it as an flist to Flist Hub')
println(term.blue(' delete ') + '- Delete an flist from Flist Hub') println(term.blue(' delete ') + '- Delete an flist from Flist Hub')
println(term.blue(' rename ') + '- Rename an flist in Flist Hub') println(term.blue(' rename ') + '- Rename an flist in Flist Hub')
println(term.blue(' help ') + '- Display this help message\n') println(term.blue(' ls ') + '- List all flists of the current user')
println(term.bold('Usage:')) println(term.blue(' help ') + '- Display this help message\n')
println(' flist install') println(term.bold('Usage:'))
println(' flist uninstall') println(' flist install')
println(' flist login') println(' flist uninstall')
println(' flist logout') println(' flist login')
println(' flist push <image>:<tag>') println(' flist logout')
println(' flist delete <flist_name>') println(' flist push <image>:<tag>')
println(' flist rename <flist_name> <new_flist_name>') println(' flist delete <flist_name>')
println(' flist help') println(' flist rename <flist_name> <new_flist_name>')
println(' flist ls')
println(' flist help')
} }
fn main() { fn main() {
if os.args.len == 1 { if os.args.len == 1 {
help() help()
return return
} }
match os.args[1] { match os.args[1] {
'install' { install() } 'install' { install() }
'uninstall' { uninstall() } 'uninstall' { uninstall() }
'push' { 'push' {
if os.args.len == 3 { if os.args.len == 3 {
push(os.args[2]) push(os.args[2])
} else { } else {
error_message('Incorrect number of arguments for \'push\'.') error_message('Incorrect number of arguments for \'push\'.')
exit(1) exit(1)
} }
} }
'login' { login() } 'login' { login() }
'logout' { logout() } 'logout' { logout() }
'delete' { 'delete' {
if os.args.len == 3 { if os.args.len == 3 {
delete(os.args[2]) delete(os.args[2])
} else { } else {
error_message('Incorrect number of arguments for \'delete\'.') error_message('Incorrect number of arguments for \'delete\'.')
exit(1) exit(1)
} }
} }
'rename' { 'rename' {
if os.args.len == 4 { if os.args.len == 4 {
rename(os.args[2], os.args[3]) rename(os.args[2], os.args[3])
} else { } else {
error_message('Incorrect number of arguments for \'rename\'.') error_message('Incorrect number of arguments for \'rename\'.')
exit(1) exit(1)
} }
} }
'help' { help() } 'ls' { ls() }
else { 'help' { help() }
error_message('Unknown command: ' + os.args[1]) else {
exit(1) error_message('Unknown command: ' + os.args[1])
} exit(1)
} }
} }
}